Android 实现微信支付那些事
来源:互联网 发布:淘宝店铺收藏 编辑:程序博客网 时间:2024/05/14 07:38
各位博友们好,这是鄙人写的第一篇技术博客(前面一篇都是代码截图,不方便使用,所以重新写了一遍),有写的不好的地方请提出来,仅供参考,不喜勿喷!关于微信支付,接触过的Android朋友们应该都深有感触,无数个坑等你着来填,你准备好了吗?
第一步,当然是去微信开放平台中创建应用,创建成功后可以拿到AppID、AppSecret和商户号PartnerId。开通微信支付能力,登录商户平台设置秘钥(32位)
签名工具下载地址:
https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk
设置成功后可以在开放平台应用详情中查看。这个秘钥就是后面我们要用到的ApiKey。
第二步,集成libammsdk.jar后,前面的把AppID注册到微信就不说了,接下来最重要的是调用官方文档中的接口https://api.mch.weixin.qq.com/pay/unifiedorder拿到PrepayId,这也是微信支付中最大的坑之一:
再者,参数中有一个非常重要的sign签名的生成,具体怎么生成官方说的是比较详细,但是要注意一点是参数的顺序一定要一致,我就在这里浪费了很多时间,代码如下:
List<NameValuePair> packageParams = new LinkedList<>(); packageParams.add(new NameValuePair("appid", appId)); packageParams.add(new NameValuePair("body", body)); packageParams.add(new NameValuePair("mch_id", mchId)); packageParams.add(new NameValuePair("nonce_str", nonceStr)); packageParams.add(new NameValuePair("notify_url", notifyURL)); packageParams.add(new NameValuePair("out_trade_no", orderNumber)); packageParams.add(new NameValuePair("spbill_create_ip", ip)); packageParams.add(new NameValuePair("total_fee", payAmt)); packageParams.add(new NameValuePair("trade_type", tradeType)); String packageValue = createServerSign(packageParams);
最后,要注意文档中有个注解容易忽视,调用上面接口时所传的参数必须是XML格式,如果你传json,那不好意思,报错。具体格式仅供参考:
xml = "<xml>" + "<appid>" + appId + "</appid>" + "<mch_id>" + mchId + "</mch_id>" + "<nonce_str>" + nonceStr + "</nonce_str>" + "<sign>" + packageValue + "</sign>" + "<body><![CDATA[" + body + "]]></body>" + "<out_trade_no>" + orderNumber + "</out_trade_no>" + "<attach>" + "" + "</attach>" + "<total_fee>" + payAmt + "</total_fee>" + "<spbill_create_ip>" + ip + "</spbill_create_ip>" + "<notify_url>" + notifyURL + "</notify_url>" + "<trade_type>" + tradeType + "</trade_type>" + "<openid>" + "" + "</openid>" + "</xml>";
补充一下签名的方法,签名这边需要用到ApiKey:
//签名 private String createServerSign(List<NameValuePair> params) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < params.size(); i++) { String k = params.get(i).getName(); String v = params.get(i).getValue(); if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { sb.append(k + "=" + v + "&"); } } sb.append("key=" + Const.API_KEY); String appSign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase(); return appSign; }
MD5工具类:
public class MD5Util {private static String byteArrayToHexString(byte b[]) {StringBuffer resultSb = new StringBuffer();for (int i = 0; i < b.length; i++)resultSb.append(byteToHexString(b[i]));return resultSb.toString();}private static String byteToHexString(byte b) {int n = b;if (n < 0)n += 256;int d1 = n / 16;int d2 = n % 16;return hexDigits[d1] + hexDigits[d2];}public static String MD5Encode(String origin, String charsetname) {String resultString = null;try {resultString = new String(origin);MessageDigest md = MessageDigest.getInstance("MD5");if (charsetname == null || "".equals(charsetname))resultString = byteArrayToHexString(md.digest(resultString.getBytes()));elseresultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));} catch (Exception exception) {}return resultString;}private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5","6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };}
第三步,上一步返回的数据也是xml格式,解析时会用到jdom.jar这个包,具体代码就不列了,拿到PrepayId后就可以调用微信支付,这里还需要二次签名,签名的方法同上,下面是调用微信支付的代码:
String timestamp = String.valueOf(genTimeStamp()); String appId = Const.APP_ID; String mchId = Const.PARTNER_ID; String packageValue = "Sign=WXPay"; String sign = ""; List<NameValuePair> signParams = new LinkedList<>(); signParams.add(new NameValuePair("appid", appId)); signParams.add(new NameValuePair("noncestr", nonceStr)); signParams.add(new NameValuePair("package", packageValue)); signParams.add(new NameValuePair("partnerid", mchId)); signParams.add(new NameValuePair("prepayid", prepayId)); signParams.add(new NameValuePair("timestamp", timestamp)); sign = createServerSign(signParams); if (!api.isWXAppInstalled()) { showToast(getString(R.string.pay_wx)); return; } if (!api.isWXAppSupportAPI()) { showToast(getString(R.string.check_pay)); return; } PayReq req = new PayReq(); req.appId = appId; req.partnerId = mchId; req.prepayId = prepayId; req.nonceStr = nonceStr; req.timeStamp = timestamp; req.packageValue = packageValue; req.sign = sign; req.extData = "app data"; api.sendReq(req);
最后,回调支付结果通知WXPayEntryActivity这个类,必须是在包名.wxapi.WXPayEntryActivity之下,清单中别忘记注册了,具体如下:
<activity android:name=".wxapi.WXPayEntryActivity" android:exported="true" android:launchMode="singleTop" android:noHistory="true"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="wx3e8d4bdfabaf9856" /> </intent-filter> </activity>
谢谢大家观看!希望能有所帮助
- Android 实现微信支付那些事
- Android 实现微信支付那些事
- 微信支付那些事
- Android 支付宝,微信支付实现
- android实现微信支付
- iOS 微信支付的那些事
- 关于微信支付的那些事
- 微信公众号支付那些事
- iOS开发支付那些事(一)微信支付
- 细数Android微信支付的那些坑
- 关于Android微信支付的那些坑
- Android植入微信支付的那些坑
- Hbuilder 开发IOS 和 Android申请微信支付?那些懵逼的事?
- android微信支付的实现
- Android第三方实现微信支付
- Android实现微信支付功能
- Android快速实现微信支付
- Android 从零开始实现微信支付
- 鼠标右键事件
- 44-中断系统调用与自动重启动
- tcp中RACK算法
- 特征缩放(Feature Scaling)
- 【Android】条形码/二维码扫描——ZXing源码分析及相关jar包导入
- Android 实现微信支付那些事
- ngin 安装成设置 pathinfo
- 如何清除缓冲区中的字符,防止scanf函数的误读?
- C#程序员整理的Unity 3D笔记(十):Unity3D的位移、旋转的3D数学模型
- 玲珑学院oj Round#7
- easyUI折叠表格层次显示detailview详解及实例(本实例3层嵌套)
- MPEG-2 Transport Stream Multiplexers
- Android中的Bitmap
- 北京天宇联科技有限责任公司-T语言iOS开发指南