微信V3支付(避免重复进入这个坑)

微信支付遇到了无数的坑,总算是一个个解决了,官方文档真是让人郁闷到死,不多说,直接上代码。

一.生成预支付订单

private StringBuffer strbuffer;
private Map resultunifiedorder;
private final IWXAPI msgApi = WXAPIFactory.createWXAPI(this, null);

1.1准备工作

strbuffer=new StringBuffer();
msgApi.registerApp(Constants.APP_ID);
GetPrepayIdTask getPrepayId = new GetPrepayIdTask();
getPrepayId.execute();
 
  

1.2GetPrepayIdTask 

//1.获取预支付订单编号
 private class GetPrepayIdTask extends AsyncTask> {

     private ProgressDialog dialog;


     @Override
     protected void onPreExecute() {
         dialog = ProgressDialog.show(EShopWEIXIN_EPAYActivity.this, "提示", "正在获取预支付订单...");
     }

     @Override
     protected void onPostExecute(Map result) {
         if (dialog != null) {
             dialog.dismiss();
         }
	resultunifiedorder=result;

         if(result.get("return_code").contentEquals("SUCCESS") ){//预支付成功
             genPayReq();//2生成签名参数
            
         }
         strbuffer.append("prepay_id\n"+result.get("prepay_id")+"\n\n");
     }

     @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 = WXUtil.httpPost(url, entity);//提交预支付订单

         String content = new String(buf);
         Log.e("orion", content);
         Map xml=decodeXml(content);

         return xml;
     }
 }
 
  
1.3生成预支付订单请求
 
  
private String genProductArgs() {
      StringBuffer xml = new StringBuffer();

      try {
         String nonceStr = genNonceStr();
         String strIP=genWifiIp();//获取手机ip

         xml.append("");
         List packageParams = new LinkedList();
         packageParams.add(new BasicNameValuePair("appid", Constants.APP_ID));//应用ID
         packageParams.add(new BasicNameValuePair("body", "e"));//商品描述e路通-保险支付
         packageParams.add(new BasicNameValuePair("mch_id", Constants.MCH_ID));//商户号
         packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));//随机字符串nonceStr
         packageParams.add(new BasicNameValuePair("notify_url", "http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php"));//通知地址
         packageParams.add(new BasicNameValuePair("out_trade_no", "15036257092394985"));//商户订单号
         packageParams.add(new BasicNameValuePair("spbill_create_ip", strIP));//用户端实际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);
//       xmlstring = new String(xmlstring.getBytes(), "ISO-8859-1");
         return xmlstring;//String(xmlstring.getBytes("UTF-8"), "ISO8859-1")body使用中文xml要转码

      } catch (Exception e) {

         return null;
      }

   }

1.4随机数
 
  
private String genNonceStr() {
   Random random = new Random();
   return MD5.getMessageDigest(String.valueOf(random.nextInt(10000))
         .getBytes());
}

1.5通过wifi获取用户手机IP
 
  
private String genWifiIp() {
   //获取wifi管理服务
   WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(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) ;
}

1.6商户订单号(只要唯一就可以)
 
  
private String genOutTradNo() {
   Random rand = new Random();
   int randNum = rand.nextInt(9999);
   String randStr = String.format("%04d", randNum);
   String orderseq = String.valueOf(System.currentTimeMillis())+randStr;
   return orderseq;
}

1.7sign预支付签名
 
  
private String genPackageSign(List params) {
   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);


   String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
   Log.e("orion",packageSign);
   return packageSign;
}

1.8提交数据的格式化
 
  
private String toXml(List params) {
   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();
}

1.9WXUtil文件
 
  
 
  
2.0返回数据格式化
 
  
public Map decodeXml(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;

}

二、调起微信支付
 
  
1.1调起genPayReq()开始微信支付;
 
  
private void genPayReq() {
    PayReq req= new PayReq();
    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);

    strbuffer.append("sign\n"+req.sign+"\n\n");
    msgApi.registerApp(Constants.APP_ID);
msgApi.sendReq(req); Log. e( "orion", signParams.toString());}
1.2时间戳
 
  
private long genTimeStamp() {
   return System.currentTimeMillis() / 1000;
}
 
  
1.3sign二次签名
 
  
private String genAppSign(List params) {
    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.strbuffer.append("sign str\n"+sb.toString()+"\n\n");
    String appSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
    Log.e("orion",appSign);
    return appSign;
}

三、支付结果

    参照微信SDK Sample,在net.sourceforge.simcpux.wxapi包路径中实现WXPayEntryActivity类

(包名或类名不一致会造成无法回调)在WXPayEntryActivity类中实现onResp函数,支付完成后,
微信APP会返回到商户APP并回调onResp函数,开发者需要在该函数中接收通知,判断返回错误码,
如果支付成功则去后台查询支付结果再展示用户实际支付结果。注意一定不能以客户端返回作为用户支付的结果,
应以服务器端的接收的支付通知或查询API返回的结果为准。
 
  

package cn.com.siyuan.eshop.wxapi;


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.tencent.mm.sdk.constants.ConstantsAPI;
import com.tencent.mm.sdk.modelbase.BaseReq;
import com.tencent.mm.sdk.modelbase.BaseResp;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.sdk.openapi.WXAPIFactory;

import cn.com.siyuan.eshop.utils.Util;
import cn.com.siyuan.eshop.weixinepay.Constants;
import cn.com.siyuan.rbeshop.R;

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler{
   
   private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";
   
    private IWXAPI api;
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pay_result);
        
       api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
        api.handleIntent(getIntent(), this);
    }

   @Override
   protected void onNewIntent(Intent intent) {
      super.onNewIntent(intent);
      setIntent(intent);
        api.handleIntent(intent, this);
   }

   @Override
   public void onReq(BaseReq req) {
      
   }

   @Override
   public void onResp(BaseResp resp) {
      Log.d(TAG, "onPayFinish, errCode = " + resp.errCode);
      if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
         if(resp.errCode==0){
            Toast.makeText(WXPayEntryActivity.this,"支付成功!",Toast.LENGTH_LONG).show();
         }else if(resp.errCode==-1){
            Toast.makeText(WXPayEntryActivity.this,"支付失败!",Toast.LENGTH_LONG).show();
         }else if(resp.errCode==-2){
            Toast.makeText(WXPayEntryActivity.this,"用户取消支付!支付失败!",Toast.LENGTH_LONG).show();
         }
         Util.isPay=resp.errCode;
         finish();
      }
   }
}
 
  

你可能感兴趣的:(安卓,微信)