PHP实现微信支付全流程:统一下单、签名与回调处理
针对使用PHP语言对接微信支付的需求,本指南梳理了从参数组装、签名生成、统一下单到前端支付调用及后端回调验证的全流程。重点解决了签名算法中参数排序与KEY拼接的关键难点,并提供了JSAPI支付所需的JSON数据结构构造方法。
1. 准备工作与核心参数获取
在发起任何请求之前,首先需要确保已获得微信支付商户平台分配的 appid(应用ID)、mch_id(商户号)以及私钥 key。对于订单信息,必须准确获取三个核心字段:body(商品描述或名称)、out_trade_no(商户订单号)和 total_fee(金额,单位为分)。此外,还需确定交易场景对应的 trade_type,若为微信公众号内部支付则类型为 JSAPI,此时必填 openid;若为扫码支付则为 NATIVE。
2. 生成支付签名 (Sign)
签名是微信支付安全机制的核心,遵循以下步骤生成 sign:
- A:参数排序 将所有参与签名的参数(除
sign自身外)放入数组,按照键名ASCII码从小到大(字典序)排序。 - B:拼接字符串 将排序后的数组转换为
k1=v1&k2=v2&...kN=vN格式的字符串。 - C:附加密钥 在字符串末尾加上 API 密钥,即
&key=你的密钥值。 - D:MD5 加密 对拼接后的完整字符串进行 MD5 运算。
- E:转大写 将得到的 MD5 串全部转换为大写字母,最终得到
sign。
3. 统一下单与请求微信服务器
将包括 sign 在内的所有参数组合成 XML 格式,通过 HTTP POST 方式发送至微信支付下单接口:https://api.mch.weixin.qq.com/pay/unifiedorder。
<![CDATA[]]> <![CDATA[SUCCESS]]> <![CDATA[SUCCESS]]> <![CDATA[wx201411101639507cbf6ffd8b0779950874]]> <![CDATA[JSAPI]]>
若下单成功且 trade_type 为 NATIVE,响应中将额外包含 code_url 二维码链接,用于展示给用户扫描。若为 JSAPI 支付,则需提取响应中的 prepay_id 用于后续前端调起支付。
4. JSAPI 内部支付 JSON 构造
为了实现用户在微信内直接点击唤起支付面板,需要构造一个符合 WeixinJSBridge 规范的 JSON 对象。步骤如下:
- A:构建基础数组 包括
appId、timeStamp(时间戳,秒级)、nonceStr(随机串)、package(固定格式prepay_id=xxx)、signType(如 MD5),注意此处字段名为驼峰命名。 - B:重新签名 对上述新数组再次执行字典序排序和签名算法,生成
paySign。 - C:合并数据 将
paySign加入数组后,使用json_encode输出 JSON 字符串$js_string。
前端通过以下 JavaScript 代码调用支付:
<![CDATA[function jsApiCall() {
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
$js_string,
function(res) {
if(res.err_msg == 'get_brand_wcpay_request:ok') {
alert('支付成功');
} else {
alert('支付失败');
}
}
);
}
// 监听WeixinJSBridge就绪事件触发支付函数...]]>5. 支付结果回调处理
用户支付成功后,微信服务器会向配置好的 notify_url 发送 POST 请求验证结果。服务端需执行反向验证以确保数据安全:
- 接收 POST 报文并将其转为关联数组。
- 移除原报文中的
sign字段,按同样规则对剩余参数进行签名计算。 - 将计算出的签名与报文中的
sign比对。一致则视为有效通知。 - 反馈响应:验证通过后,立即返回特定的 XML 告知微信已成功接收,避免重复推送:
<![CDATA[]]> <![CDATA[SUCCESS]]> <![CDATA[OK]]>
若验证失败或缺少必要参数,返回 F
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









