一、开发前提
APP支付又称移动端支付,是商户通过在移动端应用APP中集成开放SDK调起微信支付模块完成支付的模式。
本文档旨在指导开发者快速集成微信APP支付,包括开发者帐号申请、服务器配置以及安卓端配置。
1、开发者资质认证
登录微信开放平台:https://open.weixin.qq.com
如图:在帐号中心里,选择开发者资质认证,根据申请引导进行申请,等待审核通过即可
2、创建应用
如图:在管理中心里,选择移动应用,点击创建移动应用
创建应用时要求填写应用签名和应用包名,应用签名可以通过软件查看:下载地址,包名可以查看AndroidManifest.xml
中声明的package
值
填写各项信息之后,等待审核通过,即可获得如下权限:
3、申请开通微信支付
应用审核通过后若想获取微信支付能力,需要申请开通微信支付功能,根据申请引导申请即可
4、了解支付流程
以下是交互时序图,统一下单API、支付结果通知API和查询订单API等都涉及签名过程,调用都必须在商户服务器端完成。
二、服务器配置
参考文档:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1
1、统一下单
商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再在APP里面调起支付。
接口地址:https://api.mch.weixin.qq.com/pay/unifiedorder
必传参数:
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
---|---|---|---|---|---|
应用ID | appid | 是 | String(32) | wxd678efh567hg6787 | 微信开放平台审核通过的应用APPID |
商户号 | mch_id | 是 | String(32) | 1230000109 | 微信支付分配的商户号 |
随机字符串 | nonce_str | 是 | String(32) | 5K8264ILTKCH16CQ2502SI8ZNMTM67VS | 随机字符串,不长于32位。推荐随机数生成算法 |
签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 签名,详见签名生成算法 |
商品描述 | body | 是 | String(128) | 腾讯充值中心-QQ会员充值 | 商品描述交易字段格式根据不同的应用场景按照以下格式:应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。 |
商户订单号 | out_trade_no | 是 | String(32) | 20150806125346 | 商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号 |
总金额 | total_fee | 是 | Int | 888 | 订单总金额,单位为分,详见支付金额 |
终端IP | spbill_create_ip | 是 | String(16) | 123.12.12.123 | 用户端实际ip |
通知地址 | notify_url | 是 | String(256) | http://www.weixin.qq.com/wxpay/pay.php | 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。 |
交易类型 | trade_type | 是 | String(16) | APP | 支付类型 |
2、在线验证签名
微信提供了在线验证签名,以检测开发者调用微信公众平台开发者API时发送的请求参数是否正确
在线验证地址:https://pay.weixin.qq.com/wiki/tools/signverify/
如图:填写各项参数,点击生成签名,然后将生成的#4.最终的提交xml
的内容提交给统一支付下单接口即可。
3、再次验签
商户系统调用统一下单接口后在微信支付服务后台生成预支付交易订(prepay_id),返回正确的预支付交易回话标识后再将APP端需要的参数进行签名,然后返回给APP,再在APP里面调起支付。
统一下单接口返回结果如下:
<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[wxdf5a5e8166b65d8e]]></appid>
<mch_id><![CDATA[1413719303]]></mch_id>
<nonce_str><![CDATA[cCKl1CPUKbc1Viu1]]></nonce_str>
<sign><![CDATA[A457DA342972CE8EB86C9BFA46BDFC86]]></sign>
<result_code><![CDATA[SUCCESS]]></result_code>
<prepay_id><![CDATA[wx20161123112638700583976e0487596811]]></prepay_id>
<trade_type><![CDATA[APP]]></trade_type>
</xml>
然后,将APP端需要的参数再次签名,然后将参数和签名返回给APP端
如图,签名的参数至少为以下几个:(appid、partnerid、noncestr、package、prepayid、timestamp)
4、注意事项
调用统一下单接口需要验签,收到返回结果之后,还需要将APP调起支付所需要的参数再次验签,然后再返回给APP端,在APP端调起支付即可。
三、Android端配置
参考文档:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5
1、注册APPID
商户APP工程中引入微信JAR包,调用API前,需要先向微信注册您的APPID,代码如下:
IWXAPI msgApi;
msgApi = WXAPIFactory.createWXAPI(this, null);
msgApi.registerApp("wxdf5a5e8166b65d8e");// 将该app注册到微信
经测试:以下组合均能注册成功
msgApi = WXAPIFactory.createWXAPI(this, "wxdf5a5e8166b65d8e", true);
msgApi.registerApp("wxdf5a5e8166b65d8e");
msgApi = WXAPIFactory.createWXAPI(this, "wxdf5a5e8166b65d8e", false);
msgApi.registerApp("wxdf5a5e8166b65d8e");
msgApi = WXAPIFactory.createWXAPI(this, "wxdf5a5e8166b65d8e");
msgApi.registerApp("wxdf5a5e8166b65d8e");
2、调起支付
商户服务器生成支付订单,先调用统一下单接口生成预付单,获取到prepay_id后将参数再次签名传输给APP发起支付。以下是调起微信支付的关键代码:
//msgApi,不用重新声明,使用注册时的就行
PayReq request = new PayReq();
request.appId = "wxdf5a5e8166b65d8e";
request.partnerId = "1413719303";
request.prepayId = "wx2016112309404508902deea40216174377";
request.nonceStr = "pFDVAPrK4R5okMYg";
request.timeStamp = "1456552292";
request.packageValue = "Sign=WXPay";
request.sign = "68F28572072B187B5F27E1542BEE05F6";
msgApi.sendReq(request);
APP端调起支付的参数列表可参考:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12
3、支付结果回调
参照微信SDK Sample,在net.sourceforge.simcpux.wxapi包路径中实现WXPayEntryActivity类(包名或类名不一致会造成无法回调,例如我的包名是com.juemuren.weixinzhifu
,则该类需要放在com.juemuren.weixinzhifu.wxapi
中)
在manifest文件中注册:
<activity android:name=".wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop"/>
在WXPayEntryActivity类中实现onResp函数,支付完成后,微信APP会返回到商户APP并回调onResp函数,开发者需要在该函数中接收通知,判断返回错误码,如果支付成功则去后台查询支付结果再展示用户实际支付结果。
注意一定不能以客户端返回作为用户支付的结果,应以服务器端的接收的支付通知或查询API返回的结果为准。代码示例如下:
@Override
public void onResp(BaseResp resp) {
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
Log.e("resp.errCode=", resp.errCode + "");
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("提示");
builder.setMessage("支付结果" + String.valueOf(resp.errCode));
builder.show();
}
}
回调中errCode值列表:
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
---|---|---|---|---|---|
返回状态码 | return_code | 是 | String(16) | SUCCESS | SUCCESS/FAIL SUCCESS表示商户接收通知成功并校验成功 |
返回信息 | return_msg | 否 | String(128) | OK | 返回信息,如非空,为错误原因:签名失败 参数格式校验错误 |
4、注意事项
实际支付结果一定不能以客户端返回作为用户支付的结果,应以服务器端的接收的支付通知或查询API返回的结果为准。
确认debug或者打包运行的程序签名与微信开发平台设置的签名一致(使用下面任意一种方法):
①、可以设置后台的签名为debug包的签名,这样每次直接运行即可,待程序发布之前再将签名修改为正式包的签名
②、若使用的正式包的签名,则每次都要打包运行,或者可以在build.gradle中的android标签中添加下面的代码(推荐):
signingConfigs {
debug {
storeFile file("正式keystore的路径")
storePassword "密码"
keyAlias "别名"
keyPassword "密码"
}
}
网友评论