最近在开发一个红包的小程序项目,要求就是能够像微信一样发布答题、语音口令红包、文字口令红包,下单后能够生成海报并且用户扫码登录后答对题目或者说对语音口令来做到领取红包直接到账微信的零钱。
因为微信的企业付款到零钱的接口不是谁都可以使用的,但是目前来说商家转账功能是只要开通就会通过的,所以我们来通过目前红包小程序项目为基础来介绍一下商家转账的接口如何使用。
红包项目基本功能流程图
上面就是基本的流程图,我们今天仅仅讲述一下关于最后领取红包的东西,当然我们的系统里面还包含了答题的题库和口令管理但是这不是我们今天讲述的重点。
重点是通过微信支付的商家转账接口,把钱打给对应的用户的微信余额里面!!!
下面我们就开始今天的全部的接口实现的流程。
生成对应的转账订单
首先我们要知道商家转账的基本流程就是 发起转账,用户确认收款,当然里面还有别的功能这里就不一一赘述了
我们直接上代码
1.发起转账(这里用php作为例子)代码可以直接使用的
里面还有很多的参数我这里仅仅就是简单的介绍一下没有全部的一一去实现
1.1 基本的参数
public $mchid = '您的商户ID';
public $appid = '您的微信小程序APPid';
public $serial_no = '您的证书序列号'; // 证书序列号,不知道怎么获取的看上面的图
1.2 开始发起转账
public function transfer($openid, $trade_no, $money, $desc='备注说明')
{
$money = (int)($money * 100);
$post_data = [
"appid" => $this->appid,//appid
"openid" => $openid,//openid
"out_bill_no" => $trade_no,//订单单号
"transfer_scene_id" => '1000',//转账场景
"user_name" => '',//收款用户姓名
"transfer_remark" => $desc,//转账备注
"transfer_amount" => $money,// 转账金额单位为“分”
//注意下面的transfer_scen_report_infos必须是两组哦要不然会报错的
"transfer_scene_report_infos" =>[
[
"info_type" => "活动名称",
"info_content" => "现金营销"
] ,
[
"info_type" => "奖励说明",
"info_content" => "参加有礼现金价值活动"
]
]
];
$url = 'https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills';
//JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE 防止中文被转义
$result = $this->curl_post($url, json_encode($post_data, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE));
$result = json_decode($result, true);
if (isset($result['prepay_id'])) {
return $result['prepay_id'];
}
return $result;
}
1.3 基本的函数
/**post请求
* @param $url
* @param $param
* @return bool|string
*/
private function curl_post($url, $param)
{
$authorization = $this->getV3Sign($url, "POST", $param);
$curl = curl_init();
$headers = [
'Authorization:' . $authorization,
'Wechatpay-Serial:'.$this->serial_no,
'Accept:application/json',
'Content-Type:application/json;charset=utf-8',
'User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
];
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 500);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POSTFIELDS, $param);
curl_setopt($curl, CURLOPT_POST, true);
$res = curl_exec($curl);
curl_close($curl);
return $res;
}
/**
* 微信签名
* @param $url
* @param $http_method
* @param $body
* @return string
*/
private function getV3Sign($url, $http_method, $body)
{
$nonce = strtoupper($this->createNonceStr(32));
$timestamp = time();
$url_parts = parse_url($url);
$canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
$cert_dir ='您的证书路径';
$sslKeyPath = $cert_dir."apiclient_key.pem";
//拼接参数
$message = $http_method . "\n" .
$canonical_url . "\n" .
$timestamp . "\n" .
$nonce . "\n" .
$body . "\n";
$private_key = $this->getPrivateKey($sslKeyPath);
openssl_sign($message, $raw_sign, $private_key, 'sha256WithRSAEncryption');
$sign = base64_encode($raw_sign);
$token = sprintf('WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",timestamp="%s",serial_no="%s",signature="%s"', $this->mchid, $nonce, $timestamp, $this->serial_no, $sign);
return $token;
}
/**
* 生成随机32位字符串
* @param $length
* @return string
*/
public function createNonceStr($length = 16) { //生成随机16个字符的字符串
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
/**
* 获取私钥
* @param $filepath
* @return false|resource
*/
private function getPrivateKey($filepath = '')
{
if (empty($filepath)) {
//私钥位置
$cert_dir = '您的证书路径';
$filepath = $cert_dir."apiclient_key.pem";
}
return openssl_get_privatekey(file_get_contents($filepath));
}
上面提供的是基本的方法函数可以直接定义到您的类文件里面去进行使用
正常的发起付款状态返回码如下
2.返回的状态
{
"out_bill_no" : "plfk2020042013",
"transfer_bill_no" : "1330000071100999991182020050700019480001",
"create_time" : "2015-05-20T13:29:35.120+08:00",
"state" : "ACCEPTED",
"fail_reason" : "PAYEE_ACCOUNT_ABNORMAL",
"package_info" : "affffddafdfafddffda=="
}
主要看state
和package_info
package_info
:这个是在用户确认收款时必须要用的。
state
:常见的状态值如下
ACCEPTED: 转账已受理
PROCESSING: 转账锁定资金中。如果一直停留在该状态,建议检查账户余额是否足够,如余额不足,可充值后再原单重试。
WAIT_USER_CONFIRM: 待收款用户确认,可拉起微信收款确认页面进行收款确认
TRANSFERING: 转账中,可拉起微信收款确认页面再次重试确认收款
SUCCESS: 转账成功
FAIL: 转账失败
CANCELING: 商户撤销请求受理成功,该笔转账正在撤销中
CANCELLED: 转账撤销完成
只要有一定的开发基础就可以基本实现了发起转账了,下面我们来看看用户确认收款的开发,说是开发不如说是基本现成的东西下面是UNIAPP
中的代码片断可以直接使用的
3.用户确认收款
Pay(){
if (wx.canIUse('requestMerchantTransfer')) {
wx.requestMerchantTransfer({
mchId: '', // 商户号
appId: '', // appId
package: _self.orderData.receives.package_info, // 商家转账付款单跳转收款页package信息
success: (res) => {
// res.err_msg将在页面展示成功后返回应用时返回ok,并不代表付款成功
console.log('success:', res);
},
fail: (res) => {
console.log('fail:', res);
},
});
} else {
wx.showModal({
content: '你的微信版本过低,请更新至最新版本。',
showCancel: false,
});
}
},
这样就基本实现了发起付款,用户确认收款,然后钱打到了微信的余额里面了。大家可以自行实验一下
结语
说在最后项目是通过Uniapp
开发的,如有问题可以咨询我。如果需要整体的项目也可以咨询我,我们一起来探讨。