1. First apply for development and application on the WeChat open platform. The WeChat open platform will generate the unique identification APPID of the APP. Since payment security is required, the merchant application package name and application signature need to be bound on the open platform, and payment can only be initiated normally after setting it up.
2. Register the APPID (this can be placed in the project application)
The WeChat JAR package is introduced into the merchant APP project. Before calling the API, you need to register your APPID with WeChat. The code is as follows:
final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);// Register the app to WeChat msgApi.registerApp("wxd930ea5d5a258f4f"); 3. Call the unified single API to generate a prepay order. After obtaining the prepay_id, sign the parameters and transmit them to the APP to initiate payment.
example:
The order number in the following code needs to be generated in the background
String url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; WXPrePost post = new WXPrePost(); post.appid = "your appId"; post.mch_id = "your merchant number"; post.nonce_str = StringUtils.genNonceStr();//Random string**1 post.body = "product name"; post.detail = "product description"; post.out_trade_no = out_trade_no; //Merchant order number**2 post.total_fee = "Commodity Price";//The unit is divided into post.spbill_create_ip = getLocalIpAddress();//ip address**3 post.notify_url = "";//This is the URL address for the backend to accept payment result notification post.trade_type = "APP"; post.sign = genPackageSign(post);//Signature**4 List<NameValuePair> firstSignParams = getFirstSignParams(post); String xml = toXml(firstSignParams); String entity = null; try { entity = new String(xml.getBytes(), "ISO8859-1"); byte[] buf = Util.httpPost(url, entity); if (buf != null) { String content = new String(buf); Map<String, String> map = decodeXml(content); if (map != null) { //Sign again (the fields participating in the signature are: Appid partnerId prepayId nonceStr TimeStamp package) String appId = ""; String prepayId = ""; String nonceStr = ""; for (Map.Entry<String, String> entry: map.entrySet()) { if ("appid".equals(entry.getKey())) { appId = entry.getValue(); } else if ("prepay_id".equals(entry.getKey())) { prepayId = entry.getValue(); } else if ("nonce_str".equals(entry.getKey()))) { nonceStr = entry.getValue(); } } Log.d(TAG, "run: :" + appId + "/" + prepayId + "/" + nonceStr + "/"); String TimeStamp = String.valueOf(genTimeStamp()); //ok Get the secondary signature String secondPackageSign = genSecondPackageSign(getSecondSignParams(appId, prepayId, nonceStr, TimeStamp)); PayReq req = new PayReq(); req.appId = appId; req.partnerId = "merchant number"; req.prepayId = prepayId; req.nonceStr = nonceStr; req.timeStamp = TimeStamp; req.packageValue = "Sign=WXPay"; req.sign = secondPackageSign; req.extData = "app data"; // optional // System.out.println("genPackageSign3:"+post.getSign()+"/"+secondPackageSign); // Before payment, if the application is not registered with WeChat, you should first call IWXMsg.registerApp to register the application to WeChat mApi.sendReq(req); Log.d(TAG, "run: " + appId + "/" + prepayId + "/" + nonceStr + "/" + TimeStamp + "/" + secondPackageSign); } } } catch (Exception e) { } public static byte[] httpPost(String url, String entity) { if (url == null || url.length() == 0) { Log.e(TAG, "httpPost, url is null"); return null; } HttpClient httpClient = getNewHttpClient(); HttpPost httpPost = new HttpPost(url); try { httpPost.setEntity(new StringEntity(entity)); httpPost.setHeader("Accept", "application/json"); httpPost.setHeader("Content-type", "application/json"); HttpResponse resp = httpClient.execute(httpPost); if (resp.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { Log.e(TAG, "httpGet fail, status code = " + resp.getStatusLine().getStatusCode()); return null; } return EntityUtils.toByteArray(resp.getEntity()); } catch (Exception e) { Log.e(TAG, "httpPost exception, e = " + e.getMessage()); e.printStackTrace(); return null; } } // Method to get random string public static String genNonceStr() { Random random = new Random(); return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes()); } private String toXml(List<NameValuePair> params) { StringBuilder sb = new StringBuilder(); sb.append("<xml>"); 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("</xml>"); return sb.toString(); } public Map<String, String> decodeXml(String content) { try { Map<String, String> 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)) { xml.put(nodeName, parser.nextText()); } break; case XmlPullParser.END_TAG: break; } event = parser.next(); } return xml; } catch (Exception e) { } return null; } @NonNull private List<NameValuePair> getFirstSignParams(WXPrePost params) { List<NameValuePair> packageParams = new LinkedList<>(); packageParams.add(new BasicNameValuePair("appid", "appId")); packageParams.add(new BasicNameValuePair("body", params.body)); packageParams.add(new BasicNameValuePair("detail", params.detail)); packageParams.add(new BasicNameValuePair("mch_id", "merchant number")); packageParams.add(new BasicNameValuePair("nonce_str", params.nonce_str)); packageParams.add(new BasicNameValuePair("notify_url", params.notify_url)); packageParams.add(new BasicNameValuePair("out_trade_no", params.out_trade_no)); packageParams.add(new BasicNameValuePair("spbill_create_ip", params.spbill_create_ip)); packageParams.add(new BasicNameValuePair("total_fee", params.total_fee + "")); packageParams.add(new BasicNameValuePair("trade_type", params.trade_type)); packageParams.add(new BasicNameValuePair("sign", params.sign)); return packageParams; } public class WXPrePost { //The parameters that must be brought with public String appid; //Application APPID approved by WeChat Open Platform public String mch_id; //The merchant number assigned by WeChat Pay public String nonce_str; //Random string, no longer than 32 digits. Recommended random number generation algorithm public String sign; //Signature, see the signature generation algorithm public String body; // Product description transaction field format is according to the following format according to different application scenarios: APP - APP name that needs to be passed into the application market - actual product name, Tiantian Aiying Eliminate - Game recharge. public String out_trade_no; // The order number inside the merchant system, which can contain letters within 32 characters. For other instructions, see the merchant order number public int total_fee; // The total order amount is in small units. For details, see the payment amount public String spbill_create_ip; // The actual ip public String notify_url; // The callback address for receiving WeChat payment asynchronous notifications, the notification url must be a directly accessible url and cannot carry parameters. (Provided in the background) public String trade_type; // Payment type// Parameters that are not required to be carried public String device_info; // Terminal device number (store number or cashier device ID), please pass "WEB" by default; // Product name details public String attach; // Additional data, returned as in the query API and payment notification. This field is mainly used for custom data of merchants carrying orders public String fee_type; // Three-digit letter code that complies with ISO 4217 standard, default RMB: CNY, see currency type for other value lists for details // public String time_start; // The order generation time is yyyyMMddHHmmss, as shown in 20091225091010, as shown in 20091225091010. For other details, see the time rules // public String time_expire; // Order expiration time, format is yyyyMMddHHmmss, as shown in 20091227091010 at 9:10 on December 27, 2009. Please refer to the time rules for other details. Note: The minimum expiration time interval must be greater than 5 minutes. Public String goods_tag; // Parameters of product tags, vouchers or discount discounts. For details, please refer to the vouchers or discount discounts. // public String limit_pay; //no_credit--Specify that you cannot use a credit card to pay public String getAppid() { return appid; } public void setAppid(String appid) { this.appid = appid; } public String getMch_id() { return mch_id; } public void setMch_id(String mch_id) { this.mch_id = mch_id; } public String getNonce_str() { return nonce_str; } public void setNonce_str(String nonce_str) { this.nonce_str = nonce_str; } public String getSign() { return sign; } public void setSign(String sign) { this.sign = sign; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public String getOut_trade_no() { return out_trade_no; } public void setOut_trade_no(String out_trade_no) { this.out_trade_no = out_trade_no; } public int getTotal_fee() { return total_fee; } public void setTotal_fee(int total_fee) { this.total_fee = total_fee; } public String getSpbill_create_ip() { return spbill_create_ip; } public void setSpbill_create_ip(String spbill_create_ip) { this.spbill_create_ip = spbill_create_ip; } public String getNotify_url() { return notify_url; } public void setNotify_url(String notify_url) { this.notify_url = notify_url; } public String getTrade_type() { return trade_type; } public void setTrade_type(String trade_type) { this.trade_type = trade_type; } public String getDevice_info() { return device_info; } public void setDevice_info(String device_info) { this.device_info = device_info; } public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } public String getAttach() { return attach; } public void setAttach(String attach) { this.attach = attach; } public String getFee_type() { return fee_type; } public void setFee_type(String fee_type) { this.fee_type = fee_type; } public String getTime_start() { return time_start; } public void setTime_start(String time_start) { this.time_start = time_start; } public String getTime_expire() { return time_expire; } public void setTime_expire(String time_expire) { this.time_expire = time_expire; } public String getGoods_tag() { return goods_tag; } public void setGoods_tag(String goods_tag) { this.goods_tag = goods_tag; } public String getLimit_pay() { return limit_pay; } public void setLimit_pay(String limit_pay) { this.limit_pay = limit_pay; }}The parameters given here can be obtained by the mobile terminal themselves. Of course, it is best to provide us with the background for security reasons.
After the payment is completed, WeChat will call back WXPayEntryActivity. I won’t go into details here. The WeChat document clearly states the results of WeChat payment returned in the onResp() of WXPayEntryActivity (Note: This result cannot be the result of whether we purchase the product successfully. We must use WeChat callback to the Taiwan Strait and then return to the Taiwan Strait to tell us the payment result).
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) { int code = resp.errCode; switch (code) { case 0: Log.d(TAG, "onPayFinish, errCode = " + "Pay Success"); //After WeChat payment successful, go to the background, the payment result returned by the background is the basis. //This is the callback after WeChat payment is completed. Here is a request for the background and ask him to tell us whether the payment is successful. break; case -1: Toast.makeText(this, "Pay failed 1", Toast.LENGTH_SHORT).show(); Log.d(TAG, "onPayFinish, errCode = " + "Pay failed 1"); finish(); break; case -2: Toast.makeText(this, "Pay cancel", Toast.LENGTH_SHORT).show(); Log.d(TAG, "onPayFinish, errCode = " + "Pay cancel"); finish(); break; default:// Toast.makeText(this, "Pay failed 2", Toast.LENGTH_SHORT).show(); Log.d(TAG, "onPayFinish, errCode = " + "Pay failed 2"); setResult(RESULT_OK); finish(); break; } }The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.