微信支付...
主要分为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"一定得写......