Android接入微信支付的方法
1、先在微信开放平台申请开发应用,微信开放平台会生成APP的唯一标识APPID。由于需要保证支付安全,需要在开放平台绑定商户应用包名和应用签名,设置好后才能正常发起支付。
2、注册APPID(这个可以放在项目的application里)
商户APP工程中引入微信JAR包,调用API前,需要先向微信注册您的APPID,代码如下:
finalIWXAPImsgApi=WXAPIFactory.createWXAPI(context,null);
//将该app注册到微信
msgApi.registerApp("wxd930ea5d5a258f4f");
3、调用统一下单api生成预付单,获取到prepay_id后将参数再次签名传输给APP发起支付。
例:
下面代码中的订单号是需要后台生成的
Stringurl="https://api.mch.weixin.qq.com/pay/unifiedorder"; WXPrePostpost=newWXPrePost(); post.appid="你的appId"; post.mch_id="你的商户号"; post.nonce_str=StringUtils.genNonceStr();//随机字符串**1 post.body="商品名称"; post.detail="商品的描述"; post.out_trade_no=out_trade_no;//商户订单号**2 post.total_fee="商品价格";//单位是分 post.spbill_create_ip=getLocalIpAddress();//ip地址**3 post.notify_url="";//这里是后台接受支付结果通知的url地址 post.trade_type="APP"; post.sign=genPackageSign(post);//签名**4 ListfirstSignParams=getFirstSignParams(post); Stringxml=toXml(firstSignParams); Stringentity=null; try{ entity=newString(xml.getBytes(),"ISO8859-1"); byte[]buf=Util.httpPost(url,entity); if(buf!=null){ Stringcontent=newString(buf); Map map=decodeXml(content); if(map!=null){ //再次签名(参与签名的字段有:AppidpartnerIdprepayIdnonceStrTimeStamppackage) StringappId=""; StringprepayId=""; StringnonceStr=""; for(Map.Entry entry:map.entrySet()){ if("appid".equals(entry.getKey())){ appId=entry.getValue(); }elseif("prepay_id".equals(entry.getKey())){ prepayId=entry.getValue(); }elseif("nonce_str".equals(entry.getKey())){ nonceStr=entry.getValue(); } } Log.d(TAG,"run::"+appId+"/"+prepayId+"/"+nonceStr+"/"); StringTimeStamp=String.valueOf(genTimeStamp()); //ok获取二次签名 StringsecondPackageSign=genSecondPackageSign(getSecondSignParams(appId,prepayId,nonceStr,TimeStamp)); PayReqreq=newPayReq(); req.appId=appId; req.partnerId="商户号"; req.prepayId=prepayId; req.nonceStr=nonceStr; req.timeStamp=TimeStamp; req.packageValue="Sign=WXPay"; req.sign=secondPackageSign; req.extData="appdata";//optional //System.out.println("genPackageSign3:"+post.getSign()+"/"+secondPackageSign); //在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信 mApi.sendReq(req); Log.d(TAG,"run:"+appId+"/"+prepayId+"/"+nonceStr+"/"+TimeStamp+"/"+secondPackageSign); } } }catch(Exceptione){ }
publicstaticbyte[]httpPost(Stringurl,Stringentity){
if(url==null||url.length()==0){
Log.e(TAG,"httpPost,urlisnull");
returnnull;
}
HttpClienthttpClient=getNewHttpClient();
HttpPosthttpPost=newHttpPost(url);
try{
httpPost.setEntity(newStringEntity(entity));
httpPost.setHeader("Accept","application/json");
httpPost.setHeader("Content-type","application/json");
HttpResponseresp=httpClient.execute(httpPost);
if(resp.getStatusLine().getStatusCode()!=HttpStatus.SC_OK){
Log.e(TAG,"httpGetfail,statuscode="+resp.getStatusLine().getStatusCode());
returnnull;
}
returnEntityUtils.toByteArray(resp.getEntity());
}catch(Exceptione){
Log.e(TAG,"httpPostexception,e="+e.getMessage());
e.printStackTrace();
returnnull;
}
}
//获取随机字符串的方法
publicstaticStringgenNonceStr(){
Randomrandom=newRandom();
returnMD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
}
privateStringtoXml(Listparams){ StringBuildersb=newStringBuilder(); sb.append(" "); for(inti=0;i "); returnsb.toString(); }"); sb.append(params.get(i).getValue()); sb.append(""+params.get(i).getName()+">"); } sb.append("
publicMapdecodeXml(Stringcontent){ try{ Map xml=newHashMap<>(); XmlPullParserparser=Xml.newPullParser(); parser.setInput(newStringReader(content)); intevent=parser.getEventType(); while(event!=XmlPullParser.END_DOCUMENT){ StringnodeName=parser.getName(); switch(event){ caseXmlPullParser.START_DOCUMENT: break; caseXmlPullParser.START_TAG: if(!"xml".equals(nodeName)){ xml.put(nodeName,parser.nextText()); } break; caseXmlPullParser.END_TAG: break; } event=parser.next(); } returnxml; }catch(Exceptione){ } returnnull; }
@NonNull privateListgetFirstSignParams(WXPrePostparams){ List packageParams=newLinkedList<>(); packageParams.add(newBasicNameValuePair("appid","appId")); packageParams.add(newBasicNameValuePair("body",params.body)); packageParams.add(newBasicNameValuePair("detail",params.detail)); packageParams.add(newBasicNameValuePair("mch_id","商户号")); packageParams.add(newBasicNameValuePair("nonce_str",params.nonce_str)); packageParams.add(newBasicNameValuePair("notify_url",params.notify_url)); packageParams.add(newBasicNameValuePair("out_trade_no",params.out_trade_no)); packageParams.add(newBasicNameValuePair("spbill_create_ip",params.spbill_create_ip)); packageParams.add(newBasicNameValuePair("total_fee",params.total_fee+"")); packageParams.add(newBasicNameValuePair("trade_type",params.trade_type)); packageParams.add(newBasicNameValuePair("sign",params.sign)); returnpackageParams; }
publicclassWXPrePost{
//必须带的参数
publicStringappid;
//微信开放平台审核通过的应用APPID
publicStringmch_id;
//微信支付分配的商户号
publicStringnonce_str;
//随机字符串,不长于32位。推荐随机数生成算法
publicStringsign;
//签名,详见签名生成算法
publicStringbody;
//商品描述交易字段格式根据不同的应用场景按照以下格式:APP——需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。
publicStringout_trade_no;
//商户系统内部的订单号,32个字符内、可包含字母,其他说明见商户订单号
publicinttotal_fee;
//订单总金额,单位为分,详见支付金额
publicStringspbill_create_ip;
//用户端实际ip
publicStringnotify_url;
//接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。(后台提供的)
publicStringtrade_type;
//支付类型
//非必须携带的参数
publicStringdevice_info;
//终端设备号(门店号或收银设备ID),默认请传"WEB"
publicStringdetail;
//商品名称明细列表
publicStringattach;
//附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
publicStringfee_type;
//符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
//
publicStringtime_start;
//订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
//
publicStringtime_expire;
//订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则注意:最短失效时间间隔必须大于5分钟
publicStringgoods_tag;
//商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠
//
publicStringlimit_pay;
//no_credit--指定不能使用信用卡支付
publicStringgetAppid(){
returnappid;
}
publicvoidsetAppid(Stringappid){
this.appid=appid;
}
publicStringgetMch_id(){
returnmch_id;
}
publicvoidsetMch_id(Stringmch_id){
this.mch_id=mch_id;
}
publicStringgetNonce_str(){
returnnonce_str;
}
publicvoidsetNonce_str(Stringnonce_str){
this.nonce_str=nonce_str;
}
publicStringgetSign(){
returnsign;
}
publicvoidsetSign(Stringsign){
this.sign=sign;
}
publicStringgetBody(){
returnbody;
}
publicvoidsetBody(Stringbody){
this.body=body;
}
publicStringgetOut_trade_no(){
returnout_trade_no;
}
publicvoidsetOut_trade_no(Stringout_trade_no){
this.out_trade_no=out_trade_no;
}
publicintgetTotal_fee(){
returntotal_fee;
}
publicvoidsetTotal_fee(inttotal_fee){
this.total_fee=total_fee;
}
publicStringgetSpbill_create_ip(){
returnspbill_create_ip;
}
publicvoidsetSpbill_create_ip(Stringspbill_create_ip){
this.spbill_create_ip=spbill_create_ip;
}
publicStringgetNotify_url(){
returnnotify_url;
}
publicvoidsetNotify_url(Stringnotify_url){
this.notify_url=notify_url;
}
publicStringgetTrade_type(){
returntrade_type;
}
publicvoidsetTrade_type(Stringtrade_type){
this.trade_type=trade_type;
}
publicStringgetDevice_info(){
returndevice_info;
}
publicvoidsetDevice_info(Stringdevice_info){
this.device_info=device_info;
}
publicStringgetDetail(){
returndetail;
}
publicvoidsetDetail(Stringdetail){
this.detail=detail;
}
publicStringgetAttach(){
returnattach;
}
publicvoidsetAttach(Stringattach){
this.attach=attach;
}
publicStringgetFee_type(){
returnfee_type;
}
publicvoidsetFee_type(Stringfee_type){
this.fee_type=fee_type;
}
publicStringgetTime_start(){
returntime_start;
}
publicvoidsetTime_start(Stringtime_start){
this.time_start=time_start;
}
publicStringgetTime_expire(){
returntime_expire;
}
publicvoidsetTime_expire(Stringtime_expire){
this.time_expire=time_expire;
}
publicStringgetGoods_tag(){
returngoods_tag;
}
publicvoidsetGoods_tag(Stringgoods_tag){
this.goods_tag=goods_tag;
}
publicStringgetLimit_pay(){
returnlimit_pay;
}
publicvoidsetLimit_pay(Stringlimit_pay){
this.limit_pay=limit_pay;
}
}
这里给出的参数都是可以移动端自己获取到的,当然,最好是后台提供给我们,出于安全性考虑
支付完成,微信会回调WXPayEntryActivity,这里就不详细说了,微信文档说的很清晰
在WXPayEntryActivity的onResp()里面返回的微信支付的结果(注:这个结果不能作为我们购买商品成功与否的结果,要以微信回调给回台,然后回台告诉我们的支付结果为准)
if(resp.getType()==ConstantsAPI.COMMAND_PAY_BY_WX){
intcode=resp.errCode;
switch(code){
case0:
Log.d(TAG,"onPayFinish,errCode="+"支付成功");
//微信支付成功后去调后台,以后台返回的支付结果为准
//这里是微信支付完成后的回调,在这里请求后台,让他来告诉我们到底支付成功没。
break;
case-1:
Toast.makeText(this,"支付失败1",Toast.LENGTH_SHORT).show();
Log.d(TAG,"onPayFinish,errCode="+"支付失败1");
finish();
break;
case-2:
Toast.makeText(this,"支付取消",Toast.LENGTH_SHORT).show();
Log.d(TAG,"onPayFinish,errCode="+"支付取消");
finish();
break;
default:
//Toast.makeText(this,"支付失败2",Toast.LENGTH_SHORT).show();
Log.d(TAG,"onPayFinish,errCode="+"支付失败2");
setResult(RESULT_OK);
finish();
break;
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。