أصبحت مدفوعات WeChat أكثر شيوعًا الآن ، وهناك العديد من المنتجات التي يمكنها الوصول بسرعة إلى دفع WeChat. ومع ذلك ، بالإضافة إلى كوننا مريحًا ، فإنه يجعلنا نعتمد تدريجياً على أطراف ثالثة للقيام بالأشياء وفقدان القدرة على التفكير بشكل مستقل. هذه المرة ، نخطط لمشاركة دفعة WeChat التي طورتها من قبل.
1. دفع الحساب الرسمي H5
النقاط الرئيسية: الحصول على OpenID بشكل صحيح وتوحيد الواجهة الفردية ، وعملية الإشعارات بشكل صحيح ، وتكوين دليل ترخيص الدفع بشكل صحيح
طريقة الدفع لـ H5 هي طريقة تستخدم على نطاق واسع. تستخدم طريقة الدفع هذه بشكل أساسي لصفحات الويب مع قوائم مخصصة في WeChat. يعتمد على عميل WeChat المثبت على الهاتف المحمول. إصدارات أعلى فقط من WeChat تدعم مدفوعات WeChat. يرجى ملاحظة التعليمات التالية لاتباع عملي.
1. اكتب صفحة للدفع ، لأنها اختبار ، فهي أبسط قليلاً.
<٪@ page language = "java" import = "java.util.*" pageencoding = "utf-8" ٪> <٪ string path = request.getContextPath () ؛ String BasePath = request.getScheme ()+": //"+request.getServerName ()+":"+request.getServerPort ()+path+"/" ؛ ٪> <! doctype html public "-// w3c // dtd html 4.01 transitional // en"> <html> <head> <base href = "<٪ = basepath>"> <title> مثال على الدفع wechat </title> <!-<link rel = "stylesheet" type = "text/css" href = "styles.css">-> </head> <body> <form action = "oauthServlet" method = "post"> number: <input type = "text" name = "orderno" Action = "scancodepayservlet؟ flag = createCode" method = "post"> رقم الطلب: <input type = "text" name = "orderno"/> <input type = "submit" value = "مسح الرمز للدفع"/> </form> </body> </html>
2 اكتب servlet للحصول على الكود من خلال Oauth
حزمة com.debug.weixin.servlet ؛ استيراد java.io.ioException ؛ استيراد java.io.printwriter ؛ استيراد javax.servlet.requestDispatcher ؛ استيراد javax.servlet.servletexception ؛ استيراد javax.servlet.http.httpservlet ؛ استيراد javax.servlet.http.httpservletrequest ؛ استيراد javax.servlet.http.httpservletresponse ؛ استيراد com.debug.weixin.util.commonutil ؛ استيراد com.debug.weixin.util.serverConfig ؛ الطبقة العامة OauthServlet يمتد httpservlet {public void doget (httpservletrequest request ، httpservletresponse) يلقي servletexception ، ioException {this.dopost (request ، response) ؛ } public void dopost (httpservletRequest request ، httpservletresponse) يلقي servletexception ، ioException {string orderno = request.getParameter ("orderno") ؛ // استدعاء WeChat Oauth2.0 للحصول على redirecturl سلسلة مفتوحة = serverConfig.ServerDomain+"/basicweixin/payservletforh5؟ orderno ="+orderno ؛ string redirecturi = "" ؛ حاول {redirecturi = commonutil.initopenid (redirecturl) ؛ } catch (استثناء e) {// todo catch e.printstacktrace () ؛ } //system.out.println(redirecturi) ؛ // requestDispatcher dis = request.getRequestDispatcher (redirecturi) ؛ //dis.forward(request ، الرد) ؛ استجابة. }} 3 بعد الحصول على الكود ، احصل
حزمة com.debug.weixin.servlet ؛ استيراد java.io.ioException ؛ استيراد java.io.printwriter ؛ استيراد java.util.sortedMap ؛ استيراد java.util.treemap ؛ استيراد javax.servlet.requestDispatcher ؛ استيراد javax.servlet.servletexception ؛ استيراد javax.servlet.http.httpservlet ؛ استيراد javax.servlet.http.httpservletrequest ؛ استيراد javax.servlet.http.httpservletresponse ؛ استيراد com.debug.weixin.pojo.weixinoauth2token ؛ استيراد com.debug.weixin.pojo.weixinqrcode ؛ استيراد com.debug.weixin.util.advancedutil ؛ استيراد com.debug.weixin.util.commonutil ؛ استيراد com.debug.weixin.util.configutil ؛ استيراد com.debug.weixin.util.paycommonutil ؛ يمتد Payservletforh5 من الفئة العامة httpservlet {public void dogge (httpservletrequest request ، httpservletresponse) يلقي servletexception ، ioException {this.dopost (request ، response) ؛ } public void dopost (httpservletRequest request ، httpservletresponse) يلقي servletexception ، ioException {string orderno = request.getParameter ("orderno") ؛ رمز السلسلة = request.getParameter ("رمز") ؛ // احصل على AccessToken Weixinoauth2Token Token = AdvancedUtil.getoauth2AccessToken (configutil.appid ، configutil.app_secrect ، الكود) ؛ String OpenId = token.getopenid () ؛ // استدعاء واجهة الدفع الموحد weChat sortedMap <object ، object> parameters = new Treemap <object ، Object> () ؛ المعلمات. المعلمات. Parameters.put ("device_info" ، "1000") ؛ المعلمات. المعلمات. parameters.put ("out_trade_no" ، orderno) ؛ //parameters.put("total_fee "، string.valueof (total)) ؛ Parameters.put ("Total_fee" ، "1") ؛ parameters.put ("spbill_create_ip" ، request.getRemoteadDr ()) ؛ المعلمات. المعلمات. المعلمات. علامة سلسلة = payCommonutil.createsign ("UTF-8" ، المعلمات) ؛ parameters.put ("علامة" ، علامة) ؛ requestxml string = payCommonUtil.getRequestxMl (المعلمات) ؛ String result = commonutil.httpsRequestForStr (configutil.unified_order_url ، "post" ، requestxml) ؛ System.out.println ("------------------------------------") ؛ System.out.println (نتيجة) ؛ System.out.println ("------------------------------------") ؛ request.setattribute ("orderno" ، orderno) ؛ request.setattribute ("TotalPrice" ، "0.01") ؛ سلسلة payjson = "" ؛ حاول {payjson = commonutil.geth5paysstr (النتيجة ، طلب) ؛ } catch (استثناء e) {// todo catch e.printstacktrace () ؛ } //system.out.println(payjson) ؛ request.setAttribute ("unifyorder" ، payjson) ؛ requestDispatcher dis = request.getRequestDispatcher ("h5pay.jsp") ؛ dis.forward (طلب ، استجابة) ؛ }} يتطلب استدعاء WeChat لتوحيد واجهة واحدة الانتباه إلى خوارزمية التوقيع. فقط عندما يكون حساب التوقيع صحيحًا ، يمكن أن يكون الدفع بسلاسة
السلسلة الثابتة العامة geth5paysstr (نتيجة السلسلة ، طلب httpservletrequest) يلقي الاستثناء {map <string ، string> map = xmlutil.doxmlparse (النتيجة) ؛ sortedMap <object ، object> params = new treemap <object ، object> () ؛ params.put ("appid" ، configutil.appid) ؛ params.put ("timestamp" ، long.toString (Date (). GetTime ())) ؛ params.put ("noncester" ، paycommonutil.createnoncester ()) ؛ params.put ("package" ، "prepay_id ="+map.get ("prepay_id")) ؛ params.put ("signtype" ، configutil.sign_type) ؛ سلسلة paysign = payCommonutil.createsign ("UTF-8" ، params) ؛ params.put ("paysign" ، paysign) ؛ . إرجاع JSON ؛ } 4 اكتب واجهة الدفع النهائية لضبط الدفع WeChat H5
<٪@ page language = "java" import = "java.util.*" pageencoding = "utf-8" ٪> <٪ string path = request.getContextPath () ؛ String BasePath = request.getScheme ()+": //"+request.getServerName ()+":"+request.getServerPort ()+path+"/" ؛ ٪> <! doctype html public "-// w3c // dtd html 4.01 Transitional // en"> <html> <head> <base href = "<٪ = basepath>"> <title> wechat h5 payment </title> <script type = "text/javaScript"> function jsapicall () {weixinjsbridge.invoke ('getBrandwCpayRequest' ، <٪ = (string) request.getAttribute ("endipleorder") ٪> ، function (res) {weixinjsbridge.log (res.err_msg) ؛ //alert(r_code. } وظيفة callPay () {if (typeof weixinjsbridge == "undefined") {if (document.addeventListener) {document.addeventListener ('weixinjsbridgeready' ، jsapicall ، false) ؛ } if if (document.attachevent) {document.attachevent ('Weixinjsbridgeready' ، jsapicall) ؛ document.attachevent ('onweixinjsbridgeready' ، jsapicall) ؛ }} else {jsapicall () ؛ }} </script> </head> <body> <input type = "button" value = "pay" onClick = "CallPay ()"/> </body> </html> 5. معالجة إشعار نتائج دفع WeChat
حزمة com.debug.weixin.servlet ؛ استيراد java.io.bytearrayoutputstream ؛ استيراد java.io.ioException ؛ استيراد java.io.inputstream ؛ استيراد java.io.printwriter ؛ استيراد java.util.map ؛ استيراد javax.servlet.servletexception ؛ استيراد javax.servlet.http.httpservlet ؛ استيراد javax.servlet.http.httpservletrequest ؛ استيراد javax.servlet.http.httpservletresponse ؛ استيراد org.jdom.jdomexception ؛ استيراد com.debug.weixin.util.paycommonutil ؛ استيراد com.debug.weixin.util.xmlutil ؛ يمتد payhandlerservlet من الفئة العامة httpservlet {public void dogge (httpservletrequest request ، httpservletresponse) يلقي servletexception ، ioexception {this.dopost (request ، response) ؛ } public void dopost (httpservletrequest request ، httpservletponse respress) يلقي servletexception ، ioException {inputStream instream = request.getInputStream () ؛ bytearrayoutputstream outSteam = جديد bytearrayoutputStream () ؛ Byte [] Buffer = New Byte [1024] ؛ int len = 0 ؛ بينما ((len = instream.read (buffer))! = -1) {outsteam.write (buffer ، 0 ، len) ؛ } outsteam.close () ؛ instream.close () ؛ String Result = new String (OutSteam.tobyTearray () ، "UTF-8") ؛ // احصل على معلومات الإرجاع الخاصة بـ WeChat استدعاء خريطة inform_url <object ، كائن> خريطة = null ؛ حاول {map = xmlutil.doxmlparse (النتيجة) ؛ } catch (jdomexception e) {// todo catch catch e.printstacktrace () ؛ } لـ (Object keyvalue: map.keyset ()) {system.out.println (keyvalue+"="+map.get (keyvalue)) ؛ } if (map.get ("result_code"). toString (). equalsignoreCase ("success")) {// العمليات التجارية على النظام system.out.println ("------------------------- OK") ؛ Response.getWriter (). الكتابة (paycommonutil.setxml ("النجاح" ، "")) ؛ // أخبر خادم WeChat أنني تلقيت الرسالة ، لا تتصل بعملية رد الاتصال}}}} بالنسبة للرمز أعلاه ، يشير الكثير منهم إلى http://blog.csdn.net/u011160656/article/details/41759195 ، لذلك لن يتم نشر هذا الجزء من الرمز. إذا كنت في حاجة إليها ، فستعرف ذلك من خلال قراءة هذه المدونة.
2. رمز مسح WeChat للدفع (الوضع 1)
نقاط المفاتيح: يجب عليك الاتصال بالرابط الطويل إلى واجهة الارتباط القصيرة وتكوين رمز المسح بشكل صحيح لدفع عنوان URL للاستدعاء
1 قم بإنشاء رمز الاستجابة السريعة للدفعة WeChat بناءً على رقم الطلب
فيما يلي بعض الطرق لتوليد رموز QR:
حزمة com.debug.weixin.util ؛ استيراد com.google.zxing.common.bitmatrix ؛ استيراد javax.imageio.imageio ؛ استيراد java.io.file ؛ استيراد java.io.outputStream ؛ استيراد java.io.ioException ؛ استيراد java.awt.image.bufferedImage ؛ Public Class Class MatrixtoImageWriter {Private Static Final Int Black = 0xFF000000 ؛ استاتيكي خاص نهائي int white = 0xfffffff ؛ MatrixToImageWriter () {} الثابتة العامة bufferedimage tobufferedimage (مصفوفة bitmatrix) {int width = matrix.getWidth () ؛ ارتفاع int = matrix.getheight () ؛ صورة bufferedImage = جديد bufferedImage (العرض ، الارتفاع ، bufferedImage.type_int_rgb) ؛ لـ (int x = 0 ؛ x <width ؛ x ++) {for (int y = 0 ؛ y <height ؛ y ++) {image.setrgb (x ، y ، matrix.get (x ، y)؟ Black: White) ؛ }} صورة الإرجاع ؛ } public static void writeTofile (مصفوفة bitmatrix ، تنسيق السلسلة ، ملف الملف) يلقي ioException {bufferedImage Image = tobufferedImage (matrix) ؛ if (! imageio.write (صورة ، تنسيق ، ملف)) {رمي ioException جديد ("لا يمكن كتابة صورة للتنسيق" + format + "إلى" + file) ؛ }} public static void writeToStream (مصفوفة bitmatrix ، تنسيق السلسلة ، دفق outputstream) يلقي ioexception {bufferedImage Image = tobufferedImage (matrix) ؛ if (! imageio.write (صورة ، تنسيق ، دفق)) {رمي ioException جديد ("لا يمكن كتابة صورة للتنسيق" + تنسيق) ؛ }}} هذه فئة أدوات ، وهناك طريقة أخرى لعرض رمز الاستجابة السريعة على الواجهة. يستخدم CreateQRcode بشكل أساسي كتل التعليمات البرمجية:
public static void createCodeStream (نص السلسلة ، استجابة httpservletresponse) يلقي الاستثناء {// reponse.setContentType ("Image/JPEG") ؛ servleToutPutStream SOS = response.getOutputStream () ؛ عرض int = 500 ؛ ارتفاع int = 500 ؛ // QR Code Image Format Format Torting = "JPG" ؛ multiformatwriter multiformatwriter = new multiformatwriter () ؛ تلميحات الخريطة = new hashmap () ؛ // تلميحات مشفرة (encodehinttype.character_set ، "utf-8") ؛ bitmatrix bitmatrix = multiformatwriter.encode (نص ، barcodeformat.qr_code ، العرض ، الارتفاع ، تلميحات) ؛ // إنشاء رمز QR MatrixToImageWriter.WritetoStream (Bitmatrix ، Format ، SOS) ؛ sos.close () ؛ } 2. لتحويل الروابط الطويلة إلى روابط قصيرة لإنشاء رموز QR ، اكتب طريقة رد اتصال دفع رمز المسح واتصل بالواجهة الفردية الموحدة
حزمة com.debug.weixin.servlet ؛ استيراد java.io.bytearrayoutputstream ؛ استيراد java.io.ioException ؛ استيراد java.io.inputstream ؛ استيراد java.io.printwriter ؛ استيراد java.util.date ؛ استيراد java.util.map ؛ استيراد java.util.sortedMap ؛ استيراد java.util.treemap ؛ استيراد javax.servlet.servletexception ؛ استيراد javax.servlet.http.httpservlet ؛ استيراد javax.servlet.http.httpservletrequest ؛ استيراد javax.servlet.http.httpservletresponse ؛ استيراد org.jdom.jdomexception ؛ استيراد com.debug.weixin.util.commonutil ؛ استيراد com.debug.weixin.util.configutil ؛ استيراد com.debug.weixin.util.createqrcode ؛ استيراد com.debug.weixin.util.paycommonutil ؛ استيراد com.debug.weixin.util.xmlutil ؛ استيراد com.mongodb.dboBject ؛ الطبقة العامة scancodepayservlet يمتد httpservlet {public void doget (httpservletrequest request ، httpservletresponse) يلقي servletexception ، ioException {this.dopost (request ، response) ؛ } public void dopost (httpservletrequest request ، httpservletresponse) يلقي servletexception ، ioException {string flag = request.getParameter ("flag") ؛ if ("createCode" .equals (flag)) {createPayCode (request ، response) ؛ } else {try {wxscancodehandler (request ، response) ؛ } catch (استثناء e) {// todo catch e.printstacktrace () ؛ }}} public void createPayCode (طلب httpservletrequest ، httpservletresponse استجابة) {string orderno = request.getParameter ("orderno") ؛ sortedMap <object ، object> paras = new treemap <object ، object> () ؛ paras.put ("appid" ، configutil.appid) ؛ paras.put ("MCH_ID" ، configutil.mch_id) ؛ paras.put ("time_stamp" ، long.toString (date (). getTime ())) ؛ paras.put ("nonce_str" ، paycommonutil.createnoncester ()) ؛ paras.put ("product_id" ، orderno) ؛ // يجب أن يكون رقم المنتج علامة سلسلة فريدة = paycommonutil.createsign ("UTF-8" ، Paras) ؛ paras.put ("علامة" ، علامة) ؛ url url = "weixin: // wxpay/bizpayurl؟ sign = sign & appid = appid & mch_id = mchid & product_id = productid & time_stamp = timestamp & nonce_str = nocestr = nocestr" ؛ String nativeUrl = url.replace ("sign" ، sign) .replace ("appid" ، configutil.appid) .replace ("mchid" ، configutil.mch_id) .replace ("productID" ، (string) paras.get ("product_id"). (سلسلة) paras.get ("nonce_str")) ؛ sortedMap <object ، object> parameters = new treemap <object ، Object> () ؛ المعلمات. المعلمات. المعلمات. المعلمات. sign 2 = payCommonutil.createsign ("UTF-8" ، المعلمات) ؛ Parameters.put ("sign" ، sign2) ؛ requestxml string = payCommonUtil.getRequestxMl (المعلمات) ؛ String result = commonutil.httpsRequestForStr (configutil.short_url ، "post" ، requestxml) ؛ الخريطة <string ، string> map = null ؛ حاول {map = xmlutil.doxmlparse (النتيجة) ؛ } catch (jdomexception e) {// todo catch catch e.printstacktrace () ؛ } catch (ioException e) {// todo acto catch block e.printstacktrace () ؛ } string returncode = map.get ("return_code") ؛ String ResultCode = map.get ("result_code") ؛ if (returncode.equalsignorecase ("success") && resultcode.equalsInsIgnoreCase ("success")) {String ShortUrl = map.get ("Short_url") ؛ // todo الحصول على ShortUrl ، اكتب الكود لإنشاء نظام QR System.out.println ("ShortUrl ="+Shorturl) ؛ حاول {createqrcode.createCodeStream (Shorturl ، الاستجابة) ؛ } catch (استثناء e) {// todo catch e.printstacktrace () ؛ }}} public void wxscancodehandler (طلب httpservletrequest ، استجابة httpservletresponse) يلقي الاستثناء {inputStream instream = request.getInputStream () ؛ bytearrayoutputstream outSteam = جديد bytearrayoutputStream () ؛ Byte [] Buffer = New Byte [1024] ؛ int len = 0 ؛ بينما ((len = instream.read (buffer))! = -1) {outsteam.write (buffer ، 0 ، len) ؛ } outsteam.close () ؛ instream.close () ؛ String Result = new String (OutSteam.tobyTearray () ، "UTF-8") ؛ // احصل على معلومات الإرجاع الخاصة بـ WeChat استدعاء خريطة inform_url <object ، كائن> خريطة = null ؛ حاول {map = xmlutil.doxmlparse (النتيجة) ؛ } catch (jdomexception e) {// todo catch catch e.printstacktrace () ؛ } لـ (Object keyvalue: map.keyset ()) {system.out.println (keyvalue+"="+map.get (keyvalue)) ؛ } string orderno = map.get ("product_id"). toString () ؛ // بعد تلقي معلمة الطلب ، اتصل بالواجهة الفردية الموحدة SortedMap <Object ، Object> Parameters = New Treemap <Object ، Object> () ؛ المعلمات. المعلمات. Parameters.put ("device_info" ، "1000") ؛ المعلمات. المعلمات. Parameters.put ("Out_trade_no" ، map.get ("product_id")) ؛ //parameters.put("total_fee "، string.valueof (TotalPrice)) ؛ Parameters.put ("Total_fee" ، "1") ؛ parameters.put ("spbill_create_ip" ، request.getRemoteadDr ()) ؛ المعلمات. المعلمات. المعلمات. علامة سلسلة = payCommonutil.createsign ("UTF-8" ، المعلمات) ؛ parameters.put ("علامة" ، علامة) ؛ requestxml string = payCommonUtil.getRequestxMl (المعلمات) ؛ string result2 = commonutil.httpsRequestForStr (configutil.unified_order_url ، "post" ، requestxml) ؛ System.out.println ("----------------------------- 统一下单结果 -------------------------------") ؛ system.out.println (result2) ؛ الخريطة <string ، string> mm = null ؛ حاول {mm = geth5paymap (result2 ، request) ؛ } catch (استثناء e) {// todo catch e.printstacktrace () ؛ } // string prepayid = getPrepayId (result2 ، request) ؛ // string returnnonestr = getReturnNonester (result2 ، request) ؛ String prepayid = mm.get ("prepay_id") ؛ String ReturnNonester = mm.get ("nonce_str") ؛؛ sortedMap <object ، object> lastSign = new treemap <object ، object> () ؛ LastSign.put ("return_code" ، "النجاح") ؛ lastSign.put ("appid" ، configuTil.appid) ؛ LastSign.put ("mch_id" ، configuTil.mch_id) ؛ lastsign.put ("nonce_str" ، returnnonester) ؛ LastSign.put ("prepay_id" ، prepayid) ؛ LastSign.put ("result_code" ، "Success") ؛ LastSign.put ("Key" ، configutil.api_key) ؛ String lastSignPara = paycommonutil.createsign ("UTF-8" ، LastSign) ؛ StringBuffer buf = new StringBuffer () ؛ buf.append ("<xml>") ؛ buf.append ("<return_code> النجاح </return_code>") ؛ buf.append ("<AppID>"+configutil.appid+"</appid>") ؛ buf.append ("<mch_id>"+configutil.mch_id+"</mch_id>") ؛ buf.append ("<mch_id>"+configutil.mch_id+"</mch_id>") ؛ buf.append ("<nonce_str>"+returnnonester+"</nunce_str>") ؛ buf.append ("<prepay_id>"+prepayid+"</prepay_id>") ؛ buf.append ("<drege_code> النجاح </result_code>") ؛ buf.append ("<sign>"+lastSignPara+"</sign>") ؛ buf.append ("</xml>") ؛ desponse.getWriter (). print (buf.ToString ()) ؛ } الخريطة العامة <string ، string> geth5paymap (نتيجة السلسلة ، طلب httpservletrequest) يلقي الاستثناء {map <string ، string> map = xmlutil.doxmlparse (result) ؛ خريطة العودة }}أخيرًا ، دعونا نلقي نظرة على تكوين WeChat لدفع الحساب الرسمي ودفع رمز المسح الضوئي:
آمل أنه من خلال هذه المقالة ، يمكن للجميع أن يفهموا أنه حتى إذا كنت تستخدم Java لجعل WeChat Public Accounts و Wechat الدفع دون استخدام رمز الغش الذي توفره Github ، فيمكنك تطوير تطبيقات WeChat التي ترضي عليك وعملائك. على الرغم من أن العروض التوضيحية التي قدمها WeChat كلها PHP ، إلا أنها كلها سحب. لغة التطوير هي الثانية ، وفهم الطبقة الأساسية التي تتطلبها مكالمات الواجهة ليست سوى مسار إلزامي للمبرمجين.