PHP之银联手机控件支付

Stephen 后端开发 2019-03-18 17:49:11

先说一个题外话:

银联支付接起来,相对有点麻烦,尤其是网上关于银联手机控件支付PHP后端的DEMO少之又少,今天接入银联手机空间支付发起请求的时候,报了个一个错误


{"Invalid request.":""}
一直找不到问题原因,打印请求参数,才发现证书ID certId为null,但接入方法都是用的SDK上的DEMO,证书路径也都配对了,certId怎么会是null呢,一直找不到问题,后咨询了客服,客服给我发了一个图片,提示用错证书,我还再三向客服确认了是不是那几个证书,确认了问题,也知道报错原因后,决定自己研究SDK代码,后来终于找到了,我犯了一个很傻的错误,由于我用的是docker环境,证书路径居然是用的宿主机的证书路径,然后我把证书路径改为docker容器路径后,终于请求并验签成功了。



银联手机控件支付PHP端接入方法:

1.将下载的PHP SDK代码的sdk目录(PHP Version SDK/upacp_demo_app/sdk)拷贝到vendor/union目录下

2.将测试环境证书(PHP Version SDK/upacp_demo_app/assets/测试环境证书)复制到服务器上,正式环境用生产环境证书,生产环境证书有三个,外加一个入网签约时银联颁发的验签私钥证书

3.修改sdk配置文件(vendor/union/acp_sdk.ini)中的证书路径和地址等等

4.请求方法:

public function pay($orderNo, $money, $subject="订单描述")
{
    $config = [
        "callback" => "",
        "merId" => "88888888",
    ];
    $params = [
        //以下信息非特殊情况不需要改动
        'version' => SDKConfig::getSDKConfig()->version, //版本号
        'encoding' => 'utf-8', //编码方式
        'txnType' => '01', //交易类型
        'txnSubType' => '01', //交易子类
        'bizType' => '000201', //业务类型
        //'frontUrl' =>  SDKConfig::getSDKConfig()->frontUrl, //前台通知地址
        'backUrl' => $config['callback'], //后台通知地址
        'signMethod' => SDKConfig::getSDKConfig()->signMethod, //签名方法
        'channelType' => '08', //渠道类型,07-PC,08-手机
        'accessType' => '0', //接入类型
        'currencyCode' => '156', //交易币种,境内商户固定156

        //TODO 以下信息需要填写
        'orderDesc' => $subject, //订单描述
        'merId' => $config['merId'], //商户代码,请改自己的测试商户号,此处默认取demo演示页面传递的参数
        'orderId' => $orderNo, //商户订单号,8-32位数字字母,不能含“-”或“_”,此处默认取demo演示页面传递的参数,可以自行定制规则
        'txnTime' => date('YmdHis'), //订单发送时间,格式为YYYYMMDDhhmmss,取北京时间,此处默认取demo演示页面传递的参数
        'txnAmt' => $money*100,	 //交易金额,单位分,此处默认取demo演示页面传递的参数
    ];
    AcpService::sign($params); //获取证书ID和签名
    $url = SDKConfig::getSDKConfig()->appTransUrl; //获取银联请求地址
    $result_arr = AcpService::post($params, $url);
    if(count($result_arr)<=0) { //没收到200应答的情况
        return "";
    }
    //验签通过,返回授权码给客户端
    if(AcpService::validate($result_arr)){
        return $result_arr['respCode'] == "00" ? $result_arr["tn"] : '';
    }
}
5.异步通知回调(回调功能还没测试,测试后再来修改,先把代码写在这里)

public function notify(Request $request)
{
    $post = $request->post();
    $flag = $this->notify($post);
    if($flag){
        //处理订单信息,修改数据库订单支付状态

        echo '302';
    }
}

//验签
public function notify($post)
{
    if(isset($post['signature'])){
        $res = AcpService::validate($post);
        $orderId = $post['orderId'];
        $respCode = $post['respCode'];
        //涉及到资金交易,需查询订单情况,这一点和支付宝、微信不同
        return $this->query($orderId);
    }
}

//查询订单交易状态
public function query($orderId)
{
    $params = [
        //以下信息非特殊情况不需要改动
        'version' => SDKConfig::getSDKConfig()->version, //版本号
        'encoding' => 'utf-8', //编码方式
        'signMethod' => SDKConfig::getSDKConfig()->signMethod, //签名方法
        'txnType' => '00', //交易类型
        'txnSubType' => '00', //交易子类
        'bizType' => '000000', //业务类型
        'accessType' => '0', //接入类型
        'channelType' => '08', //渠道类型

        //TODO 以下信息需要填写
        'orderId' => $orderId, //请修改被查询的交易的订单号,8-32位数字字母,不能含“-”或“_”,此处默认取demo演示页面传递的参数
        'merId' => $this->merId, //商户代码,请改自己的测试商户号,此处默认取demo演示页面传递的参数
        'txnTime' => date('YmdHis'), //请修改被查询的交易的订单发送时间,格式为YYYYMMDDhhmmss,此处默认取demo演示页面传递的参数
    ];
    AcpService::sign ( $params ); // 签名
    $url = SDKConfig::getSDKConfig()->singleQueryUrl;
    $result_arr = AcpService::post($params, $url);
    if(count($result_arr)<=0) { //没收到200应答的情况
        return false;
    }
    if(AcpService::validate($result_arr)){
        return $result_arr['respCode'] == "00" && $result_arr['origRespCode'] == "00" ? true : false;
    }
}


分享

评论