Full record of Android WeChat payment stepping on the pit

First of all, let me talk about it. The WeChat payment documentation and the demo provided by WeChat are really horrible. It took a long time to finally get it done. If there is still a problem, please check carefully whether the requested parameter is correct. Generally, the name of a parameter is omitted. some type of.

1. The first step is to obtain the MD5 signature information of the application

Write picture description here
If you do not keytool environment configuration, you can also use direct access to information provided by the micro-channel package signatures

2. I won’t mention the application process, please pay attention, the application package name and signature information must be filled in correctly. At the beginning, my signature information was wrong, and it took a long time.

3. After the application is complete, start accessing now

dependencies {
   compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
}
  • Register 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);
  • The payment result callback, implement one .wxapi.WXPayEntryActivity(the inconsistent package name or class name will make the callback impossible). If you don't need to display this, just finish directly.
<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("微信支付成功");
            }
        }
    }
}
  • If it returns a failure, please double check whether the parameters of the payment call are correct and the parameters for the sign signature are correct. If it still does not work, please check again. There are too few error messages for WeChat payment, only success and failure. If the unified order is successful, then it must be the parameter that you transferred to the payment is wrong, please check carefully, and repeat the important thing three times.
  • If there is a problem when placing an order in a unified manner, please confirm whether the order number returned to you by the backend is unique, whether the parameters are correct, sign according to the requirements when signing, whether the WeChat platform fills in the MD5 signature, and whether the method of initiating the request For post, whether it is XML data or not, if you use Retrofit to initiate the request, you can do this:
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);
    }

Guess you like

Origin blog.csdn.net/Ser_Bad/article/details/68490947