PHP原生服务端签名生成请求订单信息「orderString」

来自    APP支付与登录 | 
作者:Mitsein  |  更新于:2017-07-06 15:47:32     
PHP原生服务端签名生成请求订单信息「orderString」仅供参考

接口文档:https://docs.open.alipay.com/204/105465/

第一步:配置开发者信息「私钥」And「App_id

/* 配置信息 */
// 支付宝分配给开发者的应用ID
$app_id='';
// 开发者私钥,为这里填入方便,去头、去尾、去换行 字符串私钥,私钥处理放在签名方法内。
$private_key='';
// 商户生成签名字符串所使用的签名算法类型,目前支持RSA2和RSA,推荐使用RSA2
$sign_type='RSA2';
/* 配置信息 */


第二步:组装部分请求参数

根据接口文档组装参数 app_id、method、format、timestamp、charset、version、notify_url、sign_type
/* 组装请求参数部分start */
       
// 支付宝分配给开发者的应用ID
$params['app_id'] = $app_id;
// 接口名称
$params['method'] = 'alipay.trade.app.pay';
// 仅支持JSON
$params['format'] = 'json'; 
// 发送请求的时间,格式"yyyy-MM-dd HH:mm:ss"
$params['timestamp'] = date("Y-m-d H:i:s");
// 请求使用的编码格式,如utf-8,gbk,gb2312等
$params['charset'] = 'UTF-8';
// 调用的接口版本,固定为:1.0
$params['version'] = '1.0';
// 支付宝服务器主动通知商户服务器里指定的页面http/https路径。建议商户使用https
$params['notify_url'] = '';
// 商户生成签名字符串所使用的签名算法类型,目前支持RSA2和RSA,推荐使用RSA2
$params['sign_type'] = $sign_type;
       
/* 组装请求参数部分end */


第三步:组装业务参数json格式,并填充在$params数组中

根据业务需求组装需要用到的业务参数
/* 组装业务参数json */
// 对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。
$bizcontent['body'] = '非sdk原生php服务端生成请求订单';
// 商品的标题/交易标题/订单标题/订单关键字等。
$bizcontent['subject'] = 'php代码示例';
       
/* 生成随机数作为外部订单号start */
$date=date("YmdHis"); 
$arr=range(1000,9999);
shuffle($arr);
$out_trade_no=$date.$arr[0];
/* 生成随机数作为外部订单号end */
// 商户网站唯一订单号
$bizcontent['out_trade_no'] = $out_trade_no;
// 设置未付款支付宝交易的超时时间,一旦超时,该笔交易就会自动被关闭。当用户进入支付宝收银台页面(不包括登录页面),会触发即刻创建支付宝交易,此时开始计时。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m。
$bizcontent['timeout_express']='10m';
// 订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]
$bizcontent['total_amount'] = '0.01';
// 销售产品码,商家和支付宝签约的产品码
$bizcontent['product_code'] = 'QUICK_MSECURITY_PAY';
// 商品主类型:0—虚拟类商品,1—实物类商品 注:虚拟类商品不支持使用花呗渠道
$bizcontent['goods_type'] = '0';
// 公用回传参数,如果请求时传递了该参数,则返回给商户时会回传该参数。支付宝会在异步通知时将该参数原样返回。本参数必须进行UrlEncode之后才可以发送给支付宝
$bizcontent['passback_params']='spicy%3d%e8%87%aa%e5%ae%9a%e4%b9%89%e5%8f%82%e6%95%b01%26custom%3d%e8%87%aa%e5%ae%9a%e4%b9%89%e5%8f%82%e6%95%b02';
       
$biz_content=json_encode($bizcontent,JSON_UNESCAPED_UNICODE);
/* 组装业务参数json */
       
// 将业务参数填充在请求参数内
$params['biz_content'] = $biz_content;


第四步:排序签名得到sign,并填充在$params数组中「签名方法请往下翻

