微信支付是当前国内最流行的支付方式之一,而微信支付统一下单接口则是实现整个支付功能的重要环节之一。本文将详细介绍如何使用PHP编写微信支付统一下单的代码,并给出完整的代码实现过程。
1. 准备工作
在编写代码之前,我们需要先进行一些准备工作。首先,我们需要在微信公众平台上创建一个应用并完成开发者身份认证。然后,我们需要在微信支付平台上申请支付权限,并获取到自己的商户号、支付密钥以及设备号等关键信息。最后,我们需要安装PHP的XML解析器库,以便后续处理微信支付接口返回的XML数据。
2. 发起统一下单请求
使用微信支付统一下单接口,我们可以通过一次HTTP请求完成支付交易的全部过程。在请求参数中,我们需要提供以下信息:
appid:应用id,在公众平台上申请时获取。
mch_id:商户号,在微信支付平台上申请时获取。
nonce_str:随机字符串,用于防止重放攻击的安全机制。
body:商品描述。
out_trade_no:商户订单号,要求32个字符以内,必须在商户系统内唯一。
total_fee:订单总金额,单位为分。
spbill_create_ip:客户端ip地址,必须为实际用户ip。
notify_url:支付结果通知地址,用于接收微信支付平台异步通知。
trade_type:交易类型,固定为JSAPI。
openid:用户openid,用户在微信公众平台上的唯一标识。
sign:签名,用于验证请求的合法性。
在请求参数中,最重要的是签名参数。我们需要按照微信支付平台的规则计算出签名,并将签名值作为参数传递给微信支付统一下单接口。以下是签名计算的具体步骤:
1. 将所有非空参数按照参数名ASCII码从小到大排序(字典序)。
2. 将所有参数名和参数值串在一起,并用&符号连接起来,得到一个待签名字符串。
3. 在待签名字符串末尾加上商户支付密钥的密钥值,并将其MD5加密后转换成小写字母,得到签名值。
在PHP中,我们可以借助一些函数库来实现签名计算。以下是发起统一下单请求的PHP代码示例:
// 设置请求参数
$params = array(
'appid' => 'wx1234567890abcdef', // 应用id
'mch_id' => '1234567890', // 商户号
'nonce_str' => uniqid(), // 随机字符串
'body' => '测试商品', // 商品描述
'out_trade_no' => '202105051234567890', // 商户订单号
'total_fee' => 1, // 订单总金额,单位为分
'spbill_create_ip' => '114.242.26.19', // 客户端ip地址
'notify_url' => 'http://www.example.com/pay_notify.php', // 支付结果通知地址
'trade_type' => 'JSAPI', // 交易类型
'openid' => 'o7LQ20GmLmNjRgpIevL4xJ265wAk', // 用户openid
);
// 计算签名
ksort($params); // 按照参数名排序
$str = urldecode(http_build_query($params)); // 构造待签名字符串
$str .= '&key=' . 'abcdefg1234567890abcdefg12345678'; // 商户支付密钥
$params['sign'] = strtoupper(md5($str)); // 计算签名
// 转换为XML格式
$xml = new SimpleXMLElement(' ');
array_walk($params, array($xml, 'addChild'));
$xml_str = $xml->asXML();
// 发送HTTP请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.mch.weixin.qq.com/pay/unifiedorder');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_str);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);
// 解析XML响应
$xml_resp = simplexml_load_string($result);
3. 处理下单结果
微信支付统一下单接口会返回一个XML格式的响应,我们需要解析响应,并根据返回结果进行相应的处理。以下是处理下单结果的PHP代码示例:
// 验证响应
if ($xml_resp->return_code == 'SUCCESS' && $xml_resp->result_code == 'SUCCESS') {
// 预支付交易会话标识
$prepay_id = (string)$xml_resp->prepay_id;
// 生成JSAPI参数
$params = array(
'appId' => 'wx1234567890abcdef', // 应用id
'timeStamp' => time(), // 时间戳
'nonceStr' => uniqid(), // 随机字符串
'package' => 'prepay_id=' . $prepay_id, // 预支付交易会话标识
'signType' => 'MD5', // 签名算法
);
// 计算签名
ksort($params);
$str = urldecode(http_build_query($params));
$str .= '&key=' . 'abcdefg1234567890abcdefg12345678'; // 商户支付密钥
$params['paySign'] = strtoupper(md5($str));
// 返回JSAPI参数
echo json_encode($params);
} else {
// 下单失败,输出错误信息
echo (string)$xml_resp->return_msg;
}
以上代码会将下单结果转换为JSAPI参数,并输出一个JSON格式的字符串。在前端页面中,我们可以直接使用该参数调起微信支付功能。
4. 总结
本文详细介绍了如何使用PHP编写微信支付统一下单的代码,并给出了完整的代码实现过程。在实际开发中,我们需要根据自己的业务需求和开发经验,进一步完善代码,并考虑各种异常情况的处理方式。当然,除了PHP,我们还可以使用其他编程语言如Java、Python等来实现微信支付统一下单功能。无论使用何种编程语言,我们都需要遵循微信支付平台的规则,并保证代码的可维护性和安全性。