配色: 字号:
Android集成微信支付功能
2017-01-03 | 阅:  转:  |  分享 
  
Android集成微信支付功能



这里主要说下调起支付的注意事项。按照上面文档中说的商户服务器生成支付订单,先调用统一下单API生成预付单,获取到prepay_id后将参数再次签名传输给APP发起支付。



相关代码如下:





[java]viewplaincopy在CODE上查看代码片派生到我的代码片

/

商户服务器生成支付订单,先调用统一下单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=""+Constants.APP_ID+""+Constants.MCH_ID+""+nonce_str+""+sign+

"
"+body+""+out_trade_no+""+total_fee+

"
127.0.0.1http://www.weixin.qq.com/wxpay/pay.phpAPP
";



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



[java]viewplaincopy在CODE上查看代码片派生到我的代码片

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
intposition=random.nextInt(source.length());

builder.append(source.charAt(position));

}



returnbuilder.toString();

}



publicstaticStringgenerateOutTradeNo(intn){

StringBuilderbuilder=newStringBuilder();

Randomrandom=newRandom();

for(inti=0;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.printStacwww.tt951.comkTrace();

}catch(IOExceptione){

e.printStackTrace();

}



returnorderResult;

}

}

其中关于sign的生成,参数的顺序一定要严格按照上面的顺序加上key进行MD5加密,查看签名规范。

关于key的说明,这里的key是需要自己生成然后配置到微信开放平台的,参考商户支付密钥key的生成与设置进行配置,两边需要保持一致。另外,下单时,参数要以xml的格式来传递。



最后附上自己的签名算法:



SignUtil.java



[java]viewplaincopy在CODE上查看代码片派生到我的代码片

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.length2);

for(byteb:bytes){

/

0xFF默认是整形,一个byte跟0xFF相与会先将那个byte转化成整形运算

/

if((b&0xFF)<0x10){//如果为1位前面补个0

builder.append("0");

}



builder.append(Integer.toHexString(b&0xFF));

}



returnbuilder.toString();

}

}

献花(0)
+1
(本文系thedust79首藏)