<?php
/**
 * 银联商务POS通B扫C交易接口
 * INSERT INTO `hanchao_payment` (`id`, `code`, `name`, `fee`, `content`, `config_account`, `config_key`, `config_partner`, `config_other`, `is_wap`, `is_online`, `is_return`, `sort`, `status`) VALUES
(NULL,	'Chinaumspos',	'银联商务',	0.00,	'',	'f0ec96ad2c3848b5b810e7aadf369e2f',	'775481e2556e4564985f5439a5e6a277',	'123456789900081',	'J00810001',	0,	0,	0,	10,	1);
 */
namespace Common\Vendor\Pay\Driver;
class Chinaumspos extends \Common\Vendor\Pay\Pay {
    protected $gateway = 'http://58.247.0.18:29015/';//请求银联接口地址   
    protected $config = array('config_partner' => '','config_key' => '','config_account' => '');
    //检查账户是否正确
    public function check() {
        if (!$this->config['config_partner'] || !$this->config['config_account'] || !$this->config['config_key']) {
            E("参数设置有误！");
        }
        if($this->config['config_partner']!='123456789900081'){
            $this->gateway='https://api-mop.chinaums.com/';
        }
        return true;
    }
    /**
     * 请求接口，传递参数
     * @param PayVo $vo
     * @return mixed
     */
    public function buildRequestForm(\Common\Vendor\Pay\PayVo $vo) {
        if(substr($this->config['config_other'],0,1)!='J'){$this->activeterminal();}
        $this->config['config_other']=str_replace('J','',$this->config['config_other']);          
        $token=$this->getToken();if(is_array($token))return $token;      
        $params = array(
            'merchantCode'            => $this->config['config_partner'],//商户号
            'terminalCode'            => $this->config['config_other'],//终端号
            'transactionAmount'       => ($vo->getFee()*100),//交易金额单位：分
            'transactionCurrencyCode' => '156',//交易币种
            'merchantOrderId'         => $vo->getOrderNo(),//商户订单号
            'merchantRemark'          => $vo->getTitle(),//商户备注
            'payMode'                 => 'CODE_SCAN',//支付方式
            'payCode'                 => $vo->getProduct_id(),//支付码
        );
        $headers=array('Authorization:'.$token);
        $result=$this->curlinit($this->gateway.'v2/poslink/transaction/pay', $params,$headers);
        $getparam=$vo->getParam();
        $out_trade_no=$params['merchantOrderId'];
        $is_app=$getparam['is_app'];
        if($is_app){
            $return['status']=1;
            return $return;
        }
        return $result;
        
    }
    //6.交易状态查询
    public function query($out_trade_no, &$succCode=0,$transaction_id=''){
        if(empty($out_trade_no) && empty($transaction_id))return false;
        $this->config['config_other']=str_replace('J','',$this->config['config_other']);
        $params = array(
            'merchantCode'            => $this->config['config_partner'],//商户号
            'terminalCode'            => $this->config['config_other'],//终端号
            'merchantOrderId'         => $out_trade_no,//商户订单号
            'originalOrderId'         => $transaction_id,//银商订单号
        );
        $token=$this->getToken();if(is_array($token))return $token;
        $headers=array('Authorization:'.$token);
        $result=$this->curlinit($this->gateway.'v2/poslink/transaction/query', $params,$headers);
        if($result['errCode']=='00'){
            if($result['queryResCode']=='0'){
                $result['out_trade_no']=$out_trade_no;
                $this->setInfo($result);
                $succCode=1;
            }
            if($result['queryResCode']=='FF'){
                $succCode=2;
            }
        }
        return $result;
    }
    /**
	 * 
	 * 撤销订单
	 * @param string $out_trade_no银商订单号
	 */
    public function cancel($out_trade_no){
        if(empty($out_trade_no))return false;
        $this->config['config_other']=str_replace('J','',$this->config['config_other']);
        $params = array(
            'merchantCode'            => $this->config['config_partner'],//商户号
            'terminalCode'            => $this->config['config_other'],//终端号
            'originalOrderId'         => $out_trade_no,//银商订单号
        );
        $token=$this->getToken();if(is_array($token))return $token;
        $headers=array('Authorization:'.$token);
        return $this->curlinit($this->gateway.'v2/poslink/transaction/voidpayment', $params,$headers);
    }
    public function refund($out_trade_no,$trade_no,$refund_amount,$refund_sn){
        $pay_money=idtoname($trade_no,'PayLog','scan_money','pay_sn');
        if($pay_money==$refund_amount){
            return $this->voidpayment($out_trade_no,$trade_no,$refund_sn);
        }else{
            return $this->refund_real($out_trade_no,$trade_no,$refund_amount,$refund_sn);            
        }
    }
    /**
     * 订单退款
     * @param  [type] $out_trade_no  商家订单号
     * @param  [type] $trade_no      支付交易号
     * @param  [type] $refund_amount 退款金额
     * @return [type] $refund_sn     退款单号
     */
    public function refund_real($out_trade_no,$trade_no,$refund_amount,$refund_sn){
        if(empty($out_trade_no))return false;
        $res=array('status'=>0,'msg'=>'');
        $res['msg'] = '暂不支持部分退款';return $res;
        $this->config['config_other']=str_replace('J','',$this->config['config_other']);
        $params = array(
            'merchantCode'            => $this->config['config_partner'],//商户号
            'terminalCode'            => $this->config['config_other'],//终端号
            'originalOrderId'         => $trade_no,//银商订单号
            'refundRequestId'         => $refund_sn,//退款请求标识
            'transactionAmount'       => $refund_amount*100,//退货金额
        );
        $headers=array('Authorization:'.$this->getToken());
        $result= $this->curlinit($this->gateway.'v2/poslink/transaction/refund', $params,$headers);
        if($result['errCode']=='00'){
            $payment_refund = idtoname($refund_sn,'PaymentRefund','*','refund_sn');
            $status =1;
            D('Common/OrderInfo')->payment_refund($refund_sn,$status);           
            $info['status'] = true;
            $info['money'] = $payment_refund['money'];
            $info['out_trade_no'] = $payment_refund['order_id'];
            $info['pay_sn'] = $payment_refund['trade_no'];
            D('Common/OrderInfo')->refund_order($info);
            $res['status'] = 1;
			$res['msg'] = '退款成功';
        }else{
            $res['msg'] = $result['errInfo'];
        }return $res;
    }
    /**
     * 支付撤销
     * @param  [type] $out_trade_no  商家订单号
     * @param  [type] $trade_no      支付交易号
     * @return [type] $refund_sn     退款单号
     */
    public function voidpayment($out_trade_no,$trade_no,$refund_sn){
        if(empty($out_trade_no))return false;
        $res=array('status'=>0,'msg'=>'');
        $this->config['config_other']=str_replace('J','',$this->config['config_other']);
        $params = array(
            'merchantCode'            => $this->config['config_partner'],//商户号
            'terminalCode'            => $this->config['config_other'],//终端号
            'originalOrderId'         => $trade_no,//银商订单号
        );
        $token=$this->getToken();if(is_array($token))return $token;
        $headers=array('Authorization:'.$token);
        $result= $this->curlinit($this->gateway.'v2/poslink/transaction/voidpayment', $params,$headers);
        if($result['errCode']=='00'){
            $payment_refund = idtoname($refund_sn,'PaymentRefund','*','refund_sn');
            $status =1;
            D('Common/OrderInfo')->payment_refund($refund_sn,$status);           
            $info['status'] = true;
            $info['money'] = $payment_refund['money'];
            $info['out_trade_no'] = $payment_refund['order_id'];
            $info['pay_sn'] = $payment_refund['trade_no'];
            D('Common/OrderInfo')->refund_order($info);
            $res['status'] = 1;
            $res['msg'] = '退款成功';
        }else{
            $res['msg'] = $result['errInfo'];
        }return $res;
    }
    /**
     * 激活设备
     */
    private function activeterminal(){
        $token=$this->getToken();
        $params =array(
            'merchantCode'=>$this->config['config_partner'],//商户号
            'terminalCode'=>$this->config['config_other'],//终端号
        );
        $headers=array('Authorization:OPEN-ACCESS-TOKEN AccessToken='.$token);
        $result=$this->curlinit($this->gateway.'v2/poslink/transaction/activeterminal', $params,$headers);
        
        if($result['errCode']=='00'){
            $map=$data=array();
            $map['code']='Chinaumspos';
            $data['config_other']='J'.$this->config['config_other'];
            M('Payment')->where($map)->save($data);
            return true;
        }return false;
    }
    private function getToken() {// 从缓存获取ACCESS_TOKEN
        if($this->config['config_account']=='46938142602cb7a201607414a8580d77'){
            $token= $this->getTokennew();
            if($token && !is_array($token))return $token;
        }
        static $stoken = null;		
        $cachename='PAY_CHINAUMS_TOKEN';
		is_null($stoken) && $stoken = S($cachename);
        if(is_array($stoken) && $stoken['accessToken'] && $stoken['expiresIn']>NOW_TIME)return $stoken['accessToken'];        
        $param =array(
            'appId'=>$this->config['config_account'],//AppId
            'timestamp'=>time_format(NOW_TIME,'YmdHis'),//AppId
            'nonce'=>randStr(32),//随机数长度不超过128位
        );
        $param['signature']=SHA1(implode('',$param).$this->config['config_key']);
        $result=$this->curlinit($this->gateway.'v1/token/access', $param);
        if($result['errCode']=='0000'){
            $cachedata['accessToken']=$result['accessToken'];
            $cachedata['expiresIn']=NOW_TIME+$result['expiresIn'];
            S($cachename,$cachedata,60*60);
            return $result['accessToken'];
        }else{
            $result=array('status'=>0,'msg'=>$result['errInfo'].$result['errCode']);
            return $result;
        }
    }
    private function getTokennew() {// 从缓存获取ACCESS_TOKEN        
        static $stoken = null;		
        $cachename='PAY_CHINAUMS_TOKEN';
		is_null($stoken) && $stoken = S($cachename);
        if(is_array($stoken) && $stoken['accessToken'] && $stoken['expiresIn']>NOW_TIME)return $stoken['accessToken'];        
    
        $param=array(
            'action'=>'getchinaumstoken',
            'signtype'=>'sha1',
            'appid'=>C('appid'),//站点ID
            'timestamp'=>NOW_TIME,//时间戳
        );
        ksort($param);$key=C('SAAS_APPSECRET');
        $param['sign']= sha1(format_array2http($param).$key);
        $url='http://www.hanchao9999.com/index.php?s=/home/saas/index';
        $result=curlget($url,$param,'POST');$result=json_decode($result,1);
        if($result['status']==1 && !empty($result['accessToken'])){
            $resultbody['accessToken']=$result['accessToken'];
            $resultbody['expiresIn']=$result['expiresIn'];
            S($cachename,$resultbody,60*60);
            return $resultbody['accessToken'];
        }else{
            if(empty($result['msg']))$result['msg']='获取token失败';
            return $result;
        }
    }
    protected function getSignVerify($param, $sign) {return true;}
    public function get_pay_code($info='') {print_r($this->config);
        $type=I('type');
        $payCode=I('code');
        if(empty($type)){
            $token=$this->getToken();
            print_r($token);echo "\n";
            $params =array(
                'merchantCode'=>$this->config['config_partner'],//商户号
                'terminalCode'=>$this->config['config_other'],//终端号
            );
            $headers=array('Authorization:OPEN-ACCESS-TOKEN AccessToken='.$token);
            echo "header:\n";
            print_r($headers);
            echo "参数:\n";
            print_r($params);
            $result=$this->curlinit($this->gateway.'v2/poslink/transaction/activeterminal', $params,$headers);
            return $result;
        }else{$getOrderNo=NOW_TIME;if(empty($payCode))$payCode='1348'.NOW_TIME;
            $this->config['config_other']=str_replace('J','',$this->config['config_other']);      
            $token=$this->getToken();if(is_array($token))return $token;      
            $params = array(
                'merchantCode'            => $this->config['config_partner'],//商户号
                'terminalCode'            => $this->config['config_other'],//终端号
                'transactionAmount'       => 1,//交易金额单位：分
                'transactionCurrencyCode' => '156',//交易币种
                'merchantOrderId'         => $getOrderNo,//商户订单号
                'merchantRemark'          => '扫码付',//商户备注
                'payMode'                 => 'CODE_SCAN',//支付方式
                'payCode'                 => $payCode,//支付码
            );
            $headers=array('Authorization:'.$token);
             echo "header:\n";
            print_r($headers);
            echo "url:\n";
            echo $this->gateway.'v2/poslink/transaction/pay'."\n";
            echo "参数:\n";
            print_r($params);
            $result=$this->curlinit($this->gateway.'v2/poslink/transaction/pay', $params,$headers);
            print_r($result);exit;    
            return $result;
        }
    }
    /**
     * 针对notify_url验证消息是否是支付宝发出的合法消息
     * @return 验证结果
     */
    public function verifyNotify($notify) {
        //生成签名结果
        $isSign = $this->getSignVerify($notify, $notify["sign"]);
        if ($isSign) {
        $this->setInfo($notify);return true;}else {return false;}
    }
    /**
     * curl 请求
     * @param string $url请求地址
     * @param array $post 参数
     */
    private function curlinit($url,$post,$headers=false){
        $header=array('Content-Type:application/json');
        if($headers)$header=array_merge($header,$headers);
        $param_str=json_encode($post);
        $result=curlget($url, $param_str,'POST',$header,true);
        $res = json_decode($result,true);
        return $res;
   }
    protected function setInfo($notify) {
        $info = array();
        //支付状态
        $info['status']=$notify['errCode']=='00'?true:false;
        $info['money'] = $notify['originalTransactionAmount']/100;
        $info['out_trade_no'] = $notify['out_trade_no'];
        $info['pay_sn'] = $notify['orderId'];
        $info['pay_codes']=$notify['thirdPartyName'];
        $this->info = $info;
    }
    
}
?>