Recently, the project requires WeChat payment, and then I looked at the WeChat official account payment. Although it is not difficult, the details still need to be paid attention to. I spent most of the day writing a demo and tested the payment process completely. Let’s share the experience of WeChat official account payment below.
1. Configure official account WeChat payment
We need to configure the WeChat official account payment address and test whitelist.
For example: The address of the payment JS page is http://www.xxx.com/shop/pay/
Then here is configured www.xxx.com/shop/pay/
2. Development process
Borrow the WeChat official account to pay for the API (address http://pay.weixin.qq.com/wiki/doc/api/index.PHP?chapter=7_4), which we need to develop is marked in red. as follows:
3. Place an order with the WeChat server
Call the unified single interface so that you can get the prepay_id of WeChat payment (http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_1).
Before calling this interface, there are several fields that are openids that must be filled in for H5 payment.
3.1 Get openid
You can use the web authorization form (http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html)
Send the following link in WeChat
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=url&response_type=code&scope=snsapi_base&state=123#wechat_redirect
3.2 Place an order to get prepay_id
The code is as follows, which is actually sending an XML file through post to obtain the prepay_id sent from the WeChat server.
import java.io.ByteArrayInputStream; import javaioIOException; import javaioInputStream; import javaioUnsupportedEncodingException; import javautilDate; import javautilHashMap; import javautilIterator; import javautilMap; import javautilMapEntry; import javautilRandom; import javaxservlethttpHttpServletRequest; import javaxservlethttpHttpServletResponse; import orgapachecommonscodecdigestDigestUtils; import orgspringframeworkstereotypeController; import orgspringframeworkwebbindannotationRequestMapping; import orgxmlpullvXmlPullParser; import orgxmlpullvXmlPullParserException; import orgxmlpullvXmlPullParserFactory; import comfasterxmljacksondatabindJsonNode; import comgsonoauthOauth; import comgsonoauthPay; import comgsonutilHttpKit; import comsyutilDatetimeUtil; import comsyutilJsonUtil; @Controller @RequestMapping("/pay") public class WXPayController { @RequestMapping(value = "wxprepaydo") public void jspay(HttpServletRequest request, HttpServletResponse response, String callback) throws Exception { // Get openid String openId = SessionUtilgetAtt(request, "openId"); if (openId == null) { openId = getUserOpenId(request); } String appid = "wx16691fcb0523c1a4"; String paternerKey = "ININGFENG1234567fdfwfdfd1ss234567"; String out_trade_no = getTradeNo(); Map<String, String> paraMap = new HashMap<String, String>(); paraMapput("appid", appid); paraMapput("attach", "test"); paraMapput("body", "test purchase payment"); paraMapput("mch_id", "10283271"); paraMapput("nonce_str", create_nonce_str()); paraMapput("openid", openId); paraMapput("out_trade_no", out_trade_no); paraMapput("spbill_create_ip", getAddrIp(request)); paraMapput("total_fee", "1"); paraMapput("trade_type", "JSAPI"); paraMapput("notify_url", "http://wwwxxxco/bank/page/wxnotify"); String sign = getSign(paraMap, paternerKey); paraMapput("sign", sign); // Unified order https://apimchweixinqqcom/pay/unifiedorder String url = "https://apimchweixinqqcom/pay/unifiedorder"; String xml = ArrayToXml(paraMap); String xmlStr = HttpKitpost(url, xml); // Prepaid product id String prepay_id = ""; if (xmlStrindexOf("SUCCESS") != -1) { Map<String, String> map = doXMLParse(xmlStr); prepay_id = (String) mapget("prepay_id"); } Map<String, String> payMap = new HashMap<String, String>(); payMapput("appId", appid); payMapput("timeStamp", create_timestamp()); payMapput("nonceStr", create_nonce_str()); payMapput("signType", "MD5"); payMapput("package", "prepay_id=" + prepay_id); String paySign = getSign(payMap, paternerKey); payMapput("pg", prepare_id); payMapput("paySign", paySign); WebUtilresponse(response, WebUtilpackJsonp(callback, JsonUtilwarpJsonNodeResponse(JsonUtilobjectToJsonNode(payMap))toString())); } /** * map to xml * * @param arr * @return */ public String ArrayToXml(Map<String, String> arr) { String xml = "<xml>"; Iterator<Entry<String, String>> iter = arrentrySet()iterator(); while (iterhasNext()) { Entry<String, String> entry = iternext(); String key = entrygetKey(); String val = entrygetValue(); xml += "<" + key + ">" + val + "</" + key + ">"; } xml += "</xml>"; return xml; } // Get openId private String getUserOpenId(HttpServletRequest request) throws Exception { String code = requestgetParameter("code"); if (code == null) { String openId = requestgetParameter("openId"); return openId; } Oauth o = new Oauth(); String token = ogetToken(code); JsonNode node = JsonUtilStringToJsonNode(token); String openId = nodeget("openid")asText(); return openId; } private String create_nonce_str() { String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; String res = ""; for (int i = 0; i < 16; i++) { Random rd = new Random(); res += charscharAt(rdnextInt(charslength() - 1)); } return res; } private String getAddrIp(HttpServletRequest request){ return requestgetRemoteAddr(); } private String create_timestamp() { return LongtoString(SystemcurrentTimeMillis() / 1000); } private String getTradeNo(){ String timestamp = DatetimeUtilformatDate(new Date(), DatetimeUtilDATETIME_PATTERN); return "HZNO" + timestamp; } private String getSign(Map<String, String> params, String paternerKey ) throws UnsupportedEncodingException { String string1 = PaycreateSign(params, false); String stringSignTemp = string1 + "&key=" + paternerKey; String signValue = DigestUtilsmd5Hex(stringSignTemp)toUpperCase(); return signValue; } private Map<String, String> doXMLParse(String xml) throws XmlPullParserException, IOException { InputStream inputStream = new ByteArrayInputStream(xmlgetBytes()); Map<String, String> map = null; XmlPullParser pullParser = XmlPullParserFactorynewInstance() newPullParser(); pullParsersetInput(inputStream, "UTF-8"); // Set the xml data to be parsed for xml int eventType = pullParsergetEventType(); while (eventType != XmlPullParserEND_DOCUMENT) { switch (eventType) { case XmlPullParserSTART_DOCUMENT: map = new HashMap<String, String>(); break; case XmlPullParserSTART_TAG: String key = pullParsergetName(); if (keyequals("xml")) break; String value = pullParsernextText(); maput(key, value); break; case XmlPullParserEND_TAG: break; } eventType = pullParsernext(); } return map; } }4. H5 payment
H5 payment is actually very simple. You only need to call the js method of the WeChat embedded browser (http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=7_7)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="spring" uri="http://wwwspringframeworkorg/tags" %> <% String path = requestgetContextPath(); String basePath = requestgetScheme() + "://" + requestgetServerName() + ":" + requestgetServerPort() + path + "/"; %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 01 Transitional//EN" "http://wwworg/TR/html4/loosedtd"> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=0, maximum-scale=0, user-scalable=0" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" /> <meta name="format-detection" content="telephone=no" /> <title>Test payment</title> <link href="/css/csss?v=0" rel="stylesheet" type="text/css"> </head> <body> <div> <div> WeChat js payment test</div> <div> <ul> <li><span>Test payment information</span></li> </ul> <p><a href="javascript:pay();">Pay now</a></p> </div> </div> <script type="text/javascript" src="/js/zeptominjs"></script> <script type="text/javascript" src="/js/commonjs"></script> <script type="text/javascript"> var appId = urlparameter("appId"); var timeStamp = urlparameter("timeStamp"); var nonceStr = urlparameter("nonceStr"); var pg = urlparameter("pg"); var signType = urlparameter("signType"); var paySign = urlparameter("paySign"); function onBridgeReady(){ WeixinJSBridgeinvoke( 'getBrandWCPayRequest', { "appId" : appId, //The name of the official account, passed in "timeStamp": timeStamp, //Timestamp, number of seconds since 1970 "nonceStr" : nonceStr, //Random string "package" : "prepay_id=" + pg, "signType" : signType, //WeChat signature method: "paySign" : paySign //WeChat signature}, function(res){ if(reserr_msg == "get_brand_wcpay_request:ok" ) { alert("Pay Successful"); } // Use the above method to judge the front-end return. The WeChat team solemnly reminds: reserr_msg will return ok after the user's payment is successful, but it does not guarantee that it is absolutely reliable. } ); } function pay(){ if (typeof WeixinJSBridge == "undefined"){ if( documentaddEventListener ){ documentaddEventListener('WeixinJSBridgeReady', onBridgeReady, false); }else if (documentattachEvent){ documentattachEvent('WeixinJSBridgeReady', onBridgeReady); documentattachEvent('onWeixinJSBridgeReady', onBridgeReady); } }else{ onBridgeReady(); } } </script> </body> </html> The effect is as follows
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.