招商银行一网通H5接口调试和测试报告撰写注意事项

最近有朋友需要在微信小程序内使用招商银行一网通支付,目前能支持的支付类型只有H5支付接口,所以记录下整个调试流程和调试过程可能出现的问题,写测试报告时需要注意的事项也记录下,以备以后需要时,可以及时找出,免踩坑。
微信小程序下H5支付,用户操作流程,小程序(小程序原生)内通过点击—》访问到提交订单页面(webview包含的订单外链页)-》跳转到一网通H5支付页面——》支付成功回到支付成功页面(webview包含的订单外链页)——》点击支付完成回到小程序页面(小程序原生)
一网通H5操作流程图
招商银行一网通H5接口调试和测试报告撰写注意事项
以下流程采用PHP进行调试和测试
先定义一个总配置数组

$config = [
    'use_sandbox' => true, // 是否使用 招商测试系统

    'branch_no' => 'xxxx',  // 商户分行号,4位数字
    'mch_id'    => 'xxxx', // 商户号,6位数字
    'mer_key'   => '1234567890123456', // 秘钥16位,包含大小写字母 数字

    // 招商的公钥,建议每天凌晨2:15发起查询招行公钥请求更新公钥。
    'cmb_pub_key' => 'xxxx',

    'op_pwd'    => 'xxxxxx', // 操作员登录密码。
    'sign_type' => 'SHA-256', // 签名算法,固定为“SHA-256”
    'limit_pay' => 'A', // 允许支付的卡类型,默认对支付卡种不做限制,储蓄卡和信用卡均可支付   A:储蓄卡支付,即禁止信用卡支付

    'notify_url' => 'http://cmb.admin.com/cmb_tz.php', // 支付成功的回调

    'sign_notify_url' => 'http://cmb.admin.com/cmb_tz.php', // 成功签约结果通知地址
    'sign_return_url' => 'http://cmb.admin.com', // 成功签约结果通知地址

    'return_url' => 'http://cmb.admin.com/cmb_ok.php', // 如果是h5支付,可以设置该值,返回到指定页面
];

一网通支付时需要一个sign签名字段,签名内容是reqData内容,定义一个签名函数

//签名
function make_sign($mer_key,$str){

    $reqData = arraySort($str);
    $signStr = createLinkString($reqData);

    $signStr .= '&'.$mer_key;
//SHA-256签名
    $baSrc = mb_convert_encoding($signStr,"UTF-8");
    $baResult = hash('sha256', $baSrc);
//转为16进制字符串(可选)
//$sign = bin2hex($baResult);

    return $baResult;
}

1.一网通支付中H5类型,可能用到的接口有3个,获取公钥接口、一网通下单接口、查询订单接口

//一网通获取公钥地址(测试)
$QueryKeyAPI_test = 'http://mobiletest.cmburl.cn/CmbBank_B2B/UI/NetPay/DoBusiness.ashx';
//一网通下单地址(测试)
$OneCardPayAPI_test = 'http://121.15.180.66:801/netpayment/BaseHttp.dll?MB_EUserPay';
//$OneCardPayAPI_test ='http://paytest.cmburl.cn:801/netpayment/BaseHttp.dll?MB_EUserPay';
//查询订单
$DoBusiness_test = 'http://121.15.180.66:801/netpayment_directlink_nosession/BaseHttp.dll?QuerySingleOrder';

2.获取公钥目的套用一网通自己的话:使用招行公钥验签(用于对“成功签约结果通知”和“成功支付结果通知”接收到的通知报文进行验签)
(1)公钥获取的数组

$pub_get_data = [

    'version'  => '1.0',
    'charset'  => 'UTF-8',
    'signType' => $config['sign_type'],
    'reqData'  => [
        'dateTime'   => date('YmdHis', $nowTime),
        'txCode'     => 'FBPK',
        'branchNo'   => $config['branch_no'],
        'merchantNo' => $config['mch_id'],
    ],

];

公钥获取方式可以直接采用CURL方式获取。
对reData内容进行签名,Json后然后放入jsonRequestData字段:

$baResult = make_sign($config['mer_key'],$pub_get_data['reqData']);
$pub_get_data['sign']=$baResult;
$formParams['jsonRequestData']=json_encode($pub_get_data, JSON_UNESCAPED_UNICODE);

最后采用Curl请求,获取公钥。(go_curl函数文章后面提供)

go_curl($QueryKeyAPI_test,'POST',$formParams);

2.提交订单(一网通支付)
订单结构:

$tradeNo = time() . rand(1000, 9999);
$timeExpire = "30";
//数据结构
$pay_get_data = [

    'version'  => '1.0',
    'charset'  => 'UTF-8',
    'signType' => $config['sign_type'],
    'reqData'  => [
        'dateTime'         => date('YmdHis', $nowTime),
        'branchNo'         => $config['branch_no'],
        'merchantNo'       => $config['mch_id'],
        'date'             => date('Ymd',  $nowTime),
        'orderNo'          => $tradeNo,
        'amount'           => "0.01", // 固定两位小数,最大11位整数
        'expireTimeSpan'   => $timeExpire,
        'payNoticeUrl'     => $config['notify_url'],
        //'payNoticePara'    =>  '',
        'returnUrl'        => $config['return_url'],
        //'clientIP'         =>  '',
        //'cardType'         => $config['limit_pay'], // A:储蓄卡支付,即禁止信用卡支付
        // 'agrNo'            => '',
        // 'merchantSerialNo' =>  '',
        //'userID'           => '',
        // 'mobile'           =>  '',
        // 'lon'              => '',
        // 'lat'              => '',
        // 'riskLevel'        => '',
        'signNoticeUrl'    => $config['sign_notify_url'],
        // 'signNoticePara'   =>  '',
    ],

];

