Die WeChat -Zahlung ist jetzt immer beliebter geworden, und es gibt viele Produkte, die schnell auf WeChat -Zahlungen zugreifen können. Zusätzlich zu bequemer ist es uns jedoch auch, dass wir uns auch allmählich auf Dritte verlassen, um Dinge zu tun und die Fähigkeit zu verlieren, unabhängig zu denken. Dieses Mal planen wir, die zuvor entwickelte WeChat -Zahlung zu teilen.
1. H5 Offizielle Kontozahlung
Schlüsselpunkte: Erhalten Sie OpenID korrekt und vereinen Sie die einzelne Schnittstelle, verarbeiten Sie die Zahlungsergebnisbenachrichtigungen korrekt und konfigurieren Sie das Zahlungsautorisierungsverzeichnis korrekt
Die Zahlungsmethode von H5 ist eine weit verbreitete Methode. Diese Zahlungsmethode wird hauptsächlich für Webseiten mit benutzerdefinierten Menüs in WeChat verwendet. Es stützt sich auf den auf dem Mobiltelefon installierten WeChat -Client. Nur höhere Versionen von WeChat unterstützen WeChat -Zahlung. Bitte beachten Sie die folgenden Anweisungen, um meinen Prozess zu befolgen.
1. Schreiben Sie eine Seite zur Zahlung, da es sich um einen Test handelt, es ist etwas einfacher.
<%@ page Language = "java" import = "java.util. String basepath = request.getScheme ()+": //"+request.getSerVername ()+":"+request.getServerport ()+path+"/"; %> <! DocType html public "-// w3c // dtd html 4.01 transitional // en"> <html> <head> <base href = "<%= Basepath%>"> <Titel> WeChat-Zahlungsbeispiel </title> <meta name = "viewport" content = "widdh. <!-<link rel = "styleSheet" type = "text/css" href = "styles.css">-> </head> <body> <Form Action = "oAuthServlet" methode = "post"> Bestellnummer: <Eingabe type = "text" name = "orderno"/> </BR> <Flody = "Form". action = "scancodepayServlet? Flag = createCode" method = "post"> Order -Nummer: <Eingabe type = "text" name = "orderno"/> <input type = "value =" scannen Sie den Code zu bezahlen "/> </Form> </body> </html>>
2 Schreiben Sie einen Servlet, um Code über OAuth zu erhalten
Paket com.debug.weixin.servlet; importieren java.io.ioException; Import Java.io.printwriter; importieren javax.servlet.requestDispatcher; importieren javax.servlet.servletException; import Javax.servlet.http.httpServlet; importieren javax.servlet.http.httpServletRequest; importieren javax.servlet.http.httpServletResponse; import com.debug.weixin.util.commonutil; import com.debug.weixin.util.serverconfig; public class oAuthServlet erweitert HttpServlet (public void dodget (httpServletRequest Request, httpServletResponse -Antwort). } public void dopost (httpServletRequest Request, httpServletResponse -Antwort) löst ServletException aus, ioException {String orderNo = request.getParameter ("orderNo"); // WeChat OAuth2.0 rufen, um openID String reverecturl = serverconfig.serverdomain+"/BasicWeixin/PayServletForH5? Orderno ="+orderno; String recirecturi = ""; try {recirecturi = CommonUtil.initopenid (recirecturl); } catch (Ausnahme e) {// Todo automatisch generierter Block E. printstacktrace (); } //System.out.println(redirecturi); // RequestDispatcher Dis = Request.GetRequestDispatcher (recirecturi); //dis.forward(Request, Antwort); response.sendredirect (recirecturi); }} 3 Erhalten Sie nach dem Erhalt des Codes OpenID über recirecturi und rufen Sie die einheitliche Einzelschnittstelle auf
Paket com.debug.weixin.servlet; importieren java.io.ioException; Import Java.io.printwriter; Import Java.util.SorteedMap; Import Java.util.Treemap; importieren javax.servlet.requestDispatcher; importieren javax.servlet.servletException; import Javax.servlet.http.httpServlet; importieren javax.servlet.http.httpServletRequest; importieren javax.servlet.http.httpServletResponse; import com.debug.weixin.pojo.weisixinoauth2token; import com.debug.weixin.pojo.weixinqrcode; import com.debug.weixin.util.advancedutil; import com.debug.weixin.util.commonutil; import com.debug.weixin.util.configutil; com.debug.weixin.util.paycommonutil; Die öffentliche Klasse PayServletForH5 erweitert HttpServlet (public void dodget (httpServletRequest Request, httpServletResponse -Antwort). } public void dopost (httpServletRequest Request, httpServletResponse -Antwort) löst ServletException aus, ioException {String orderNo = request.getParameter ("orderNo"); String code = request.getParameter ("Code"); // accessToken wixinoAuth2Token token = Advancedutil.getOAuth2AccessToken (configUtil.appid, configUtil.app_secrekt, Code); String openID = token.getOpenid (); // WeChat Unified Payment Interface sortEdMap <Objekt, Objekt> Parameter = New TREEMAP <Objekt, Objekt> (); Parameter.put ("Appid", configUtil.appid); parameters.put ("mch_id", configUtil.mch_id); Parameter.put ("Device_info", "1000"); Parameter.put ("Körper", "meine Testreihenfolge"); parameters.put ("nonce_str", paycommonutil.createNoncestern ()); parameters.put ("out_trade_no", orderno); //parameters.put("total_fee ", string.valueof (insgesamt)); Parameter.put ("Total_fee", "1"); parameters.put ("SPBILL_CREATE_IP", Request.getRemoteaddr ()); parameters.put ("benachrichtigen_url", configUtil.notify_url); Parameter.put ("Trade_Type", "JSAPI"); Parameter.put ("openID", openID); String Sign = paycommonutil.createSign ("utf-8", Parameter); Parameter.put ("Zeichen", Zeichen); String RequestXML = PayCommonUtil.getRequestXML (Parameter); String result = CommonUtil.httpsRequestforStr (configUtil.unified_order_url, "post", requestXml); System.out.println ("------------------------------"); System.out.println (Ergebnis); System.out.println ("------------------------------"); Request.SetAttribute ("orderno", orderno); Request.SetAttribute ("TotalPrice", "0,01"); String payjson = ""; try {payjson = CommonUtil.geth5Paystr (Ergebnis, Anfrage); } catch (Ausnahme e) {// Todo automatisch generierter Block E. printstacktrace (); } //System.out.println(payjson); request.setAttribute ("Unifiedorder", payjson); RequestDispatcher dis = request.getRequestDispatcher ("H5Pay.jsp"); dis.forward (Anfrage, Antwort); }} Das Aufrufen von WeChat, um eine einzelne Schnittstelle zu vereinen, ist auf den Signaturalgorithmus aufmerksam. Nur wenn die Signaturberechnung korrekt ist, kann die Zahlung reibungslos sein
public static String Geth5Paystr (String -Ergebnis, httpServletRequest -Anforderung) löst Ausnahme aus {map <String, String> map = xmlutil.doxmlParse (Ergebnis); SortEdMap <Objekt, Objekt> params = new TREEMAP <Objekt, Objekt> (); params.put ("Appid", configUtil.appid); params.put ("timestamp", long.toString (neues Datum (). GetTime ())); params.put ("noncest", paycommonutil.createNoncestern ()); params.put ("package", "prepay_id ="+map.get ("prepay_id")); params.put ("SignType", configUtil.sign_type); String paySign = payCommonUtil.CreateSign ("UTF-8", Params); params.put ("paysign", paysign); // Die Erzeugungsregeln von Paysign stimmen mit den Erzeugungsregeln von Sign String json = jsonObject.fromObject (Params) .ToString () überein; Rückkehr JSON; } 4 Schreiben Sie die endgültige Zahlungsschnittstelle, um die Zahlung von WeChat H5 anzupassen
<%@ page Language = "java" import = "java.util. String basepath = request.getScheme ()+": //"+request.getSerVername ()+":"+request.getServerport ()+path+"/"; %> <! DocType html public "-// w3c // dtd html 4.01 transitional // en"> <html> <head> <base href = "<%= Basepath%>"> <Titel> WeChat H5-Zahlung </title> <meta name = "content =" content = "content =" widdh. <script type = "text/javaScript"> Funktion jsapicall () {wixinjsbridge.invoke ('getBrandwcPayRequest', <%= (String) request.getAttribute ("Unifiedorder")%>, Funktion (res) {weixinjsbridge.log (res.err_msg); //alert(res.err_code+Res.err_desc+res.err_msg); } function callpay () {if (typeof weixinjsbridge == "undefined") {if (document.addeventListener) {document.adDeVentListener ('wixinjsbridgeready', jsapicall, false); } else if (document.attachEvent) {document.attachEvent ('wixinjsbridgeready', jsapicall); document.attachEvent ('Onweixinjsbridgeready', jsapicall); }} else {jsapicall (); }} </script> </head> <body> <Eingabe type = "button" value = "pay" onclick = "callpay ()"/> </body> </html> 5. Bearbeitung der WeChat -Zahlungsergebnisbenachrichtigung
Paket com.debug.weixin.servlet; importieren java.io.BytearrayoutputStream; importieren java.io.ioException; importieren java.io.inputstream; Import Java.io.printwriter; import Java.util.map; importieren javax.servlet.servletException; import Javax.servlet.http.httpServlet; importieren javax.servlet.http.httpServletRequest; importieren javax.servlet.http.httpServletResponse; import org.jdom.jdomexception; com.debug.weixin.util.paycommonutil; import com.debug.weixin.util.xmlutil; public class payHandlerServlet erweitert HttpServlet (public void dodget (httpServletRequest request, httpServletResponse -Antwort). } public void dopost (httpServletRequest -Anforderung, httpServletResponse -Antwort) löst ServletException aus, iOException {InputStream instream = request.getInputStream (); BytearrayoutputStream outsteam = new bytearrayoutputStream (); byte [] buffer = neues byte [1024]; int len = 0; while ((len = instrenm.read (puffer))! = -1) {outsteam.write (puffer, 0, len); } outsteam.close (); instream.close (); String result = new String (outsteam.tobytearray (), "utf-8"); // Die Rückgabeinformationen von WeChat erhalten, das unsere Notify_url-Karte <Objekt, Objekt> map = null aufruft; try {map = xmlutil.doxmlParse (Ergebnis); } catch (jdomexception e) {// Todo automatisch generierter Catch-Block e.printstacktrace (); } für (Object KeyValue: map.keyset ()) {System.out.println (KeyValue+"="+map.get (KeyValue)); } if (map.get ("result_code"). toString (). EqualSignoreCase ("Erfolg")) {// Business Operations on Bestellungen System.out.println ("--------------------------- OK"); response.getWriter (). Schreiben (paycommonutil.setXML ("Erfolg", ""); // Sagen Sie dem WeChat -Server, dass ich die Nachricht erhalten habe. Rufen Sie nicht die Callback -Aktion an}}}. Für den obigen Code beziehen sich viele von ihnen auf http://blog.csdn.net/u011160656/article/details/41759195, sodass dieser Teil des Codes nicht veröffentlicht wird. Wenn Sie es brauchen, wissen Sie es, indem Sie diesen Blog lesen.
2. WeChat -Scan -Code zu bezahlen (Modus 1)
Schlüsselpunkte: Sie müssen den langen Link zur kurzen Linkschnittstelle aufrufen und den Scan -Code korrekt konfigurieren, um eine Callback -URL zu bezahlen
1 Generieren Sie den WeChat -Zahlungs -QR -Code basierend auf der Bestellnummer
Hier sind einige Möglichkeiten, QR -Codes zu generieren:
Paket com.debug.weixin.util; import com.google.zxing.common.bitmatrix; import Javax.imageo.imageo; Import Java.io.file; importieren java.io.outputstream; importieren java.io.ioException; Import Java.awt.image.BuffenedImage; public Final Class MatrixtoimageWriter {private statische endgültige int schwarz = 0xff000000; private statische endgültige int weiß = 0xfffffff; private matrixtoimageWriter () {} public static bufferedImage tobedimage (bitmatrix matrix) {int width = matrix.getWidth (); int Höhe = matrix.getheight (); Bufferedimage image = new bufferedImage (width, Höhe, bufferedimage.type_int_rgb); für (int x = 0; x <width; x ++) {für (int y = 0; y <Höhe; y ++) {image.setRGB (x, y, matrix.get (x, y)? schwarz: weiß); }} return Image; } public static void writeToFile (Bitmatrix matrix, String -Format, Dateidatei) löscht IOException {bufferedImage image = tobufedImage (matrix); if (! imageio.write (Bild, Format, Datei)) {Neue IOException ("konnte ein Bild des Formats nicht schreiben" + Format + "to" + Datei); }} public static void writeToStream (Bitmatrix matrix, String -Format, Ausgabestream) löscht IOException {bufferedImage image = tobuffeedImage (matrix); if (! imageio.write (Bild, Format, Stream)) {Neue IOException ("konnte kein Bild des Formats schreiben" + Format); }}} Dies ist eine Werkzeugklasse, und es gibt eine andere Methode, um den QR -Code auf der Schnittstelle anzuzeigen. CreateQrCode verwendet hauptsächlich Codeblöcke:
public static void createCodestream (String -Text, httpServletResponse -Antwort) löst eine Ausnahme aus {// response.setContentType ("Image/jpeg"); ServletoutputStream sos = response.getOutputStream (); int width = 500; int Höhe = 500; // QR Code Bildformat String format = "JPG"; MultiformatWriter multiformatWriter = neuer MultiformatWriter (); MAP Hins = new HashMap (); // die codierten tipps.put (EncodeHintType.character_set, "utf-8"); Bitmatrix bitmatrix = multiformatwriter.encode (text, barcodeFormat.qr_code, Breite, Höhe, Hinweise); // qR -Code matrixtoimageWriter.Writetostream (Bitmatrix, Format, SOS) generieren; sos.close (); } 2. Um lange Links in kurze Links zu konvertieren, um QR -Codes zu generieren, schreiben
Paket com.debug.weixin.servlet; importieren java.io.BytearrayoutputStream; importieren java.io.ioException; importieren java.io.inputstream; Import Java.io.printwriter; import Java.util.date; import Java.util.map; Import Java.util.SorteedMap; Import Java.util.Treemap; importieren javax.servlet.servletException; import Javax.servlet.http.httpServlet; importieren javax.servlet.http.httpServletRequest; importieren javax.servlet.http.httpServletResponse; import org.jdom.jdomexception; import com.debug.weixin.util.commonutil; import com.debug.weixin.util.configutil; import com.debug.weixin.util.createqrcode; com.debug.weixin.util.paycommonutil; import com.debug.weixin.util.xmlutil; import com.mongodb.dbobject; öffentliche Klasse ScancodePayServlet erweitert HttpServlet (public void dodget (httpServletRequest Request, httpServletResponse -Antwort). } public void dopost (httpServletRequest -Anforderung, httpServletResponse -Antwort) löst ServletException aus, IOException {String flag = request.getParameter ("Flag"); if ("createCode" .equals (flag)) {createpayCode (request, Antwort); } else {try {wxScancodeHandler (Anfrage, Antwort); } catch (Ausnahme e) {// Todo automatisch generierter Block E. printstacktrace (); }}} public void createpayCode (httpServletRequest -Anforderung, httpServletResponse -Antwort) {String orderno = request.getParameter ("orderNo"); SortEdMap <Objekt, Objekt> paras = new Treemap <Objekt, Objekt> (); paras.put ("Appid", configUtil.appid); paras.put ("mch_id", configUtil.mch_id); paras.put ("time_stamp", long.toString (neues Datum (). GetTime ())); paras.put ("nonce_str", paycommonutil.createNoncestern ()); paras.put ("product_id", orderno); // Die Produktnummer muss eindeutig String Sign = PayCommonUtil.CreateSsign ("UTF-8", Paras) sein; paras.put ("Zeichen", Zeichen); String url = "wixin: // wxpay/bizpayurl? Sign = sign & appid = appid & mch_id = mchid & product_id = productId & time_stamp = timestamp & nonce_str = nocestry"; String nativeurl = url.replace ("sign", sign) .replace ("Appid", configUtil.appid) .replace ("mchid", configUtil.mch_id) .Replace ("productId", (String) paras.get ("product_id"). Ersetzen. (String) paras.get ("nonce_str")); SortEdMap <Objekt, Objekt> Parameter = New TREEMAP <Objekt, Objekt> (); Parameter.put ("Appid", configUtil.appid); parameters.put ("mch_id", configUtil.mch_id); parameters.put ("nonce_str", paycommonutil.createNoncestern ()); parameters.put ("long_url", Commonutil.urlenCodeutf8 (nativ)); String Sign2 = PayCommonUtil.CreateSign ("UTF-8", Parameter); Parameter.put ("Zeichen", Zeichen2); String RequestXML = PayCommonUtil.getRequestXML (Parameter); String result = CommonUtil.httpsRequestforStr (configUtil.short_url, "post", requestXml); Karte <String, String> map = null; try {map = xmlutil.doxmlParse (Ergebnis); } catch (jdomexception e) {// Todo automatisch generierter Catch-Block e.printstacktrace (); } catch (ioException e) {// Todo automatisch generierter Catch-Block e.printstacktrace (); } String returnCode = map.get ("return_code"); String resultcode = map.get ("result_code"); if (returnCode.equalSignoreCase ("Erfolg") && resultCode.equalSignoreCase ("Erfolg") {String Shorturl = map.get ("Short_url"); // todo shorturl erhalten, schreiben Sie den Code, um das QR -Code -System zu generieren. try {createQrCode.CreateCodestream (Shorturl, Antwort); } catch (Ausnahme e) {// Todo automatisch generierter Block E. printstacktrace (); }}} public void wxScancodeHandler (httpServletRequest -Anforderung, httpServletResponse -Antwort) löst die Ausnahme aus {InputStream instream = request.getInputStream (); BytearrayoutputStream outsteam = new bytearrayoutputStream (); byte [] buffer = neues byte [1024]; int len = 0; while ((len = instrenm.read (puffer))! = -1) {outsteam.write (puffer, 0, len); } outsteam.close (); instream.close (); String result = new String (outsteam.tobytearray (), "utf-8"); // Die Rückgabeinformationen von WeChat erhalten, das unsere Notify_url-Karte <Objekt, Objekt> map = null aufruft; try {map = xmlutil.doxmlParse (Ergebnis); } catch (jdomexception e) {// Todo automatisch generierter Catch-Block e.printstacktrace (); } für (Object KeyValue: map.keyset ()) {System.out.println (KeyValue+"="+map.get (KeyValue)); } String orderno = map.get ("product_id"). ToString (); // Rufen Sie nach Empfangen des Anforderungsparameters die einheitliche einzelne Schnittstelle SortEdMap <Objekt, Objekt> Parameter = New TREEMAP <Objekt, Objekt> () auf. Parameter.put ("Appid", configUtil.appid); parameters.put ("mch_id", configUtil.mch_id); Parameter.put ("Device_info", "1000"); Parameter.put ("Körper", "Testcode zur Bezahlung"); parameters.put ("nonce_str", paycommonutil.createNoncestern ()); parameters.put ("out_trade_no", map.get ("product_id")); //parameters.put("total_fee ", String.ValueOf (TotalPrice)); Parameter.put ("Total_fee", "1"); parameters.put ("SPBILL_CREATE_IP", Request.getRemoteaddr ()); parameters.put ("benachrichtigen_url", configUtil.notify_url); Parameter.put ("Trade_Type", "Native"); parameters.put ("openID", map.get ("openID")); String Sign = paycommonutil.createSign ("utf-8", Parameter); Parameter.put ("Zeichen", Zeichen); String RequestXML = PayCommonUtil.getRequestXML (Parameter); String result2 = CommonUtil.httpsRequestforStr (configUtil.unified_order_url, "post", requestXml); System.out.println ("----------------------------- 统一下单结果 -----------------------"); System.out.println (Ergebnis2); Karte <String, String> mm = null; try {mm = geth5paymap (result2, request); } catch (Ausnahme e) {// Todo automatisch generierter Block E. printstacktrace (); } // String prepayid = getPrepayid (Ergebnis2, Anfrage); // String returnNonestern = getReturnnonestern (Ergebnis2, Anfrage); String prepayid = mm.get ("prepay_id"); String returnNonestr = mm.get ("nonce_str") ;; SortEdMap <Objekt, Objekt> lastsign = new Treemap <Objekt, Objekt> (); lastsign.put ("return_code", "Erfolg"); lastsign.put ("Appid", configUtil.appid); lastsign.put ("mch_id", configUtil.mch_id); lastsign.put ("nonce_str", returnNonestern); lastsign.put ("prepay_id", prepayid); lastsign.put ("result_code", "Erfolg"); lastsign.put ("key", configutil.api_key); String lastsignPara = paycommonutil.createSign ("utf-8", lastsign); StringBuffer buf = new StringBuffer (); buf.Append ("<xml>"); buf.append ("<return_code> Erfolg </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>"+returnNonestr+"</nonce_str>"); buf.append ("<prepay_id>"+prepayid+"</prepay_id>"); buf.Append ("<Ertr ERGEBNIS_CODE> ERFORDER </result_code>"); buf.Append ("<Sign>"+lastsignPara+"</sign>"); buf.append ("</xml>"); response.getWriter (). print (buf.toString ()); } public map <String, String> Geth5PayMap (String -Ergebnis, httpServletRequest -Anforderung) löst Ausnahme aus {map <String, String> map = xmlutil.doxmlParse (Ergebnis); Rückgabekarte; }}Schauen wir uns schließlich die WeChat -Konfiguration für offizielle Kontozahlung und Scan -Code -Zahlung an:
Ich hoffe, dass in diesem Artikel jeder verstehen kann, dass Sie auch dann, wenn Sie Java verwenden, um WeChat öffentliche Konten und WeChat -Zahlungen zu leisten, ohne den von GitHub bereitgestellten Betrugscode zu verwenden, WeChat -Anwendungen entwickeln, die Sie und Ihre Kunden zufrieden stellen. Obwohl die von WeChat gegebenen Demos alle PHP sind, sind dies alles Wolken. Die Entwicklungssprache ist Zweiter, und das Verständnis der zugrunde liegenden Ebene, die Schnittstellenaufrufe erfordert, ist nur ein obligatorischer Kurs für Programmierer.