微信支付的接口又改啦
微信天天改接口,完全不顾开发人员的死活。
转账到零钱改成类似于微信支付那样,现在的流程是:
1.后台下单锁定转账资金返回收款人确认收款的参数——小程序/公众号端
2.前端拿下单时候返回的参数发起收款确认。
最垃圾的是这个确认需要在应用内完成,而不是微信给收款人直接推送消息。
下面是Thinkhphp实现下单的代码
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
/**
* 发起微信转账
*
* @param array $config 微信支付配置
* @param array $transferData 转账数据
* @return array
* @throws Exception
*/
function wechatTransfer($config, $transferData)
{
$url = 'https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills';
// 构造请求数据
$data = [
//appid
'appid' => $config['miniapp_id'],
//单号
'out_bill_no' => $transferData['out_bill_no'],
//转账场景ID
'transfer_scene_id' => '1000',
//用户openid
'openid' => $transferData['openid'],
//转账金额
'transfer_amount' => $transferData['transfer_amount'],
//转账备注
'transfer_remark' => $transferData['transfer_remark'],
//转账场景报备信息参数 https://pay.weixin.qq.com/doc/v3/merchant/4013774588
'transfer_scene_report_infos'=>$transferData['transfer_scene_report_infos']
];
// 生成签名
$timestamp = time();
$nonceStr = uniqid();
$body = json_encode($data, JSON_UNESCAPED_UNICODE);
$signature = $this->generateSignature($config, $timestamp, $nonceStr, 'POST', $url, $body);
// 构造请求头
$headers = [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Authorization' => sprintf(
'WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",signature="%s",timestamp="%d",serial_no="%s"',
$config['mch_id'],
$nonceStr,
$signature,
$timestamp,
$config['serial_no'] // 商户证书序列号 // 商户证书序列号
),
];
// 发送请求
$client = new Client();
try {
$response = $client->post($url, [
'headers' => $headers,
'body' => $body,
]);
$result = json_decode($response->getBody()->getContents(), true);
return $result;
} catch (GuzzleException $e) {
throw new Exception('微信转账请求失败: ' . $e->getMessage());
}
}
/**
* 生成签名
*
* @param array $config 微信支付配置
* @param int $timestamp 时间戳
* @param string $nonceStr 随机字符串
* @param string $method 请求方法
* @param string $url 请求URL
* @param string $body 请求体
* @return string
* @throws Exception
*/
function generateSignature($config, $timestamp, $nonceStr, $method, $url, $body)
{
$message = sprintf("%s\n%s\n%d\n%s\n%s\n",
$method,
parse_url($url, PHP_URL_PATH),
$timestamp,
$nonceStr,
$body
);
$privateKey = openssl_pkey_get_private(file_get_contents($config['private_key_path']));
if (!$privateKey) {
throw new Exception('加载私钥失败');
}
openssl_sign($message, $signature, $privateKey, 'sha256WithRSAEncryption');
return base64_encode($signature);
}
下单成功后返回的是如下参数:
array(5) {
["create_time"] => string(25) "2025-03-03T17:18:46+08:00"
["out_bill_no"] => string(23) "w2025********0097"
["package_info"] => string(156) "ABBQO+oYAAAB***********b9VnLYQFVRb+K6zE7vlZ*****rXEVxLnkF50="
["state"] => string(17) "WAIT_USER_CONFIRM"
["transfer_bill_no"] => string(34) "133*******543"
}
拿上面的参数给到应用前端用户手动确认收款。
参考文档