微信支付...
主要分为3个阶段:
1.整合9个参数,通过签名规则生成签名.总共10个参数,以POST请求,参数为XML格式的方式,请求接口:https://api.mch.weixin.qq.com/pay/unifiedorder 获取prepay_id.
2.通过返回过来,格式为XML,拿取prepay_id和5个参数进行二次生成签名,最后将包含签名,总共6个参数调用微信支付.
3.唤起微信支付成功/失败..拿到错误码-1/-2/-3/-4
具体过程:
首先是 第一次加签的过程:
字段名 | 变量名 | 类型 | 描述 |
---|---|---|---|
应用ID | appid | String(32) | 微信开放平台审核通过的应用APPID |
商户号 | mch_id | String(32) | 微信支付分配的商户号 |
随机字符串 | nonce_str | String(32) | 随机字符串,不长于32位。推荐随机数生成算法 |
签名 | sign | String(32) | 签名,详见签名生成算法 |
商品描述 | body | String(128) | 商品描述交易字段格式根据不同的应用场景按照以下格式: APP——需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。 |
商户订单号 | out_trade_no | String(32) | 商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号 |
总金额 | total_fee | Int | 订单总金额,单位为分,详见支付金额 |
终端IP | spbill_create_ip | String(16) | 用户端实际ip |
通知地址 | notify_url | String(256) | 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。 |
交易类型 | trade_type | String(16) | 支付类型 |
这10个参数都得需要...
其中签名是 根据其他9个参数按照签名规则生成的....
签名规则是:
第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下:
stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
第二步:拼接API密钥:
stringSignTemp="stringA&key=192006250b4c09247ec02edce69f6a2d"
sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A9CF3B7"
要注意的是,拼接StringA字符串的时候,顺序得按照ASCII顺序来,建议放在treeMap里面...
然后生成的Sign,还得是大写...
生成签名以后,还需要将10个参数以XML格式的形式拼接起来,作为接口请求prepay_id的参数
生成XML:
public static String toXml(List<namevaluepair> params) {
StringBuilder sb = new StringBuilder();
sb.append("<xml>");
for (int i = 0; i < params.size(); i++) {
sb.append("<" + params.get(i).getName() + ">");
sb.append(params.get(i).getValue());
sb.append("</" + params.get(i).getName() + ">");
}
sb.append("</xml>");
return sb.toString();
}
随机字符串:
public static String genNonceStr() {
try {
Random random = new Random();
String rStr = MD5Util.getMessageDigest(String.valueOf(
random.nextInt(10000)).getBytes("utf-8"));
return rStr;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
10个参数转换成XML以后,类似:
<xml>
<appid>wx2421b1c4370ec43b</appid>
<attach>支付测试</attach>
<body>APP支付测试</body>
<mch_id>10000100</mch_id>
<nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
<notify_url>http://wxpay.weixin.qq.com/pub_v2/pay/notify.v2.php</notify_url>
<out_trade_no>1415659990</out_trade_no>
<spbill_create_ip>14.23.150.211</spbill_create_ip>
<total_fee>1</total_fee>
<trade_type>APP</trade_type>
<sign>0CB01533B8C1EF103065174F50BCA001</sign>
</xml>
就可以进行网络请求了,POST请求,请求成功,返回的结果同样是XML格式...
返回的结果,类似...
<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[wx2421b1c4370ec43b]]></appid>
<mch_id><![CDATA[10000100]]></mch_id>
<nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
<sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
<result_code><![CDATA[SUCCESS]]></result_code>
<prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
<trade_type><![CDATA[APP]]></trade_type>
</xml>
请求成功,获得客户端返回的prepay_id.
然后是 二次加签的过程:
先生成一个时间戳,单位是秒,可以通过
System.currentTimeMillis() / 1000 + ""
获得时间戳,数据格式是String.
再拿取返回过来的
appid(商户ID),partnerId(商户号),nonce_str(随机字符串),prepay_id(预支付会话ID),以及timestamp(时间戳),packageValue(默认值) 进行二次签名...签名规则和第一次签名一样,必须得按照ASCII顺序进行排序...
生成二次加签的签名Sign后,就可以进行唤起微信,
唤起微信支付阶段...
PayReq request = new PayReq();
request.appId = Constants.WX_APPID;
request.partnerId = data.partnerid;
request.prepayId = data.prepayid;
request.packageValue = "Sign=WXPay";
request.nonceStr = data.noncestr;
request.timeStamp = data.timestamp+"";
request.sign = data.sign;
api.sendReq(request);
唤起微信支付后,微信支付完成/微信支付失败...结果都将在WXPayEntryActivity内的onResp()方法内自行处理...
@Override
public void onResp(BaseResp resp) {
// 支付结果回调...
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
if(resp.errCode == 0){
//支付成功
}else if(resp.errCode == -1){
Toast.makeText(this,"返回-1",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this,"返回-2",Toast.LENGTH_SHORT).show();
}
}else{
WXPayEntryActivity.this.finish();
}
}
TIPS:
1.需要jar包...libammsdk.jar
2.需要在清单文件里面在对应的Activity配置
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="xxxxxxxxxxxxxxxxxxx"/>
</intent-filter>
在XXXXXX位置填写自己APP对应的APP_ID(APP_ID)
3.需要原封不动的在项目内建立子package,名称是wxapi.需要将官方DEMO里面的WXPayEntryActivity拷贝进去...(微信支付api调用后,支付成功后回将回调结果返回至WXPayEntryActivity.onResp()方法内)
4.需要在清单文件内声明WXPayEntryActivity,并配置...
<activity android:name=".wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop"/>
5.二次加签和调起微信支付的一个参数 packageValue = "Sign=WXPay"一定得写......