注释部分不是必填的,具体参考一网通官方接口说明。
获取请求报文:

$baResult1 = make_sign($config['mer_key'],$pay_get_data['reqData']);
$pay_get_data['sign']=$baResult1;
$formParams1['charset'] = 'UTF-8';
$formParams1['jsonRequestData']=json_encode($pay_get_data);

这里和取得公钥的方法不太一样,需要直接采用form表单的方式提交跳转(可使用js自动提交)

<form action="<?php echo $OneCardPayAPI_test?>" method="post" />
<input type="hidden" name="jsonRequestData" value='<?php echo $formParams1['jsonRequestData']?>' />
<input type="hidden" name="charset" value='UTF-8' />
<input type="submit" value="提交订单">
</form>

结构无误的情况下,提交后自动跳转支付页面。
3.查询订单

$reqData = [
    'dateTime' => date('YmdHis', $nowTime),
    'branchNo' => $config['branch_no'],
    'merchantNo' => $config['mch_id'],
    'date' => date('Ymd',  time()),
    'type' => 'B',
   // 'bankSerialNo' => '',
    'orderNo' => $tradeNo
];
$baResult2 = make_sign($config['mer_key'],$reqData);



$jsonRequestData = [
    'version'  => '1.0',
    'charset'  => 'UTF-8',
    'signType' => $config['sign_type'],
    'sign' => $baResult2,
    'reqData' => $reqData
];

$formParams2['charset'] = 'UTF-8';
$formParams2['jsonRequestData']=json_encode($jsonRequestData);

查询订单采用Type中的B类型,商户自己的订单编号,这里需要注意的是,如果要查询真实(测试)订单时,需要订单编号orderNo和支付时间date完全正确哦,如你查询今天的订单号,用了昨天的时间那就会查不到。(测试报告需要 查询1给正确订单和1个失败订单)

注意事项:
‘branch_no’ => ‘xxxx’, // 商户分行号,4位数字 ‘mch_id’ => ‘xxxx’, // 商户号,6位数字 ‘mer_key’ => ‘1234567890123456’, // 秘钥16位,包含大小写字母 数字
这3个参数需要联系一网通获取,服务器ip需要过一网通白名单ip,否则无法测试成功哦
关于测试报告:
招行一网通主要测试项目有4个,正常这4个测试通过(H5支付商户测试验收报告),就可以申请正式账号了。 分别是: CMB_test003CMB_test004 和 CMB_test008CMB_test009
3和4分别通过步骤2 提交2个订单,分别用储蓄卡和信用卡进行提交(一网通提供测试卡号)。 8输入3或4提交通过的订单,查询返回并截图。 9输入任意不存在订单号,截图就可以了

附录:
go_curl函数

//提交
function go_curl($url, $type, $data = false, &$err_msg = null, $timeout = 20, $cert_info = array())
{
    $type = strtoupper($type);
    if ($type == 'GET' && is_array($data)) {
        $data = http_build_query($data);
    }
    $option = array();
    if ( $type == 'POST' ) {
        $option[CURLOPT_POST] = 1;
    }
    if ($data) {
        if ($type == 'POST') {
            $option[CURLOPT_POSTFIELDS] = $data;
        } elseif ($type == 'GET') {
            $url = strpos($url, '?') !== false ? $url.'&'.$data :  $url.'?'.$data;
        }
    }
    $option[CURLOPT_URL]            = $url;
    $option[CURLOPT_FOLLOWLOCATION] = TRUE;
    $option[CURLOPT_MAXREDIRS]      = 4;
    $option[CURLOPT_RETURNTRANSFER] = TRUE;
    $option[CURLOPT_TIMEOUT]        = $timeout;
    //设置证书信息
    if(!empty($cert_info) && !empty($cert_info['cert_file'])) {
        $option[CURLOPT_SSLCERT]       = $cert_info['cert_file'];
        $option[CURLOPT_SSLCERTPASSWD] = $cert_info['cert_pass'];
        $option[CURLOPT_SSLCERTTYPE]   = $cert_info['cert_type'];
    }
    //设置CA
    if(!empty($cert_info['ca_file'])) {
        // 对认证证书来源的检查,0表示阻止对证书的合法性的检查。1需要设置CURLOPT_CAINFO
        $option[CURLOPT_SSL_VERIFYPEER] = 1;
        $option[CURLOPT_CAINFO] = $cert_info['ca_file'];
    } else {
        // 对认证证书来源的检查,0表示阻止对证书的合法性的检查。1需要设置CURLOPT_CAINFO
        $option[CURLOPT_SSL_VERIFYPEER] = 0;
    }
    $ch = curl_init();
    curl_setopt_array($ch, $option);
    $response = curl_exec($ch);
    $curl_no  = curl_errno($ch);
    $curl_err = curl_error($ch);
    curl_close($ch);
    // error_log
    if($curl_no > 0) {
        if($err_msg !== null) {
            $err_msg = '('.$curl_no.')'.$curl_err;
        }
    }
    return $response;
}

以上代码可以Gitee上下载,地址:一网通H5支付测试Demo
如果对您有帮助,麻烦给个Star吧,谢谢!

上一篇:Redis的基本知识


下一篇:一个威屁嗯的实现思路,防封