美文网首页
微信支付开发踩坑记录

微信支付开发踩坑记录

作者: T_涛_T | 来源:发表于2016-08-25 15:24 被阅读0次

    在做微信支付时,虽然网上已经有了很多的文档和介绍,但是自己做了一遍还是遇到了很多坑,现在记录下来。

    首先说一下大概的核心代码:

    1、在微信开放平台下载了jar包后导入项目,建议顺便下载官方文档参考。虽然微信的开发文档有点坑,但有总比没有强。

    2、按照开发文档,做好相关配置。下面正式开始自己的代码。

    2.1、调用统一下单接口,该接口返回的是一个prepayId值。一般这一步都是由公司后台去进行,但有些公司可能需要自己写,现在写一下。

    首先准备几个方法。

    //获取上网ip地址:

    public static String getLocalIpAddress(Context context){

    try{// 获取wifi服务

    WifiManager wifiManager = (WifiManager) context

    .getSystemService(Context.WIFI_SERVICE);

    if (!wifiManager.isWifiEnabled()){

    //不能使用wifi

    return getLocalIpAddress();

    }else{WifiInfo wifiInfo = wifiManager.getConnectionInfo();

    int i = wifiInfo.getIpAddress();

    return int2ip(i);}

    } catch (Exception ex){

    return " 获取IP出错!!!!请保证是WIFI,或者请重新打开网络!\n" + ex.getMessage();}

    }

    public static String getLocalIpAddress() {      try {          for (Enumerationen = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {              NetworkInterface intf = en.nextElement();              for (EnumerationenumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {

    InetAddress inetAddress = enumIpAddr.nextElement();

    if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {

    //if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet6Address) {

    return inetAddress.getHostAddress().toString();

    }

    }

    }

    } catch (Exception e) {

    }

    return "";

    }

    这些代码是我在网上找到的,wifi的可以准确获取,但gps的貌似有时候会出问题,有知道的可以指点一下。

    //生成随机数,需要md5加密:

    private String genNonceStr()

    {

    Random random = new Random();

    String md5 = "";

    try

    {

    md5 = MD5Util.md5Encode(String.valueOf(random.nextInt(10000)));

    } catch (Exception e)

    {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    return md5;

    }

    /***

    * MD5加密 生成32位md5码

    * @param 待加密字符串

    * @return 返回32位md5码

    */

    public static String md5Encode(String inStr) throws Exception {

    MessageDigest md5 = null;

    try {

    md5 = MessageDigest.getInstance("MD5");

    } catch (Exception e) {

    System.out.println(e.toString());

    e.printStackTrace();

    return "";

    }

    byte[] byteArray = inStr.getBytes("UTF-8");

    byte[] md5Bytes = md5.digest(byteArray);

    StringBuffer hexValue = new StringBuffer();

    for (int i = 0; i < md5Bytes.length; i++) {

    int val = ((int) md5Bytes[i]) & 0xff;

    if (val < 16) {

    hexValue.append("0");

    }

    hexValue.append(Integer.toHexString(val));

    }

    return hexValue.toString();

    }

    /** * 获取签名 * @param params * @return */private String genAppSign(Listparams)

    {

    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < params.size(); i++)

    {

    sb.append(((BasicNameValuePair) params.get(i)).getName());

    sb.append('=');

    sb.append(((BasicNameValuePair) params.get(i)).getValue());

    sb.append('&');

    }

    sb.append("key=");

    sb.append(Config.WXMY);

    String appSign = "";

    try

    {

    appSign = MD5Util.md5Encode(sb.toString()).toUpperCase(Locale.CHINESE);

    } catch (Exception e)

    {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    return appSign;

    }

    在获得后台返回的商品订单号后,开启线程去提交参数。

    new Thread(){

    public void run(){

    try{

    int factPaymoney = (int) (rechargeAmount* 100);//微信单位是分

    String ip =  NetworkUtils.getLocalIpAddress(PayActivity.this);//获取ip地址

    String radom32=genNonceStr();//生成随机数

    List<BasicNameValuePair>signParams = new LinkedList<BasicNameValuePair>();

    //下面的参数你可以看官方文档查看意思,然后填入你自己的数据

    signParams.add(new BasicNameValuePair("appid", Config.WXAPPID));

    signParams.add(new BasicNameValuePair("body", reChargeName));

    signParams.add(new BasicNameValuePair("mch_id", Config.MCHID));//

    signParams.add(new BasicNameValuePair("nonce_str",radom32 ));

    signParams.add(new BasicNameValuePair("notify_url",""));

    signParams.add(new BasicNameValuePair("out_trade_no", paymentID));

    signParams.add(new BasicNameValuePair("spbill_create_ip", ip));

    signParams.add(new BasicNameValuePair("total_fee", 1+""));

    signParams.add(new BasicNameValuePair("trade_type", "APP"));

    StringBuilder xml = new StringBuilder();

    xml.append("<xml>");

    xml.append("<appid>" + Config.WXAPPID+ "</appid>");

    xml.append("<body>"+reChargeName+"</body>");

    xml.append("<mch_id>" + Config.MCHID+ "</mch_id>");

    xml.append("<nonce_str>" +radom32+ "</nonce_str>");

    xml.append("<notify_url>" + "自己的通知地址"+ "</notify_url>");

    xml.append("<out_trade_no>" + paymentID+ "</out_trade_no>");

    xml.append("<sign>"+ genAppSign(signParams)+"</sign>");

    xml.append("<spbill_create_ip>"+ip+"</spbill_create_ip>");

    xml.append("<total_fee>"+填入金额+"</total_fee>");

    xml.append("<trade_type>APP</trade_type>");

    xml.append("</xml>");

    Stringxmls= new String(xml.toString().getBytes(), "UTF-8");

    byte[] xmlbyte = xmls.getBytes("UTF-8");

    URL url = new URL("https://api.mch.weixin.qq.com/pay/unifiedorder");//微信统一下单接口

    HttpURLConnection conn = (HttpURLConnection) url.openConnection();

    conn.setDoOutput(true);

    conn.setConnectTimeout(5000);

    conn.setRequestMethod("POST");

    conn.setRequestProperty("Content-Type","text/xml;charset=UTF-8");//此处需要设置你的编码格式,我用的utf-8,不然中文会乱码

    conn.setRequestProperty("Content-Length",

    String.valueOf(xmlbyte.length));

    conn.getOutputStream().write(xmlbyte);

    if (conn.getResponseCode() == 200){InputStream is = conn.getInputStream();// 获取返回数据

    // 使用输出流来输出字符(可选)

    ByteArrayOutputStream out = new ByteArrayOutputStream();

    byte[] buf = new byte[1024];

    int len;while ((len = is.read(buf)) != -1){out.write(buf, 0, len);}

    String string = out.toString("UTF-8");

    Message msg= new Message();

    msg.what=1;

    msg.obj=string;handler.sendMessage(msg);out.close();}

    } catch (Exception e){e.printStackTrace();}

    };}.start();

    @SuppressLint("HandlerLeak")

    private Handler handler = new Handler(){

    public void handleMessage(Message msg) {

    switch (msg.what) {

    case 1:

    try{

    String prepar_id=msg.obj.toString();

    int start=prepar_id.indexOf("prepay_id");

    int end =prepar_id.indexOf("]]></prepay_id>");

    prepar_id=prepar_id.substring(start+19, end);//此处获得我们需要的prepar_id字段

    sendPayReq(prepar_id);//最后再次进行传参,发起支付

    } catch (Exception e)

    {

    }

    break;

    }

    };

    };

    2.2 发起支付

    /**

    * 调用微信支付页面

    */

    private void sendPayReq(String prepayId)

    {

    api.registerApp(Config.WXAPPID);//此处踩过坑,以为写了appregister注册后不用在注册,事实是需要,所以不知道那个appregister有什么作用

    genPayReq(prepayId);

    api.sendReq(req);//此处成功后,会回调微信支付结果页面WXPayEntryActivity,这个在官方文档里有

    }

    /** * 生成签名参数 * @param prepayId  */

    private void  genPayReq(String prepayId){

    req.appId = Config.WXAPPID;// appid

    req.partnerId = Config.MCHID;// 商户号

    req.prepayId = prepayId;// 预支付交易会话ID

    req.packageValue = "Sign=WXPay";// 扩展字段,固定的

    req.nonceStr = genNonceStr();// 随机字符串

    req.timeStamp = String.valueOf(genTimeStamp());// 时间戳

    List<BasicNameValuePair> signParams = newLinkedList<BasicNameValuePair>();

    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);//再次签名

    }

    /**

    * 时间戳

    *

    * @return

    */

    private long genTimeStamp()

    {

    return System.currentTimeMillis() / 1000;

    }

    以上就是微信支付开发的基本步骤了,记录一下,以备以后再用。

    相关文章

      网友评论

          本文标题:微信支付开发踩坑记录

          本文链接:https://www.haomeiwen.com/subject/hmkosttx.html