Android微信支付踩坑全记录

首先吐槽一下,微信支付的文档和微信提供的demo实在是惨不忍睹,折腾了好久才终于搞定了,如果还是有问题,请仔细检查请求的参数是否正确,一般都是漏掉了某个参数的名称之类的。

1. 首先第一步,获取应用的MD5签名信息

这里写图片描述
如果你没有配置keytool的环境,那么也可以直接使用 微信提供的获取包签名的信息

2. 申请过程就不提了,千万注意,应用包名和签名信息一定要填对,一开始我的签名信息弄错了,折腾了好久。

3. 申请好了之后,现在开始接入

dependencies {
   compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
}
  • 注册APPID
final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);
// 将该app注册到微信
msgApi.registerApp("wxd930ea5d5a258f4f");
public String getOderXml() {
       Map<String, String> oderMap = new HashMap<>();
       oderMap.put("appid", appid); //
       oderMap.put("mch_id", mch_id);//
       oderMap.put("device_info", device_info);//-
       oderMap.put("nonce_str", nonce_str);//
       oderMap.put("trade_type", trade_type);
       oderMap.put("body", body);
       oderMap.put("detail", detail);
       oderMap.put("out_trade_no", out_trade_no);
       oderMap.put("total_fee", total_fee);
       oderMap.put("spbill_create_ip", spbill_create_ip);
       oderMap.put("time_start", time_start);
       oderMap.put("notify_url", notify_url);

       //拼接字符串加上key值,然后对sign进行md5解密,之后再转成大写
       //将集合M内非空参数值的参数按照参数名ASCII码从小到大排序
       StringBuilder sign = new StringBuilder();
       TreeSet<String> set = new TreeSet<>(new Comparator<String>() {
           @Override
           public int compare(String lhs, String rhs) {
               int i = rhs.compareTo(lhs);
               if (i > 0) {
                   return -1;
               } else if (i < 0) {
                   return 1;
               } else {
                   return i;
               }
           }
       });
       set.addAll(oderMap.keySet());

       for (String str : set) {
           sign.append(str).append("=").append(oderMap.get(str)).append("&");
       }
       sign.append("key").append("=").append(WechatUtil.KEY);
       oderMap.put("sign", StringUtil.md5(sign.toString()).toUpperCase());

       //拼接成xml格式的字符串
       StringBuilder stringBuilder = new StringBuilder();
       stringBuilder.append("<xml>");
       set.clear();
       set.addAll(oderMap.keySet());
       for (String s : set) {
           stringBuilder.append("<").append(s).append(">");
           stringBuilder.append(oderMap.get(s));
           stringBuilder.append("</").append(s).append(">");
       }
       stringBuilder.append("</xml>");
       return stringBuilder.toString();
   }
//处理微信返回的xml数据
public OderResult xmlToResult(String xml) {
       XmlPullParser pullParser = Xml.newPullParser();
       InputStream ins = new ByteArrayInputStream(xml.getBytes());
       OderResult result = new OderResult();
       try {
           pullParser.setInput(ins, "utf-8");
           int eventType = pullParser.getEventType();
           while (XmlPullParser.END_DOCUMENT != eventType) {
               switch (eventType) {
                   case XmlPullParser.START_TAG:
                       if ("return_code".equals(pullParser.getName())) {
                           result.setReturn_code(pullParser.nextText());
                       }
                       if ("return_msg".equals(pullParser.getName())) {
                           result.setReturn_msg(pullParser.nextText());
                       }
                       if ("appid".equals(pullParser.getName())) {
                           result.setAppid(pullParser.nextText());
                       }
                       if ("mch_id".equals(pullParser.getName())) {
                           result.setMch_id(pullParser.nextText());
                       }
                       if ("device_info".equals(pullParser.getName())) {
                           result.setDevice_info(pullParser.nextText());
                       }
                       if ("nonce_str".equals(pullParser.getName())) {
                           result.setNonce_str(pullParser.nextText());
                       }
                       if ("sign".equals(pullParser.getName())) {
                           result.setSign(pullParser.nextText());
                       }
                       if ("prepay_id".equals(pullParser.getName())) {
                           result.setPrepay_id(pullParser.nextText());
                       }
                       if ("trade_type".equals(pullParser.getName())) {
                           result.setTrade_type(pullParser.nextText());
                       }
                       if ("result_code".equals(pullParser.getName())) {
                           result.setResult_code(pullParser.nextText());
                       }
                       break;
                   case XmlPullParser.END_TAG:
                       break;
                   default:
                       break;
               }
               eventType = pullParser.next();
           }
       } catch (XmlPullParserException e) {
           e.printStackTrace();
       } catch (IOException e) {
           e.printStackTrace();
       }
       return result;
   }
