前置条件注册
看文档获取证书公私钥APIv3概述_通用规则|微信支付商户文档中心
大约是:执照-法人信息-公账信息-发票信息-仅销售预包装食品备案按需申请
1,查看基本文档产品介绍-权限申请-开发指引-V API列表-∨ 发起转账
2 首次获取平台证书-平台证书需要微信提供的java工具获取或者PHP工具
java -jar CertificateDownloader.jar -k WXXXXXXXXXX8 -m 1699999997 -f apiclient_key.pem -s 696XXXXXXXXXXXXXXXXXBE -o certificate.pem
其余代码SDK库:
GitHub - wechatpay-apiv3/wechatpay-php: 微信支付 APIv3 的官方 PHP Library,同时也支持 APIv2
3,有可能需要安装guzzlehttp,代替原生curl_init:(如未安装自行安装一下)
composer require guzzlehttp/guzzle
PHP服务端最终代码thinkphp6(直接再默认页快速开发)
(多余注释可以自行打开试一试其余接口有,
1,查询的微信单号,
2,发送请求查询「微信支付平台证书」
3,签名
)
<?php
namespace app\controller;
require_once('./../vendor/autoload.php');
use WeChatPay\Builder;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Transformer;
use WeChatPay\Formatter;
use app\BaseController;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
class Index extends BaseController
{
public function index()
{
// 设置参数
// 商户号
$merchantId = '1XXXXXXXXXX7';
// 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名
$merchantPrivateKeyFilePath = 'file://./apiclient_key.pem';
$merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
// 「商户API证书」的「证书序列号」
$merchantCertificateSerial = '69XXXXXXXXXXXXXXXXXXXXBE';
// 从本地文件中加载「微信支付平台证书」,可由内置CLI工具下载到,用来验证微信支付应答的签名
$platformCertificateFilePath = 'file://./wechatpay_2XXXXXXXXXXXXXXXXXXXXX7A.pem';
$onePlatformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
// 「微信支付平台证书」的「平台证书序列号」
// 可以从「微信支付平台证书」文件解析,也可以在 商户平台 -> 账户中心 -> API安全 查询到
$platformCertificateSerial = '22BXXXXXXXXXXXXXX7A';
// 从本地文件中加载「微信支付公钥」,用来验证微信支付应答的签名
$platformPublicKeyFilePath = 'file://./apiclient_cert.pem';
$twoPlatformPublicKeyInstance = Rsa::from($platformPublicKeyFilePath, Rsa::KEY_TYPE_PUBLIC);
// 「微信支付公钥」的「微信支付公钥ID」
// 需要在 商户平台 -> 账户中心 -> API安全 查询
$platformPublicKeyId = 'PUB_KEY_6XXXXXXXXXXXXXXXXXXXXXBE';
// 构造一个 APIv3 客户端实例
$instance = Builder::factory([
'mchid' => $merchantId,
'serial' => $merchantCertificateSerial,
'privateKey' => $merchantPrivateKeyInstance,
'certs' => [
$platformCertificateSerial => $onePlatformPublicKeyInstance,
$platformPublicKeyId => $twoPlatformPublicKeyInstance,
],
]);
// 请求参数
$requestData = [
'appid' => 'wXXXXXXXXXXX07',
'out_bill_no' => 'plfk2020250307',
'transfer_scene_id' => '1005',
'openid' => 'oXXXXXXXXXXXXXXX0',
'user_name' => '',
'transfer_amount' => 100,
'transfer_remark' => '佣金报酬',
//'notify_url' => 'https://www.weixin.qq.com/wxpay/pay.php',
//'user_recv_perception' => '佣金报酬',
'transfer_scene_report_infos' => [
[
'info_type' => '岗位类型',
'info_content' => '销售员'
],
[
'info_type' => '报酬说明',
'info_content' => '2月佣金'
]
]
];
try {
// 发起 POST 转款请求
$response = $instance->chain('v3/fund-app/mch-transfer/transfer-bills')->post([
'json' => $requestData,
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Wechatpay-Serial' => $merchantCertificateSerial,
]
]);
// 获取响应体内容
$responseBody = (string)$response->getBody();
// 处理响应数据
echo "Response: ". $responseBody;
} catch (\Exception $e) {
// 处理异常
echo "Error: ". $e->getMessage();
}
// // 要查询的微信单号
// $transferBillNo = '1XXXXXXXXXXXXXXXXXXX2';
// try {
// // 发起 GET 请求
// $response = $instance->chain('v3/fund-app/mch-transfer/transfer-bills/transfer-bill-no')->chain("{$transferBillNo}")->get([
// 'headers' => [
// 'Accept' => 'application/json',
// 'Content-Type' => 'application/json',
// 'Wechatpay-Serial' => $merchantCertificateSerial,
// ]
// ]);
// // 获取响应体内容
// $responseBody = (string)$response->getBody();
// // 处理响应数据
// echo "Response: ". $responseBody;
// } catch (\Exception $e) {
// // 处理异常
// echo "Error: ". $e->getMessage();
// }
//var_dump($instance);
// 发送请求查询「微信支付平台证书」
// try {
// $resp = $instance->chain('v3/certificates')->get(
// /** @see https://docs.guzzlephp.org/en/stable/request-options.html#debug */
// // ['debug' => true] // 调试模式
// );
// echo (string) $resp->getBody(), PHP_EOL;
// $certificates = (string) $resp->getBody();
// } catch(\Exception $e) {
// // 进行异常捕获并进行错误判断处理
// echo $e->getMessage(), PHP_EOL;
// if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
// $r = $e->getResponse();
// echo $r->getStatusCode() . ' ' . $r->getReasonPhrase(), PHP_EOL;
// echo (string) $r->getBody(), PHP_EOL, PHP_EOL, PHP_EOL;
// }
// echo $e->getTraceAsString(), PHP_EOL;
// }
//var_dump($certificates);
//exit;
//签名
// $merchantPrivateKeyFilePath = 'file://./apiclient_key.pem';
// $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath);
// $params = [
// 'appId' => 'wXXXXXXXXXX7',
// 'timeStamp' => (string)Formatter::timestamp(),
// 'nonceStr' => Formatter::nonce(),
// 'package' => 'prepay_id=wxXXXXXXXXXXXXXXXXXXXXX00',
// ];
// $params += ['paySign' => Rsa::sign(
// Formatter::joinedByLineFeed(...array_values($params)),
// $merchantPrivateKeyInstance
// ), 'signType' => 'RSA'];
// echo json_encode($params);
}
}
返回结果,发起转款的
Response: {"create_time":"2025-03-08T13:58:11+08:00","out_bill_no":"plfk2020250307","package_info":"XXXXXXXXXXXXXXg+Vk=","state":"WAIT_USER_CONFIRM","transfer_bill_no":"1XXXXXXXXXXXXXXXXXXX2"}
返回结果,查询结果的
Response: {"appid":"wXXXXXXXXXXXXX7","create_time":"2025-03-08T13:58:11+08:00","mch_id":"1XXXXXXXXXXXX7","openid":"oIXXXXXXXXXXXXXzvE0","out_bill_no":"plfk2020250307","state":"SUCCESS","transfer_amount":100,"transfer_bill_no":"1XXXXXXXXXXXXXXXXXXX2","transfer_remark":"佣金报酬","update_time":"2025-03-08T16:04:36+08:00"}
========前端代码============
JSAPI调起用户确认收款更新时间:2025.03.07
商家转账用户确认模式下,在微信客户端通过小程序或H5拉起页面请求用户确认收款。
1,我的环境为本地开发真机调试。(微信小程序cmreb-uniapp版)
2,随便找一个页面放置按钮触发
3代码简单的调用实例
在页面添加一个按钮(示例放在「快速升级技巧」下方):
<view class="skill-section">
<!-- 原有的任务列表 -->
<view class="section-bd acea-row">
<!-- 原有任务循环 -->
</view>
<!-- 新增收款按钮 -->
<view class="section-bd">
<button class="withdraw-btn" @click="ConfirmPay">
申请提现
</button>
</view>
</view>
在样式部分添加按钮样式:
.withdraw-btn {
width: 100%;
height: 90rpx;
margin: 30rpx 30rpx 0;
background-color: #E7B667;
border-radius: 8rpx;
color: #fff;
font-size: 32rpx;
border: none;
outline: none;
}
前端核心集成 JS-SDK 逻辑,在 Vue 组件的 methods 中添加:
methods: {
// 原有方法...
ConfirmPay(){
if (wx.canIUse('requestMerchantTransfer')) {
wx.requestMerchantTransfer({
mchId: '16XXXXXXX7', // 商户号
appId: 'wXXXXXXXXX7', // appId
package: 'ABBQOXXXXXXXXXX+Vk=......', // 商家转账付款单跳转收款页package信息
success: (res) => {
// res.err_msg将在页面展示成功后返回应用时返回ok,并不代表付款成功
console.log('success:', res);
},
fail: (res) => {
console.log('fail:', res);
},
});
} else {
wx.showModal({
content: '你的微信版本过低,请更新至最新版本。',
showCancel: false,
});
}
},
}
结语:需要用户按确认收款,很不方便。