// 排序
ksort($params);
// 调用签名方法得到sign填入请求参数
$params['sign'] = sign($params, $params['sign_type'], $private_key);


第五步:将参数urlencode输出查看,打印出来的参数可以直接放在客户端使用

// htmlspecialchars是为防止浏览器将参数中的「×」和「¬」转义
echo htmlspecialchars(http_build_query($params));

工具方法:签名方法和检查是否为空方法

/**  
* 签名函数 
* 
* @param array $params 请求参数数组
* @param string $signType 签名方式
* @param string $private_key 为了方便只要填一行字符串
* @return string 返回类型
*/
function sign($params,$signType,$private_key){
    $stringToBeSigned = "";
    $i = 0;
    // 将数组使用&符号拼接
    foreach ($params as $k => $v) {
        if (false === checkEmpty($v) && "@" != substr($v, 0, 1)) {
            if ($i == 0) {
                $stringToBeSigned .= "$k" . "=" . "$v";
            } else {
                $stringToBeSigned .= "&" . "$k" . "=" . "$v";
            }
            $i++;
        }
    }
    unset ($k, $v);
       
    // 私钥处理
    $res = "-----BEGIN RSA PRIVATE KEY-----".PHP_EOL.wordwrap($private_key, 64, PHP_EOL, true).PHP_EOL."-----END RSA PRIVATE KEY-----";
    ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置'); 
       
    // 
    if ("RSA2" == $signType) {
        openssl_sign($stringToBeSigned, $sign, $res, OPENSSL_ALGO_SHA256);
    } else {
        openssl_sign($stringToBeSigned, $sign, $res);
    }
    return base64_encode($sign);
}
       
