满满的都是坑,因为服务器偷懒让客服端写统一下单,服务器只给了通知的url。微信的支付demo并没有统一下单的代码。
读此文前先阅读: https://pay.weixin.qq.com/wiki/doc/api/app/app.PHP?chapter=9_1
一步步的来 先根据统一下单的参数介绍工具:
1. 获取到当前的ip:
public String getLocalIpAddress() {
try {
for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
NetworkInterface intf = en.nextElement();
for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
return inetAddress.getHostAddress().toString();
}
}
}
} catch (SocketException ex) {
}
return null;
}
private String getWifiIp() {
//获取wifi服务
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
//判断wifi是否开启
if (!wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(true);
}
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
String ip = intToIp(ipAddress);
return ip;
}
private String intToIp(int i) {
return (i & 0xFF) + "." +
((i >> 8) & 0xFF) + "." +
((i >> 16) & 0xFF) + "." +
(i >> 24 & 0xFF);
}
2.随机订单号生成 test 你们可根据自己生成随机数:
private String genOutTradNo() {
Random random = new Random();
return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
}
3.签名工具:
private String genAppSign(Listparams) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < params.size(); i++) { sb.append(params.get(i).getName()); sb.append('='); sb.append(params.get(i).getValue()); sb.append('&'); } sb.append("key="); sb.append(Constants.API_KEY); this.sb.append("sign strn"+sb.toString()+"nn"); String appSign = MD5.getMessageDigest(sb.toString().getBytes()); Log.e("orion",appSign); return appSign; }
差不多了 现在我们需要生成传递的参数 参数要求是xml 格式的:
private String genProductArgs() {
StringBuffer xml = new StringBuffer();
String ip = getWifiIp();
if (ip == "" && ip == "") {
ip = getLocalIpAddress();
}
try {
String nonceStr = genNonceStr();
xml.append("");
List packageParams = new linkedList();
packageParams.add(new BasicNamevaluePair("appid", Constants.APP_ID));
packageParams.add(new BasicNamevaluePair("body", "APP pay test"));
packageParams.add(new BasicNamevaluePair("mch_id", Constants.MCH_ID));
packageParams.add(new BasicNamevaluePair("nonce_str", nonceStr));
packageParams.add(new BasicNamevaluePair("notify_url",ConfigUtil.NOTIFY_URL));
packageParams.add(new BasicNamevaluePair("out_trade_no",genOutTradNo()));
packageParams.add(new BasicNamevaluePair("spbill_create_ip",ip));
packageParams.add(new BasicNamevaluePair("total_fee", "1"));
packageParams.add(new BasicNamevaluePair("trade_type", "APP"));
String sign = genPackageSign(packageParams);
packageParams.add(new BasicNamevaluePair("sign", sign));
String xmlstring =toXml(packageParams);
return xmlstring;
} catch (Exception e) {
Log.e("TAG", "fail, ex = " + e.getMessage());
return null;
}
}
其中 toxml:
private String toXml(Listparams) { StringBuilder sb = new StringBuilder(); sb.append(" "); 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(" "); Log.e("orion",sb.toString()); return sb.toString(); }
得到传递的参数,根据文档指示,我们需要用post去吊连接URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder:
private class GetPrepayIdTask extends AsyncTask> { private ProgressDialog dialog; @Override protected void onPreExecute() { dialog = ProgressDialog.show(PayActivity.this, getString(R.string.app_tip), getString(R.string.getting_prepayid)); } @Override protected void onPostExecute(Map result) { if (dialog != null) { dialog.dismiss(); } sb.append("prepay_idn"+result.get("prepay_id")+"nn"); resultunifiedorder=result; } @Override protected void onCancelled() { super.onCancelled(); } @Override protected Map doInBackground(Void... params) { String url = String.format("https://api.mch.weixin.qq.com/pay/unifiedorder"); String entity = genProductArgs(); Log.e("orion",entity); byte[] buf = Util.httpPost(url, entity); String content = new String(buf); Log.e("orion", content); Map xml=decodeXml(content); return xml; } }
其中decodexml就是:
public MapdecodeXml(String content) { try { Map xml = new HashMap (); XmlPullParser parser = Xml.newPullParser(); parser.setInput(new StringReader(content)); int event = parser.getEventType(); while (event != XmlPullParser.END_document) { String nodeName=parser.getName(); switch (event) { case XmlPullParser.START_document: break; case XmlPullParser.START_TAG: if("xml".equals(nodeName)==false){ //实例化student对象 xml.put(nodeName,parser.nextText()); } break; case XmlPullParser.END_TAG: break; } event = parser.next(); } return xml; } catch (Exception e) { Log.e("orion",e.toString()); } return null; }
下单完成,第二部就是给微信支付传递调起微信支付的参数(具体参数看文档说明):
private void genPayReq() {
req.appId = Constants.APP_ID;
req.partnerId = Constants.MCH_ID;
req.prepayId = resultunifiedorder.get("prepay_id");
req.packagevalue = "prepay_id="+resultunifiedorder.get("prepay_id");
req.nonceStr = genNonceStr();
req.timeStamp = String.valueOf(genTimeStamp());
List signParams = new linkedList();
signParams.add(new BasicNamevaluePair("appid", req.appId));
signParams.add(new BasicNamevaluePair("noncestr", req.nonceStr));
signParams.add(new BasicNamevaluePair("package", req.packagevalue));
signParams.add(new BasicNamevaluePair("partnerid", req.partnerId));
signParams.add(new BasicNamevaluePair("prepayid", req.prepayId));
signParams.add(new BasicNamevaluePair("timestamp", req.timeStamp));
req.sign = genAppSign(signParams);
sb.append("signn"+req.sign+"nn");
Log.e("orion", signParams.toString());
}
第三部,调微信支付:
private void sendPayReq() {
msgApi.registerApp(Constants.APP_ID);
msgApi.sendReq(req);
}
其中:
Constants.APP_ID
是appid 在开发者平台获取
req.partnerId = Constants.MCH_ID;
商户id
ConfigUtil.NOTIFY_URL
支付后的回调通知地址。
签名两次,然后用的api——key是商户平台api安全里面自定义的。
对了 还有个获取时间工具
private long genTimeStamp() {
return System.currentTimeMillis() / 1000;
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。



