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();
}
}
|
|