/**  
* 检查是否为空
* 
* @param string $value 请求参数数组
* @return bool 返回类型
*/
function checkEmpty($value) {
    if (!isset($value))
        return true;
    if ($value === null)
        return true;
    if (trim($value) === "")
        return true;
    return false;
}
赵世杰 | 2017-12-22 10:32:17
根据你的先关代码报错ALI38173  输出参数如下:能帮我看看哪里的问题吗app_id=2017030806124852&biz_content=%7B%22body%22%3A%22%E9%9D%9Esdk%E5%8E%9F%E7%94%9Fphp%E6%9C%8D%E5%8A%A1%E7%AB%AF%E7%94%9F%E6%88%90%E8%AF%B7%E6%B1%82%E8%AE%A2%E5%8D%95%22%2C%22subject%22%3A%22php%E4%BB%A3%E7%A0%81%E7%A4%BA%E4%BE%8B%22%2C%22out_trade_no%22%3A%22201712221030298377%22%2C%22timeout_express%22%3A%2210m%22%2C%22total_amount%22%3A%220.01%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22goods_type%22%3A%220%22%2C%22passback_params%22%3A%22spicy%253d%25e8%2587%25aa%25e5%25ae%259a%25e4%25b9%2589%25e5%258f%2582%25e6%2595%25b01%2526custom%253d%25e8%2587%25aa%25e5%25ae%259a%25e4%25b9%2589%25e5%258f%2582%25e6%2595%25b02%22%7D&charset=UTF-8&format=json&method=alipay.trade.app.pay&notify_url=&sign_type=RSA2&timestamp=2017-12-22+10%3A30%3A29&version=1.0&sign=RWQ674oVF8ukkID1ugzU04jAn1qzVCBr2hMsjgmIQQE26o71%2BxwD1amBLl0Z7WIhENQm8urMDn4QM9hJlprSanT66sQTxUwsxRCL98Eskrs45Laro5VFegnLJYxkHaGynZd6%2B3tD6lmRLgknhat3rf0c%2BNRQ3d1qgqbkRSF3eKJu1wkg%2BF5gYSnRRQTL2ySbRV6R2ekCe6yxYId02RxPBHjwniRVGThr90RF5wz7cktNUCsAtkoHtQH2rOB627aHj%2FRU3tGxF%2Fe56mGQ8AkSmFfVZuwqWDz5HSg2UIitacVvCph8VBg2a1gHGywIZfaU%2BsIm8L06G1q2ENb9HeGtpQ%3D%3D
我是个导演 | 2017-12-22 10:57:51
赵世杰:根据你的先关代码报错ALI38173  输出参数如下:能帮我看看哪里的问题吗app_id=2017030806124852&biz_content=%7B%22body%22%3A%22%E9%9D%9Esdk%E5%8E%9F%E...回到原帖
&要改成&,goods_type "passback_params 这样的参数不要传,先传必传测试测试
赵世杰 | 2017-12-29 16:34:06
我是个导演:&要改成&,goods_type "passback_params 这样的参数不要传,先传必传测试测试回到原帖
谢谢了。调试出来了
赵世杰 | 2017-12-30 14:46:25
我是个导演:&要改成&,goods_type "passback_params 这样的参数不要传,先传必传测试测试回到原帖
&改成&,goods_type "passback_params 这样的参数不要传我去掉后可以拉起支付,notify_url我添加上数据就报错notify_url路径有什么特殊要求吗
赵世杰 | 2017-12-30 14:47:57
&改成&,goods_type "passback_params 这样的参数不要传我去掉后可以拉起支付,notify_url我添加上数据就报错notify_url路径有什么特殊要求吗
战狼 | 2018-01-02 14:43:43
你好,notify_url异步通知是post方式接收的 ,必须公网可以访问,http或https://格式的完整路径,不能加?id=123这类自定义参数,不能重定向。
么么lalala | 2018-01-11 17:48:49
能帮我看一下吗,我的也是出错;
alipay_sdk=alipay-sdk-php-20161101&app_id=2017080509768179&biz_content={"body":"NIHAO","subject": "享停车位支付","out_trade_no": "201801110001","timeout_express": "15m","total_amount": "0.01","product_code":"QUICK_MSECURITY_PAY","passback_params":"shared_pay"}&charset=UTF-8&format=json&method=alipay.trade.app.pay&notify_url=http://api.youyoutingche.com/ytapi/alinotify.php&sign_type=RSA2&timestamp=2018-01-11 17:04:26&version=1.0&sign=MCw6Mo5880ALo4pRCMXSpsq4H9tuFAMBWzMW1YUh27AqkfT7X5ZOghYYlnxVPL1AF+QGAdorfrsGN267AVT2a3fatABMuMvhBwPHUNiJveZzMi5lzqX2NszFg3Damt7DvKR97nPLMA5IXuzQibbGcxnR+Jpdj1IjiiLapyd6odVZd1YDsJgV+WbH72OuRS4aIemsJ1MwvO8vXeOViozscWyOxs574pY4vAgijE9xyCZ1BLCnSeKFO077dRVw9WgxJT2BIVMDbHRoCjJ5I5cl73PX6G6GzHJ00eFnu2ELKEx6nc0HyJuIMy1nfJ31vJus9pGHYtPhlQeFeFoLwRHP5A==
我是个导演 | 2018-01-11 18:17:39
么么lalala:能帮我看一下吗,我的也是出错;
alipay_sdk=alipay-sdk-php-20161101&app_id=2017080509768179&biz_content={"body":"NIHAO","subject": "享停车位支...
回到原帖
报了什么错误?麻烦提供一下报错信息或者截图方便判断问题
么么lalala | 2018-01-11 22:18:03
我是个导演:报了什么错误?麻烦提供一下报错信息或者截图方便判断问题回到原帖
这个解决了,是ios端调用的问题,但现在是支付成功了,异步回调也能走得到,但$_POST的内容一直就是空,不知道是什么地方的原因,我是php后台
我是个导演 | 2018-01-12 09:09:23
么么lalala:这个解决了,是ios端调用的问题,但现在是支付成功了,异步回调也能走得到,但$_POST的内容一直就是空,不知道是什么地方的原因,我是php后台回到原帖
需要你提供一下appid+请求参数+交易号方便排查问题
么么lalala | 2018-01-12 09:17:01
我是个导演:需要你提供一下appid+请求参数+交易号方便排查问题回到原帖
好的,
app_id=2017081508210179&biz_content={"body":"车位ID:2653254c36452755_6566494","subject": "享停车位支付","out_trade_no": "YSB1102590010148","timeout_express": "15m","total_amount": "0.01","product_code":"QUICK_MSECURITY_PAY","passback_params":"shared_pay"}&charset=UTF-8&format=json&method=alipay.trade.app.pay&notify_url=http://api.youyoutingche.com/ytapi/alinotify.php&sign_type=RSA2&timestamp=2018-01-11 18:36:03&version=1.0
因为$_POST为空,所以没有支付宝的交易号,只有自己的out_trade_no;麻烦您了
我是个导演 | 2018-01-12 09:36:34
么么lalala:好的,
app_id=2017081508210179&biz_content={"body":"车位ID:2653254c36452755_6566494","subject": "享停车位支付","out_trade_no": "YS...
回到原帖
首先你的地址已经收到了通知,记录post信息需要写在日志中,我这边查到的是你返回不符合要求没有返回success返回的是array(27) { 建议使用率云排查自查一下:https://openclub.alipay.com/read.php?tid=2085&fid=72 有疑问再追问
鹅毛 | 2018-01-23 17:34:17
{"key":"_input_charset=utf-8&body=dcloud\u81f4\u529b\u4e8e\u6253\u9020html5\u6700\u597d\u7684\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u3002¬ify_url=http%3A%2F%2Flonnyk.lanqiulm.com%2Freward%2Freturn&out_trade_no=88881516699778947825&partner=2088102123816631&payment_type=1&seller_id=emaoapp@163.com&service=mobile.securitypay.pay&subject=dcloud\u9879\u76ee\u6350\u8d60&total_fee=0.1&sign=\"LIPuoGW0HMi4iB+vTC51lY+KlGgBydtFQiC0q\/S3yVbPolBtzkibxq1TF4VbtX1khAS52x+GpzyACVs1YOW8caZCfNjTz3lzCorD59mdmKSmfVr+HrjdnDlhpaofQVrQK0o7kdM0LKthQ0ReWNJe2QC+QHJEVEghuEw3AE5\/9QaK04cjibXUEVqRql1NhSePoebJzojUtemJtB5Nno1en6iYcwIdKgVxC7LI8hTypj5gcgU6Qn+Dtlgx0INSpPr4yLLWhU5GsF5rhTYFmQC1uK++KcsPv2at\/qQ+o9be2S6bVInokzauniPuJlslnBU\/PUx2mijszIVmOuOmCCTJHg==\"&sign_type=\"RSA\""}
能帮我看下问题么?  这是要给app返回sdk调用支付宝的参数。 一直报38173
颠覆白的黑 | 2018-01-23 17:53:41
鹅毛:{"key":"_input_charset=utf-8&body=dcloud\u81f4\u529b\u4e8e\u6253\u9020html5\u6700\u597d\u7684\u79fb\u52a8\u5f00\u53d1\u5...回到原帖
你是用demo测试的么?报错ali38173一般按照这个来排查(检查请求参数 ,对照我们的线上文档查看,比如:参数少了、多了、乱码、名称不对,还有必传参数是否都请求提交给支付宝了),这边解析了你提供的参数有误,
接口文档请求参数以及正确示例这个里面有:https://docs.open.alipay.com/59/103662/#s0
还有看见你接入的是老版本的app支付接口service=mobile.securitypay.pay
这边建议集成新版本的app支付:https://docs.open.alipay.com/204/105297/
有问题再追问
我的回复
回复数
 24
阅读数
 2341

返回顶部