写在前面
我是先拿一个Demo测试的,然后再接入我们的app的,其中包名和应用签名必须实时更新,根据不同的app,即使相同的包名,应用签名是不同的,这点需要注意。
评论里的一位小伙伴儿遇到问题后总结出的几个注意项在前面特别标注:(2018.7.14更新)
关于微信支付,需要特别注意,一定要仔细阅读微信的接口文档,虽然接口文档不尽人意,但是总体的功能还是满足的。不过有以下几点需要注意:
1.App支付时,在开放平台中,安卓的包名要与在web端打的包名一致,确保安卓可以正常付款。
2.nonce_str字段值,用一下格式:
String currTime = getCurrTime();
String strTime = currTime.substring(8, currTime.length());
String strRandom = buildRandom(4) + "";
String nonce_str = strTime + strRandom;
3.回调地址需要使用外网,可以是域名也可以是ip
4.App支付和H5支付的appid,appsecret,商户id,商户秘钥都以收到的邮件为准。
5.H5支付,需要在商户平台,js中做授权和网页中做授权。
6.公众号支付:需要在商户平台做appid申请,填写的appid为所需要关注的公众号的appid,申请之后,需要前往公众平台进行M-A授权。授权通过后才可以进行开发。接口文档中的appid需要填写公众号的appid。
创建应用
该appId的申请与您应用的创建过程有关,具体流程请参考如下介绍。
访问微信开放平台,访问地址:https://open.weixin.qq.com
获取应用包名:
Android平台的包名获取方式:
将该包名填入"勾选Android应用"一步中的应用包名即可
获取应用签名:
9.7、该应用将用于获取手机上已安装应用的签名。 将该apk安装至您的Android手机中。同时请确认该手机上已经安装了您需要获取签名信息的应用。
该apk安装后如图:
将该绿色字符串一次输入,勾选Android应用的应用签名框中即可。
所以请确保您的手机上一定安装了相应的应用。
一切准备工作做好,创建的app会有AppId和Secret已经应用签名和包名的信息。如图是我们应用的信息。
请务必按照官方微信开放平台接入的文档(前面这些)一步步完成,
准备工作做完了,准备好几项数据: appid、secret(用于获取 access_token)、partnerkey(微信公众平台商户模块生成的商户密钥)。
我们使用wxPay的第二种支付方案,在模块内部处理签名过程。
在接入开始之前我们需要注意的是:检查APP是否使用模块pingpp,ipayNow,因为会产生冲突,这两个模块是不能与wxPay同时添加的模块,所以需要先检查,以防所有的工作都做好了,云编译(测试需要云编译,不能使用自定义loader,因为key.xml文件的原因)的时候不好用!
准备接入:
1.在开发控制台添加wxPay的模块。
2.配置config.xml。
使用此模块之前需先配置 config.xml 文件,方法如下
"wxPay">
<param name="urlScheme" value="wxd0d84bbf23b4a0e4"/>
<param name="apiKey" value="wxd0d84bbf23b4a0e4"/>
<param name="apiSecret" value="a354f72aa1b4c2b8eaad137ac81434cd"/>
字段描述:
urlScheme:(必须配置)用于实现应用间跳转及数据交换,本应用可以启动微信客户端,也可以从微信客户端跳回本应用。urlScheme 的 value 值是从微信开放平台获取的 appid。appid 申请方法参考微信开放平台接入文档。
apiKey:(必须配置)从微信开放平台获取的 appid,值与 urlScheme 相同。appid 申请方法参考微信开放平台接入文档。
apiSecret:从微信开放平台获取的 secret。获取支付 token 需要配置此项。token 申请方法参考微信开放平台接入文档。
key.xml 配置详解:
key.xml
文件(适用于支付方案二、支付方案一忽略本文件)需要放在 widget/res
文件目录下,格式如下:
<security>
<item name="wxPay_appId" value="wxd0d84bbf23b4a0e4"/>
<item name="wxPay_mchId" value="1234567890"/>
<item name="wxPay_partnerKey" value="***"/>
<item name="wxPay_notifyUrl" value="***"/>
<item name="其它服务需加密的参数配置 " value="***"/>
.
.
.
security>
字段描述:
wxPay_appId:在微信开发者平台创建应用生成的 appId
wxPay_mchId:商户号,填写商户对应参数
wxPay_partnerKey:商户API密钥,务必同在商户平台->账户设置->API安全里填写的密钥保持一致,此密钥是根据微信对商户密钥的规范自己生成的
wxPay_notifyUrl:接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数
但万年不变的是,首先我们需要调取我们的模块。然后走config的方法,在config方法回调成功的时候执行pay方法,调起微信客户端,执行微信支付的操作。
其中config方法因为我们在key.xml文件中处理了这些信息,所以我们在config里面不用写apiKey,mchId等这些信息。
在下面的示例代码中写了这几个参数,其实我们不需要在这里写的。
var wxPay = api.require('wxPay');
wxPay.config({
apiKey: '',
mchId: '',
partnerKey: '',
notifyUrl: ''
}, function(ret, err) {
if (ret.status) {
alert('配置商户支付参数成功');
} else {
alert(err.code);
}
});
在err.code中,有以下几种错误码对应的错误信息。我个人建议在alert的时候+上err.msg这样更清晰,毕竟错误码还需要去比对,建议将两者同时输出。
虽然我config上没有err但是在pay方法时候报错-1,我alert了err.msg之后才知道是mchId和AppId不匹配的原因,然后找到产生错误的原因解决,就避免了很多不必要的麻烦。
err:
{
code: 1 //数字类型;错误码
//-1(未知错误)
//1(apiKey 值非法)
//2(mchId 值非法)
//3(partnerKey 值非法)
//4(notifyUrl 值非法)
}
在执行config成功后,我们执行pay方法,同样的我要放上示例代码,独立出方法的代码只是为了让大家更好地理解。
其中要注意的是,在调用的时候,会自动填上下面的description等参数,这个地方有一个坑需要大家注意就是timeExpire,这个到期时间因为是2009年的时间所以会产生time_expire时间过短,刷卡至少1分钟,其他5分钟这样的错误提示。所以我建议大家留下前三个参数即可。
var wxPay = api.require('wxPay');
wxPay.pay({
description: 'iPad mini 16G 白色',
totalFee: '888',
tradeNo: '1217752501201407033233368018',
spbillCreateIP: '196.168.1.1',
deviceInfo: '013467007045764',
detail: 'iPad mini 16G 白色',
attach: '说明',
feeType: 'CNY',
timeStart: '20091225091010',
timeExpire: '20091227091010',
goodsTag: 'WXG',
productId: '12235413214070356458058',
openId: 'oUpF8uMuAJO_M2pxb1Q9zNjWeS6o'
}, function(ret, err) {
if (ret.status) {
alert(ret.result);
} else {
alert(err.code);
}
});
其中这些参数的意义我就粘贴在下方给大家理解。
description:
totalFee:
tradeNo:
spbillCreateIP:
deviceInfo:
detail:
attach:
feeType:
timeStart:
timeExpire:
goodsTag:
productId:
openId:
err:
{
code: 1 //数字类型;
//错误码:
//-2(用户取消)
//-1(可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等)
//1(必传参数缺失)
msg: 'NOAUTH' //字符串类型;
//取值范围:
//NOAUTH (商户无此接口权限)
//NOTENOUGH(余额不足)
//ORDERPAID(商户订单已支付)
//ORDERCLOSED(订单已关闭)
//SYSTEMERROR(系统错误)
//APPID_NOT_EXIST (APPID不存在)
//MCHID_NOT_EXIST(MCHID不存在)
//APPID_MCHID_NOT_MATCH(appid和mch_id不匹配)
//LACK_PARAMS(缺少参数)
//OUT_TRADE_NO_USED(商户订单号重复)
//SIGNERROR (签名错误)
//XML_FORMAT_ERROR(XML格式错误)
//REQUIRE_POST_METHOD(请使用post方法)
//POST_DATA_EMPTY(post数据为空)
//NOT_UTF8(编码格式错误)
}
到此我们的详细解释基本完成,接下来我会粘贴我的具体实现代码,这里需要
注意的是每个订单号tradeNo只能使用一次:
function wxPay() {
var wxPay = api.require('wxPay');
wxPay.config({
}, function(ret, err) {
if (ret.status) {
alert('配置商户支付参数成功');
wxPay.pay({
description: 'iPad mini 16G 白色',
totalFee: '001',
tradeNo: '1217752501201407033233368012',
},function(ret,err){
//coding...
if(ret.status) {
alert("您已支付成功");
} else {
if(err.code == '-2'){
alert("您已取消支付");
} else {
alert('回调失败'+err.code+err.msg);
}
}
});
} else {
console.log(err.code);
}
});
}
点击立即支付,ret支付成功,取消支付则err.code=-2。
到这里,微信支付的接入基本完成。
自己研究的如果有错误烦请读者指出,谢谢!