เมื่อเร็ว ๆ นี้โครงการต้องการการชำระเงิน WeChat จากนั้นฉันก็ดูการชำระเงินอย่างเป็นทางการของ WeChat แม้ว่ามันจะไม่ยาก แต่รายละเอียดก็ยังต้องให้ความสนใจ ฉันใช้เวลาส่วนใหญ่ในการเขียนตัวอย่างและทดสอบกระบวนการชำระเงินอย่างสมบูรณ์ มาแบ่งปันประสบการณ์การชำระบัญชีอย่างเป็นทางการของ WeChat ด้านล่าง
1. กำหนดค่าบัญชีอย่างเป็นทางการการชำระเงิน weChat
เราจำเป็นต้องกำหนดค่าที่อยู่บัญชีอย่างเป็นทางการของ WeChat และทดสอบ whitelist
ตัวอย่างเช่นที่อยู่ของหน้าการชำระเงิน JS คือ http://www.xxx.com/shop/pay/
จากนั้นที่นี่ได้รับการกำหนดค่า www.xxx.com/shop/pay/
2. กระบวนการพัฒนา
ยืมบัญชีอย่างเป็นทางการของ WeChat เพื่อชำระค่า API (ที่อยู่ http://pay.weixin.qq.com/wiki/doc/api/index.php?Chapter=7_4) ซึ่งเราต้องพัฒนามีการทำเครื่องหมายเป็นสีแดง ดังนี้:
3. สั่งซื้อด้วยเซิร์ฟเวอร์ WeChat
โทรหาอินเทอร์เฟซเดี่ยวแบบรวมเพื่อให้คุณได้รับการชำระเงินล่วงหน้าของ WeChat (http://pay.weixin.qq.com/wiki/doc/api/index.php?Chapter=9_1)
ก่อนที่จะเรียกอินเทอร์เฟซนี้มีหลายฟิลด์ที่เป็น OpenID ที่ต้องกรอกสำหรับการชำระเงิน H5
3.1 รับ OpenId
คุณสามารถใช้แบบฟอร์มการอนุญาตเว็บ (http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html)
ส่งลิงค์ต่อไปนี้ใน WeChat
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=url&response_type=code&scope=snsapi_base&state=123#wechat_type
3.2 สั่งซื้อเพื่อรับ prepay_id
รหัสมีดังนี้ซึ่งจริง ๆ แล้วส่งไฟล์ XML ผ่านโพสต์เพื่อรับ prepay_id ที่ส่งจากเซิร์ฟเวอร์ WeChat
นำเข้า Java.io.ByTearrayInputStream; นำเข้า JavaioioException; นำเข้า JavaioInputStream; นำเข้า JavaiounsupportencodingException; นำเข้า Javautildate; นำเข้า Javautilhashmap; นำเข้า Javautiliterator; นำเข้า JavautilMap; นำเข้า Javautilmapentry; นำเข้า Javautilrandom; นำเข้า JavaxservlethtttPhttpservletRequest; นำเข้า JavaxservlethtttpttpservletResponse; นำเข้า orgapacheCommonScodecDigestDigestUtils; นำเข้า orgspringframeworkstereotypecontroller; นำเข้า orgspringframeworkwebbindannotationRequestmapping; นำเข้า orgxmlpullvxmlpullparser; นำเข้า orgxmlpullvxmlpullparserexception; นำเข้า orgxmlpullvxmlpullparserfactory; นำเข้า comfasterxmljacksondatabindjsonnode; นำเข้า comgsonoauthoauth; นำเข้า comgsonoauthpay; นำเข้า comgsonutilhttpkit; นำเข้า ComsyutildateTimeutil; นำเข้า comsyutiljsonutil; @Controller @requestmapping ("/pay") คลาสสาธารณะ wxpaycontroller {@requestmapping (value = "wxprepaydo") โมฆะสาธารณะ jspay (httpservletrequest คำขอ httpservletResponse, การเรียกสตริง if (openId == null) {openId = getUserOpenid (คำขอ); } string appid = "WX16691FCB0523C1A4"; สตริง paternerkey = "iningfeng1234567fdfwfdfd1ss234567"; String out_trade_no = getTradeno (); แผนที่ <string, string> paramap = new hashmap <string, string> (); paramapput ("appid", appid); paramapput ("แนบ", "ทดสอบ"); paramapput ("ร่างกาย", "การชำระเงินซื้อทดสอบ"); 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 (คำขอ)); 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 url url = "https: // apimchweixinqqcom/pay/Unifiedorder"; สตริง xml = arraytoxml (paramap); สตริง xmlstr = httpkitpost (url, xml); // id ผลิตภัณฑ์ล่วงหน้าสตริง prepay_id = ""; if (xmlstrindexof ("ประสบความสำเร็จ")! = -1) {แผนที่ <สตริง, สตริง> map = doxmlparse (xmlstr); prepay_id = (สตริง) mapget ("prepay_id"); } แผนที่ <สตริง, สตริง> paymap = new hashmap <string, string> (); Paymapput ("appid", appid); Paymapput ("timestamp", create_timestamp ()); paymapput ("noncestr", create_nonce_str ()); Paymapput ("SignType", "MD5"); paymapput ("แพ็คเกจ", "prepay_id =" + prepay_id); สตริง paysign = getSign (paymap, paternerkey); Paymapput ("PG", PREPEL_ID); Paymapput ("Paysign", Paysign); WebUtilResponse (การตอบสนอง, WebUtIlPackJSONP (การโทรกลับ, JSONUTILWARPJSONNODERESPONSE (JSONUTILOBJECTTOJSONNODE (PAYMAP)) TOSTRING ()); } / ** * แผนที่เป็น XML * * @Param arr * @return * / สตริงสาธารณะ arraytoxml (แผนที่ <สตริง, สตริง> arr) {string xml = "<xml>"; Iterator <entry <string, string >> iter = arrentryset () iterator (); ในขณะที่ (iterhasNext ()) {entry <string, string> entry = iternext (); คีย์สตริง = entryGetKey (); String val = entrygetValue (); xml + = "<" + คีย์ + ">" + val + "</" + คีย์ + ">"; } xml += "</xml>"; กลับ XML; } // รับ OpenId Private String getUserOpenId (คำขอ httpservletRequest) โยนข้อยกเว้น {String code = requestgetParameter ("รหัส"); if (code == null) {string openId = requestgetParameter ("openId"); กลับ OpenId; } oauth o = new oauth (); สตริงโทเค็น = ogetToken (รหัส); jsonNode node = jsonutilStringtoJsonNode (โทเค็น); string openId = nodeGet ("openId") astext (); กลับ OpenId; } สตริงส่วนตัว create_nonce_str () {string chars = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789"; สตริง res = ""; สำหรับ (int i = 0; i <16; i ++) {random rd = new random (); res += charscharat (rdnextint (charslength () - 1)); } return res; } สตริงส่วนตัว getAddRip (คำขอ httpservletRequest) {return requestgetRemoteaddr (); } สตริงส่วนตัว create_timestamp () {return longtoString (SystemCurrentTimeMillis () / 1000); } สตริงส่วนตัว getTradeno () {สตริง timestamp = datetimeutilformatdate (วันที่ใหม่ (), datetimeutildatetime_pattern); กลับ "HZNO" + การประทับเวลา; } สตริงส่วนตัว getSign (แผนที่ <สตริง, สตริง> พารามิเตอร์, สตริง paternerkey) พ่น unsupportencodingexception {string string1 = paycreatesign (params, false); strings stringsignTemp = string1 + "& key =" + paternerkey; String signValue = DigestUtilSMD5HEX (stringsignTemp) touppercase (); ส่งคืน signvalue; } แผนที่ส่วนตัว <สตริง, สตริง> doxmlParse (สตริง xml) พ่น XMLPULLPARSERException, iOException {inputStream inputStream = new ByTeArrayInputStream (XMLGETBYTES ()); แผนที่ <สตริงสตริง> แผนที่ = null; XMLPULLPARSER PULLPARSER = XMLPULLPARSERFACTORYNEWINSTANCE () nEWPULLPARSER (); PullParsersetInput (InputStream, "UTF-8"); // ตั้งค่าข้อมูล XML ที่จะแยกวิเคราะห์สำหรับ XML Int EventType = PullParSerGetEventType (); ในขณะที่ (EventType! = XMLPULLPARSEREND_DOCUMENT) {SWITCH (EventType) {CASE XMLPULLPARSERSERSERSTART_DOCUMENT: MAP = ใหม่ HASHMAP <String, String> (); หยุดพัก; กรณี XMLPULLPARSERSERSERSTART_TAG: คีย์สตริง = PULLPARSERGETNAME (); if (keyequals ("xml")) break; ค่าสตริง = pullParSerNExtText (); Maput (คีย์, ค่า); หยุดพัก; กรณี XMLPULLPARSEREND_TAG: BREAK; } EventType = PullParserNext (); } กลับแผนที่; -4. การชำระเงิน H5
การชำระเงิน H5 นั้นง่ายมาก คุณจะต้องโทรหาวิธีการ JS ของเบราว์เซอร์ WeChat Embedded (http://pay.weixin.qq.com/wiki/doc/api/index.php?Chapter=7_7)
<%@ page language = "java" contentType = "ข้อความ/html; charset = utf-8" pageencoding = "utf-8"%> <%@ taglib prefix = "Spring" uri = "http: // wwspringframeworkorg/tags" String basepath = requestgetScheme () + ": //" + requestgetServerName () + ":" + requestgetServerport () + path + "/"; %> <! doctype html public "-// w3c // dtd html 01 transitional // en" "http: // wwworg/tr/html4/loosedtd"> <html> <head> maximum-scale = 0, user-scalable = 0 " /> <meta name =" Apple-Mobile-Web-App-App-App-App-Apple "เนื้อหา =" ใช่ " /> <meta name =" Apple-Mobile-Web-app-status-bar-bar-bar-bar-bar-bar-bar " content = "โทรศัพท์ = no"/> <title> การชำระเงินการทดสอบ </title> <link href = "/css/csss? v = 0" rel = "stylesheet" type = "text/css"> </head> <body> <div> <div> href = "javascript: pay ();"> จ่ายทันที </a> </p> </div> </div> <script type = "text/javascript" src = "/js/zeptominjs"> </script> <script type = "text/javascript urlParameter ("appid"); var timestamp = urlParameter ("timestamp"); var noncestr = urlParameter ("noncestr"); var pg = urlParameter ("pg"); var signType = urlParameter ("signType"); var paysign = urlParameter ("paysign"); ฟังก์ชั่น onbridgeready () {weixinjsbridgeinvoke ('getBrandWcPayRequest', {"appid": appid, // ชื่อของบัญชีอย่างเป็นทางการผ่าน "timestamp": timestamp, // timestamp, จำนวนวินาทีตั้งแต่ปี 1970 SignType, // WeChat Signature Method: "Paysign": Paysign // WeChat Signature}, ฟังก์ชั่น (res) {ถ้า (reserr_msg == "get_brand_wcpay_request: ตกลง" ประสบความสำเร็จ แต่ไม่รับประกันว่าจะเชื่อถือได้อย่างแน่นอน}); } function pay () {ถ้า (typeof weixinjsbridge == "undefined") {ถ้า (documentaddeventListener) {documentaddeventListener ('weixinjsbridgeready', onbridgeready, false); } อื่นถ้า (DocumentAttacheVent) {DocumentattacheVent ('Weixinjsbridgeready', onbridgeready); Documentattachevent ('onweixinjsbridgeready', onbridgeready); }} else {onbridgeready (); }} </script> </body> </html> เอฟเฟกต์มีดังนี้
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น