//随机字符串,不长于32位
   public String getRandom() {
       SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmmss", Locale.getDefault());
       Date date = new Date();
       String key = format.format(date);
       Random r = new Random();
       key = key + r.nextLong();
       key = StringUtil.md5(key);
       return key;
   }
IWXAPI api;
PayReq request = new PayReq();
request.appId = "wxd930ea5d5a258f4f";
request.partnerId = "1900000109";
request.prepayId= "1101000000140415649af9fc314aa427",;
request.packageValue = "Sign=WXPay";
request.nonceStr= "1101000000140429eb40476f8896f4c9";
request.timeStamp= "1398746574";
request.sign= "7FFECB600D7157C5AA49810D2D8F28BC2811827B";
api.sendReq(request);
  • 支付结果回调,实现一个.wxapi.WXPayEntryActivity(包名或类名不一致会造成无法回调)。如果不需要显示这个,直接finish就好了。
<activity
           android:name=".wxapi.WXPayEntryActivity"
           android:exported="true" />
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
    
    
    private IWXAPI api;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        api = WXAPIFactory.createWXAPI(this, WechatUtil.APPID, false);
        api.handleIntent(getIntent(), this);
    }

    @Override
    public void onReq(BaseReq baseReq) {

    }

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

    @Override
    public void onResp(BaseResp baseResp) {

        if (baseResp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
            if (baseResp.errCode == BaseResp.ErrCode.ERR_COMM) {
                showToast("微信支付失败");
            } else if (baseResp.errCode == BaseResp.ErrCode.ERR_USER_CANCEL) {
                showToast("用户取消");
            } else if (baseResp.errCode == BaseResp.ErrCode.ERR_OK) {
                showToast("微信支付成功");
            }
        }
    }
}
  • 如果返回的是失败,请再仔细检查调起支付的参数是否正确,进行sign签名的参数是否正确,如果还是不行,请再检查一遍,微信支付的错误信息太少了,只有成功和失败,如果统一下单成功了的话,那么就是一定是你们调起支付的参数错误,请一定要的仔细检查,重要的事重复三遍。
  • 如果是统一下单的时候有问题,请确认后台返回给你的订单号是否是唯一的,参数是否正确,sign的时候时候按照要求签名,微信平台填的是否是MD5签名,发起请求的方式是否为post,是否传送的是XML数据,如果是使用Retrofit发起请求,可以这样子:
new Retrofit.Builder()
             .baseUrl("https://api.mch.weixin.qq.com/pay/")
             .addConverterFactory(StringConverterFactory.create())
             .build()
             .create(API.class)
             .oder(RequestBody.create(MediaType.parse("text/plain"), oder)).enqueue(new Callback<String>() {
         @Override
         public void onResponse(Call<String> call, Response<String> response) {
             if (response.body() != null) {
                 OderResult result = xmlToResult(response.body());
                 if (result.getReturn_code().equals("SUCCESS")) {
                     if (result.getResult_code().equals("SUCCESS")) {

                     }
                 } else {

                 }
             }

         }

         @Override
         public void onFailure(Call<String> call, Throwable t) {

         }
     });
private interface API {
    
    
        @POST("unifiedorder")
        Call<String> oder(@Body RequestBody oder);
    }

猜你喜欢

转载自blog.csdn.net/Ser_Bad/article/details/68490947