Android集成微信支付功能
准备工作这里就不说了,包括签约和申请APPID,附上微信开放平台APP开发步骤,不懂的同学可以参考这里:
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5
上面的步骤很详细,这里主要说下调起支付的注意事项。按照上面文档中说的商户服务器生成支付订单,先调用统一下单API生成预付单,获取到prepay_id后将参数再次签名传输给APP发起支付。
相关代码如下:
/** *商户服务器生成支付订单,先调用统一下单API(详见第7节)生成预付单,获取到prepay_id后将参数再次签名传输给APP发起支付。 */ //商品描述 Stringbody="iphone6s"; //随机字符串 Stringnonce_str=ResourceUtil.createRandomString(32); //通知地址 Stringnotify_url="http://www.weixin.qq.com/wxpay/pay.php"; //商户订单号 Stringout_trade_no=ResourceUtil.generateOutTradeNo(32); //总金额(单位分) inttotal_fee=1; Stringurl="https://api.mch.weixin.qq.com/pay/unifiedorder"; Stringsign=SignUtil.signByMD5("appid="+Constants.APP_ID+"&body="+body+ "&mch_id="+Constants.MCH_ID+"&nonce_str="+nonce_str+"¬ify_url="+notify_url+ "&out_trade_no="+out_trade_no+"&spbill_create_ip=127.0.0.1"+ "&total_fee="+total_fee+"&trade_type=APP"+"&key="+Constants.KEY).toUpperCase(Locale.getDefault()); //参数以xml格式传递 Stringentity="<xml><appid>"+Constants.APP_ID+"</appid><mch_id>"+Constants.MCH_ID+"</mch_id><nonce_str>"+nonce_str+"</nonce_str><sign>"+sign+ "</sign><body>"+body+"</body><out_trade_no>"+out_trade_no+"</out_trade_no><total_fee>"+total_fee+ "</total_fee><spbill_create_ip>127.0.0.1</spbill_create_ip><notify_url>http://www.weixin.qq.com/wxpay/pay.php</notify_url><trade_type>APP</trade_type></xml>"; Log.d("entity",entity); payButton.setEnabled(false); Toast.makeText(PayActivity.this,"获取订单中...",Toast.LENGTH_SHORT).show(); byte[]buf=Util.httpPost(url,entity); if(buf!=null&&buf.length>0){ Stringcontent=newString(buf); Log.d("getserverpayparams:",content); OrderResultorderResult=ResourceUtil.parseXml(newByteArrayInputStream(content.getBytes())); if(!TextUtils.equals(orderResult.getReturnCode(),"SUCCESS")){ Toast.makeText(PayActivity.this,orderResult.getReturnMsg(),Toast.LENGTH_SHORT).show(); return; } if(!TextUtils.equals(orderResult.getResultCode(),"SUCCESS")){ Toast.makeText(PayActivity.this,orderResult.getErrorDesc(),Toast.LENGTH_SHORT).show(); return; } //下单成功,调起支付 PayReqrequest=newPayReq(); request.appId=Constants.APP_ID; request.partnerId=Constants.MCH_ID; request.prepayId=orderResult.getPrepayId(); request.packageValue="Sign=WXPay"; request.nonceStr=nonce_str; StringtimeStamp=String.valueOf(System.currentTimeMillis()/1000); request.timeStamp=timeStamp; request.sign=SignUtil.signByMD5("appid="+Constants.APP_ID+"&noncestr="+nonce_str+"&package=Sign=WXPay"+ "&partnerid="+Constants.MCH_ID+"&prepayid="+orderResult.getPrepayId()+"×tamp="+timeStamp+"&key="+Constants.KEY).toUpperCase(Locale.getDefault()); api.sendReq(request); payButton.setEnabled(true); } } });
相关参数说明在文档上都注明了,我这里面nonce_str和out_trade_no都是我随机生成的字符创,附上我的工具类,方便大家参考。
ResourceUtil.java
packagecom.xylpay.sdk.pay.uikit; importjava.io.IOException; importjava.io.InputStream; importjava.util.Random; importorg.xmlpull.v1.XmlPullParser; importorg.xmlpull.v1.XmlPullParserException; importcom.xylpay.sdk.pay.bean.OrderResult; importandroid.util.Xml; publicclassResourceUtil{ /** *随机生成字符串 *@paramlength字符串的长度 *@return随机字符串 */ publicstaticStringcreateRandomString(intlength){ Stringsource="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; Randomrandom=newRandom(); StringBuilderbuilder=newStringBuilder(); for(inti=0;i<length;i++){ intposition=random.nextInt(source.length()); builder.append(source.charAt(position)); } returnbuilder.toString(); } publicstaticStringgenerateOutTradeNo(intn){ StringBuilderbuilder=newStringBuilder(); Randomrandom=newRandom(); for(inti=0;i<n;i++){ builder.append(random.nextInt(10)); } returnbuilder.toString(); } publicstaticOrderResultparseXml(InputStreamis){ //PULL解析xml数据 XmlPullParserparser=Xml.newPullParser(); OrderResultorderResult=null; try{ parser.setInput(is,"UTF-8"); inttype=parser.getEventType(); while(type!=XmlPullParser.END_DOCUMENT){ switch(type){ caseXmlPullParser.START_DOCUMENT: break; caseXmlPullParser.START_TAG: if(parser.getName().equals("xml")){ orderResult=newOrderResult(); }elseif(parser.getName().equals("return_code")){ orderResult.setReturnCode(parser.nextText()); }elseif(parser.getName().equals("return_msg")){ orderResult.setReturnMsg(parser.nextText()); }elseif(parser.getName().equals("result_code")){ orderResult.setResultCode(parser.nextText()); }elseif(parser.getName().equals("err_code_des")){ orderResult.setErrorDesc(parser.nextText()); }elseif(parser.getName().equals("prepay_id")){ orderResult.setPrepayId(parser.nextText()); } break; caseXmlPullParser.END_TAG: break; } type=parser.next(); } }catch(XmlPullParserExceptione){ e.printStackTrace(); }catch(IOExceptione){ e.printStackTrace(); } returnorderResult; } }
其中关于sign的生成,参数的顺序一定要严格按照上面的顺序加上key进行MD5加密,查看签名规范。
关于key的说明,这里的key是需要自己生成然后配置到微信开放平台的,参考商户支付密钥key的生成与设置进行配置,两边需要保持一致。另外,下单时,参数要以xml的格式来传递。
最后附上自己的签名算法:
SignUtil.java
packagecom.xylpay.sdk.pay.uikit; importjava.security.MessageDigest; importjava.security.NoSuchAlgorithmException; /** *CreatedbyJackieon2016/2/15. **MD5加密 */ publicclassSignUtil{ publicstaticStringsignByMD5(Stringsource){ byte[]bytes=null; try{ MessageDigestdigest=MessageDigest.getInstance("MD5"); digest.update(source.getBytes());//更新摘要 bytes=digest.digest();//再通过执行诸如填充之类的最终操作完成哈希计算。在调用此方法之后,摘要被重置。 }catch(NoSuchAlgorithmExceptione){ e.printStackTrace(); } StringBuilderbuilder=newStringBuilder(bytes.length*2); for(byteb:bytes){ /** *0xFF默认是整形,一个byte跟0xFF相与会先将那个byte转化成整形运算 */ if((b&0xFF)<0x10){//如果为1位前面补个0 builder.append("0"); } builder.append(Integer.toHexString(b&0xFF)); } returnbuilder.toString(); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。