♦ 背景
-
最近项目中需要接入【微信支付分】的服务,
本文以 【免确认订单模式】:即先享模式(评估不通过不可使用服务)的使用
在此做一下实现步骤,希望能对小伙伴有所帮助,欢迎指摘 …实现语言:
PHP
官方文档,请参考:
【>>> 微信支付分产品介绍】
☞ 前期准备
可直接参考指导文档
【>>>接入前准备】
-
- 首先商户向
weixinpay_scoreBD@tencent.com
发送邮件接入申请
一般都由 产品负责人员进行申请,
作为开发人员,重点在于阅读开发文档,编写测试用例
- 首先商户向
-
- 接口调用权限说明
此处引用官方解释如下:
- 接口调用权限说明
【免确认订单模式】是高级接口权限,需特殊申请才能使用。
使用支付分的行业/场景,目前只能调用【需确认订单模式】接口。
接口调用权限与服务id相关,在申请服务id时,只有上述场景下的服务 id,才有权限调用【免确认订单模式】接口。
即只有在上述场景下,创建支付分订单 api 接口中 need_user_confirm 字段才能传。
false:免确认订单。
以【免确认订单模式】为例,用户使用流程如下:
首次使用,用户先从商户端(小程序/app/H5),跳入微信支付分页面,进行商户服务的授权
授权成功后,商户即可通过后台接口,进行支付分订单的创建和完结。用户无需再进入支付分授权页面进行授权。
-
- 测试号配置指引
一般正式开发前,需进行
【>>> 微信支付分测试号配置指引】
☛ 开发指引
再次提醒,以【免确认模式】开发操作为例
- 流程分析
1. 首先,用户在商户侧下单购买产品或服务,此时,我们需要先对用户的授权状态进行查询
2. 引导用户开启授权服务
这一步需要根据实际场景,比如:APP场景调起支付分-授权服务、H5场景调起支付分-授权服务、小程序调起支付分-授权服务
3. 创建支付分订单
4. 商户为用户提供服务,待服务结束后,商户调用完结订单接口完结当前订单
5. 收到用户扣款成功通知,业务流程结束
▷ 第一步
引导用户开启授权服务
这一步需要前端的页面设计,主要在于引导开启授权服务
▷ 第二步
签名生成
服务端接口编写前,我们需要成功使用 微信官方要求的
>>>【签名规则】
-
请求签名串的构造规则如下:
-
通过参考文档,可以封装出一个方法,方便后期接口请求的使用
如下,即为鄙人整理的HTTP Header 头
封装方法:
/**
* @Notes: 签名封装方法
* @param $url 请求接口链接地址
* @param $type 请求方法 GET/POST
* @param $bodys 请求主体 json_encode() 处理后的字符串
* @return mixed
* @User: zhanghj
* @DateTime: 2023-08-31 18:18
*/
public function getToken($url,$type,$bodys= ''){
//请求头
$arr_header[] = "Content-Type: application/json";
$arr_header[] = "Accept: application/json";
$arr_header[] = "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3100.0 Safari/537.36" ;
//生成签名
$http_method = $type;
$timestamp = time();
$nonce = $this->createNoncestr(32);
$body = $bodys;
$merchant_id = "XXXXXXXXXXXXXXXXX"; //商户号
$serial_no = "NNNNNNNNNNNNNNNNNNNNNNNNNN"; //这个是证书号 这个必须使用新版证书
$url_parts = parse_url($url);
$canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
$message = $http_method . "\n" .
$canonical_url . "\n" .
$timestamp . "\n" .
$nonce . "\n" .
$body . "\n";
openssl_sign($message, $raw_sign, PayConfig::PrivateKey, 'sha256WithRSAEncryption');
$sign = base64_encode($raw_sign);
$schema = 'WECHATPAY2-SHA256-RSA2048 ';
$token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
$merchant_id, $nonce, $timestamp, $serial_no, $sign);
$arr_header[] = "Authorization:" . $schema . $token;
return $arr_header;
}
//作用:产生随机字符串,不长于 32 位
public function createNoncestr($length = 32) {
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
$result_ = strtoupper($str);
return $result_;
}
▷ 第三步
接口请求用例
以 “创建支付分订单” 为例,代码参考如下:
- 基本的接口调用用例如下:
$url = 'https://api.mch.weixin.qq.com/v3/payscore/serviceorder';
$data = array(
'out_order_no'=>$orderSn,
'appid' => PayConfig::AppId,//公众号
'service_id' =>$wxPayConf['service_id'],//服务id
'service_introduction'=>'智慧零售',
'risk_fund'=>array(
'name'=>'ESTIMATE_ORDER_COST',
'amount'=>20000,
),
'location'=>array(
'start_location'=>'江苏省苏州市创意产业园15-303',
),
'time_range'=>array(
'start_time'=>'OnAccept',
),
'need_user_confirm'=>false,
'notify_url'=>'http://xxxxxxxxxxxxx/order/wx_pay_notify', //回调地址
);
$arr_header = $this->getToken($url,'POST',json_encode($data,JSON_UNESCAPED_UNICODE));
$res = $this->posturl($url, json_encode($data,JSON_UNESCAPED_UNICODE), $arr_header);
$res_arr = json_decode($res, true);
【提示】:
可根据返回参数 "state",对支付分订单作符合业务的处理
- 此处提供一个
CURL POST
请求处理方法
public function posturl($url, $data = null, $arr_header = []){
$curl = curl_init();
// curl 设置
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
// 判断 $data get or post
if ( !empty($data) ) {
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
if (!empty($arr_header)) {
curl_setopt($curl, CURLOPT_HTTPHEADER, $arr_header);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
// 执行
$res = curl_exec($curl);
curl_close($curl);
return $res;
}
▷ 第四步
支付成功回调通知 API
微信支付分通过支付成功通知接口将用户支付成功消息通知给商户
-
【>>> 支付成功回调通知文档】
描述如下:
-
【提示】
一般在此回调接口位置,
根据返回的订单号out_order_no
,以及状态state="DONE"
对商家应用的订单,处理最后的更新操作逻辑
同时,注意保存 微信服务端返回的支付信息,比如字段:transaction_id
,方便后期的退款操作
▶ 附录
- 简单场景中,常用的功能就是:
创建支付分订单
取消支付分订单
完结支付分订单
支付成功回调通知
申请退款、退款结果通知