微信支付商户接入(一)
使用微信支付的过程中,踩了不少坑,这里记录下遇到的问题,方便后续的开发者查找和解决问题。
JSAPI支付
微信支付申请成功后,只有JSAPI支付功能默认开通,H5支付、现金红包这些功能还有额外的要求。
官方说明:
根据监管要求,新申请商户号使用现金红包需要满足三个条件:
◆ 入驻时间超过90天;
◆ 截止今日回推30天连续不间断保持有交易;
◆ 保持正常健康交易:
JSAPI支付是指商户通过调用微信支付提供的JSAPI接口,在支付场景中调起微信支付模块完成收款。
应用场景有:
线下场所:调用接口生成二维码,用户扫描二维码后在微信浏览器中打开页面后完成支付
公众号场景:用户在微信公众账号内进入商家公众号,打开某个主页面,完成支付
PC网站场景:在网站中展示二维码,用户扫描二维码后在微信浏览器中打开页面后完成支付
沙盒环境测试
测试用例中的api调用需要使用微信支付沙箱环境的链接,即微信支付API域名后增加sandboxnew
官方提供了微信支付的SDK,下载地址:https://github.com/tedzhdz/wxpay-sdk/
微信商户后台,申请API Key和证书。在沙盒环境测试,可以不需要。
1.申请沙盒密钥
微信参考文档:
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_1&index=1
POST https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey
参数3个
商户号 mch_id
随机字符串 nonce_str
签名 sign
mch_id是微信支付申请下来时系统分配的
nonce_str可以使用SDK自带的方法WXPayUtil.generateNonceStr()生成
sign可以使用SDK自带的方法WXPayUtil.generateSignature
请求的xml,大概这样子:
<xml>
<mch_id><![CDATA[xxxx]]></mch_id>
<nonce_str><![CDATA[xxxx]]></nonce_str>
<sign>xxxx</sign>
</xml>
返回的xml,大概这样子:
<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[ok]]></return_msg>
<sandbox_signkey><![CDATA[xxxx]]></sandbox_signkey>
</xml>
为了测试方便,可以使用PostMan等http工具验证,微信官方提供了一个微信支付接口签名校验工具
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=20_1
可以生成sign和请求xml
2.统一下单
POST https://api.mch.weixin.qq.com/sandboxnew/pay/unifiedorder
参数及返回值参考
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
请求的xml,大概这样子:
<xml>
<nonce_str>xxxx</nonce_str>
<openid>xxxx-9L6Dhl8lGvdeY6U</openid>
<sign>xxxx</sign>
<fee_type>CNY</fee_type>
<mch_id>xxxx</mch_id>
<body>付费课程</body>
<notify_url>http://1.1.1.180/</notify_url>
<out_trade_no>xxxx</out_trade_no>
<appid>xxxx</appid>
<total_fee>101</total_fee>
<product_id>1</product_id>
<trade_type>JSAPI</trade_type>
</xml>
返回的xml,大概这样子:
<xml>
<trade_type><![CDATA[JSAPI]]></trade_type>
<prepay_id><![CDATA[xxxx]]></prepay_id>
<nonce_str><![CDATA[xxxx]]></nonce_str>
<return_code><![CDATA[SUCCESS]]></return_code>
<err_code_des><![CDATA[ok]]></err_code_des>
<sign><![CDATA[xxxx]]></sign>
<mch_id><![CDATA[xxxx]]></mch_id>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[xxxx]]></appid>
<device_info><![CDATA[sandbox]]></device_info>
<result_code><![CDATA[SUCCESS]]></result_code>
<err_code><![CDATA[SUCCESS]]></err_code>
</xml>
3.查询订单
POST https://api.mch.weixin.qq.com/pay/orderquery
请求的xml,大概这样子:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xml>
<transaction_id>xxxx</transaction_id>
<nonce_str>xxxx</nonce_str>
<openid>xxxx</openid>
<sign>xxxx</sign>
<fee_type>CNY</fee_type>
<mch_id>xxxx</mch_id>
<out_trade_no>20210801xx</out_trade_no>
<appid>wx19a9465f07d76613</appid>
<sign_type>MD5</sign_type>
</xml>
返回的xml,大概这样子:
<xml>
<openid><![CDATA[xxxx-9L6Dhl8lGvdeY6U]]></openid>
<sub_mch_id><![CDATA[]]></sub_mch_id>
<cash_fee_type><![CDATA[CNY]]></cash_fee_type>
<settlement_total_fee><![CDATA[1]]></settlement_total_fee>
<nonce_str><![CDATA[xxxx]]></nonce_str>
<return_code><![CDATA[SUCCESS]]></return_code>
<err_code_des><![CDATA[SUCCESS]]></err_code_des>
<time_end><![CDATA[20210809135032]]></time_end>
<mch_id><![CDATA[xxxx]]></mch_id>
<trade_type><![CDATA[JSAPI]]></trade_type>
<trade_state_desc><![CDATA[ok]]></trade_state_desc>
<trade_state><![CDATA[SUCCESS]]></trade_state>
<sign><![CDATA[xxxx]]></sign>
<cash_fee><![CDATA[1]]></cash_fee>
<is_subscribe><![CDATA[Y]]></is_subscribe>
<return_msg><![CDATA[OK]]></return_msg>
<fee_type><![CDATA[CNY]]></fee_type>
<bank_type><![CDATA[CMC]]></bank_type>
<attach><![CDATA[sandbox_attach]]></attach>
<device_info><![CDATA[sandbox]]></device_info>
<out_trade_no><![CDATA[20210801xx]]></out_trade_no>
<transaction_id><![CDATA[xxxx]]></transaction_id>
<total_fee><![CDATA[101]]></total_fee>
<appid><![CDATA[xxxx]]></appid>
<result_code><![CDATA[SUCCESS]]></result_code>
<err_code><![CDATA[SUCCESS]]></err_code>
</xml>
常见错误说明:
https://mp.weixin.qq.com/s/JEQnD_NmqNvYnCi5hCKW9g
个人遇见的几个错误及解决办法:
1.获取沙箱密钥失败,确认交易密钥是否正确
错误原因:
沙盒测试环境中,使用了生产环境的key。
解决方案:
先通过https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey申请沙盒环境的key
2.沙箱支付金额(100)无效,请检查需要验收的case
错误原因:
沙箱不支持自定义金额支付,请按验收case中给定的金额来调用对应接口验收
解决方案:
total_fee金额字段传入101