Le paiement de WeChat est devenu de plus en plus populaire maintenant, et il existe de nombreux produits qui peuvent rapidement accéder au paiement de WeChat. Cependant, en plus d'être pratique, cela nous fait également progressivement compter sur des tiers pour faire les choses et perdre la capacité de penser indépendamment. Cette fois, nous prévoyons de partager le paiement WeChat que j'ai déjà développé.
1. H5 Paiement du compte officiel
Points clés: Obtenez correctement OpenID et unifiez l'interface unique, traitez correctement les notifications de résultats de paiement et configurez correctement le répertoire d'autorisation de paiement
Le mode de paiement de H5 est une méthode largement utilisée. Ce mode de paiement est principalement utilisé pour les pages Web avec des menus personnalisés dans WeChat. Il s'appuie sur le client WeChat installé sur le téléphone mobile. Seules les versions plus élevées de WeChat prennent en charge le paiement WeChat. Veuillez noter les instructions suivantes pour suivre mon processus.
1. Écrivez une page pour le paiement, car c'est un test, c'est un peu plus simple.
<% @ page langage = "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> <adread> <base href = "<% = basepath%>"> <Title> wechat Exemple de paiement </ title> <méta name = "weffort" contenu = "width = device-width, initial-sable = 1.0, maximum-scy = 1.0" <! - <link rel = "stylesheet" type = "text / css" href = "styles.css"> -> </ head> <body> <form action = "oAuthServlet" méthode = "post"> Numéro d'ordre: <entrée type = "text" name = "OrderNo" /> <intrut type = "soupper" value = "h5 Paye action = "scancodepayServlet? Flag = createCode" méthode = "post"> Numéro d'ordre: <input type = "text" name = "OrderNo" /> <input type = "soumed" value = "scan le code à payer" /> </ form> </ body> </html>
2 Écrivez un servlet pour obtenir du code via OAuth
package com.debug.weixin.servlet; Importer java.io.ioException; import java.io.printwriter; Importer javax.servlet.requestdispatcher; Importer javax.servlet.servletException; import javax.servlet.http.httpservlet; Importer javax.servlet.http.httpservletRequest; import javax.servlet.http.httpservletResponse; import com.debug.weixin.util.commonutil; import com.debug.weixin.util.serverconfig; La classe publique OAuthServlet étend HttpServlet {public void doGet (HttpServLetRequest Request, HttpServletResponse Response) lance ServletException, ioException {this.dopost (request, réponse); } public void doPost (request httpServLetRequest, httpsservletResponse réponse) lève ServletException, ioException {String orderNo = request.getParameter ("OrderNo"); // Appelez WeChat OAuth2.0 pour obtenir OpenId String RedirectUrl = ServerConfig.ServerDomain + "/ BasicWeixin / PayServletforh5? Orderno =" + OrderNo; String redirireRri = ""; essayez {redirectturi = Commonutil.InitOpenID (redirectUrl); } catch (exception e) {// TODO Bloc de capture généré automatiquement e.printStackTrace (); } //System.out.println(redirerecturi); // requestDispatcher dis = request.getRequestDispatcher (redirectturi); //dis.forward(Request, réponse); réponse.SendRedirect (redirecty); }} 3 Après avoir obtenu le code, obtenez OpenID via Redirectturi et appelez l'interface unique unifiée
package com.debug.weixin.servlet; Importer java.io.ioException; import java.io.printwriter; import java.util.sortedmap; import java.util.treemap; Importer javax.servlet.requestdispatcher; Importer javax.servlet.servletException; import javax.servlet.http.httpservlet; Importer javax.servlet.http.httpservletRequest; import javax.servlet.http.httpservletResponse; import com.debug.weixin.pojo.weixinoauth2token; import com.debug.weixin.pojo.weixinqrcode; import com.debug.weixin.util.advancedUtil; import com.debug.weixin.util.commonutil; import com.debug.weixin.util.configutil; import com.debug.weixin.util.paycommonutil; La classe publique PayServletForH5 étend HttpServlet {public void doGet (HttpServLetRequest Request, HttpServletResponse Response) lance ServletException, ioException {this.dopost (demande, réponse); } public void doPost (request httpServLetRequest, httpsservletResponse réponse) lève ServletException, ioException {String orderNo = request.getParameter ("OrderNo"); String code = request.getParameter ("code"); // Obtenez AccessToken WeixinoAuth2Token Token = AdvancedUtil.getoAuth2AccessToken (configUtil.appid, configUtil.app_secrect, code); String openId = token.getOpenID (); // Appel WECHAT Unified Payment Interface tridmap <objet, objet> Paramètres = new Treemap <objet, objet> (); Paramètres.put ("appid", configUtil.appid); paramètres.put ("mch_id", configUtil.mch_id); Paramètres.put ("Device_info", "1000"); paramètres.put ("corps", "mon ordre de test"); Paramètres.put ("nonce_str", PayComMonutil.CreateNonCestl ()); paramètres.put ("out_trade_no", orderNo); //Parameters.put("Total_Fee ", String.ValueOf (Total)); paramètres.put ("total_fee", "1"); Paramètres.put ("SPBILL_CREATE_IP", request.getReMoteadDr ()); paramètres.put ("notify_url", configUtil.notify_url); Paramètres.put ("Trade_type", "JSAPI"); Paramètres.put ("OpenID", OpenID); String Sign = PayComMonutil.CreateSign ("UTF-8", paramètres); Paramètres.put ("signe", signe); String requestxml = PayComMonutil.getRequestXml (paramètres); String result = Commonutil.httpsRequestForstr (configUtil.unified_order_url, "post", requestXml); System.out.println ("----------------------------------"); System.out.println (résultat); System.out.println ("----------------------------------"); request.setAttribute ("OrderNo", OrderNo); request.setAttribute ("totalPrice", "0,01"); String payjson = ""; essayez {payjson = Commonutil.geth5paystr (résultat, demande); } catch (exception e) {// TODO Bloc de capture généré automatiquement e.printStackTrace (); } //System.out.println(payjson); request.setAttribute ("UnifiedOrder", Payjson); RequestDispatcher dis = request.getRequestDispatcher ("h5pay.jsp"); dis.Forward (demande, réponse); }} Appeler WeChat pour unifier une seule interface nécessite une attention sur l'algorithme de signature. Ce n'est que lorsque le calcul de la signature est correct que le paiement peut être en douceur
Public Static String GETH5PAYSTR (Result String Result, HttpServleRequest Request) lève l'exception {map <string, string> map = xmlutil.doxmlparse (result); TriMedMap <objet, objet> params = new Treemap <objet, objet> (); Params.put ("appid", configUtil.appid); params.put ("horodat", long.toString (new Date (). GetTime ())); Params.put ("nonCest", PayComMonutil.CreateNonCestl ()); params.put ("package", "prepay_id =" + map.get ("prepay_id")); Params.put ("signalpe", configUtil.sign_type); String paysign = PayComMonutil.CreatIgn ("UTF-8", params); Params.put ("paysign", paysign); // Les règles de génération de Paysign sont conformes aux règles de génération de la chaîne de signe JSON = JSONObject.FromObject (params) .toString (); retourner JSON; } 4 Écrivez l'interface de paiement finale pour ajuster le paiement WeChat H5
<% @ page langage = "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> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"> <script type = "text / javascript"> function jsapicall () {weixinjsbridge.invoke ('getBrandwcpayRequest', <% = (string) request.getAttribute ("UnifiedOrder")%>, fonction (res) {weixinjsbridge.log (res.err_msg); //Alert(rs.err_code+res.err_desc+res.err_msg); } function callpay () {if (typeof weixinjsbridge == "undefined") {if (document.addeventListener) {document.addeventListener ('weixinjsbridgeready', jsapicall, false); } else 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. Traitement des résultats de paiement WeChat Notification
package com.debug.weixin.servlet; Importer java.io.ByteArrayOutputStream; Importer java.io.ioException; import java.io.inputStream; import java.io.printwriter; importation java.util.map; Importer javax.servlet.servletException; import javax.servlet.http.httpservlet; Importer javax.servlet.http.httpservletRequest; import javax.servlet.http.httpservletResponse; import org.jdom.jdomexception; import com.debug.weixin.util.paycommonutil; import com.debug.weixin.util.xmlutil; classe publique PayHandleRervlet étend HttpServlet {public void doGet (httpServLetRequest request, httpservletResponse réponse) lance ServletException, ioException {this.dopost (request, réponse); } public void doPost (requête HttpServletRequest, réponse httpservletResponse) lève ServletException, ioException {inputStream insiteam = request.getInputStream (); BytearrayoutputStream outsteam = new bytearrayoutputStream (); octet [] tampon = nouveau octet [1024]; int len = 0; while ((len = insiteam.read (tampon))! = -1) {outsteam.write (tampon, 0, len); } outsteam.close (); instream.close (); String result = new String (outsteam.toByTearray (), "UTF-8"); // Obtenez les informations de retour de WeChat appelant notre carte notify_url <objet, objet> map = null; essayez {map = xmlutil.doxmlparse (résultat); } catch (JDomexception e) {// TODO Générations de catch Généra E.PrintStackTrace (); } pour (objet keyValue: map.KeySet ()) {System.out.println (keyValue + "=" + map.get (keyValue)); } if (map.get ("result_code"). toString (). equalSignoreCase ("Success")) {// Opérations commerciales sur Orders System.out.println ("--------------------------- ok"); réponse.getWriter (). Write (PayComMonutil.setXml ("Success", "")); // Dites au serveur WeChat que j'ai reçu le message, n'appelez pas l'action de rappel}}} Pour le code ci-dessus, beaucoup d'entre eux se réfèrent à http://blog.csdn.net/U011160656/article/details/41759195, donc cette partie du code ne sera pas publiée. Si vous en avez besoin, vous le saurez en lisant ce blog.
2. Code de numérisation WeChat à payer (mode 1)
Points clés: vous devez appeler le lien long vers l'interface de liaison courte et configurer correctement le code d'analyse pour payer l'URL de rappel
1 Générer le code QR de paiement WeChat en fonction du numéro de commande
Voici quelques façons de générer des codes QR:
package com.debug.weixin.util; import com.google.zxing.common.bitmatrix; import javax.imageio.imageio; Importer java.io.file; import java.io.outputStream; Importer java.io.ioException; Importer java.awt.image.bufferedImage; public final classe matrixtoimagewriter {private static final int black = 0xff000000; Final statique privé int blanc = 0xfffffff; MatrixToimageWriter privé () {} public static bufferedImage toblufferedImage (BitMatrix Matrix) {int width = matrix.getWidth (); int height = matrix.getheight (); BufferedImage Image = new BufferedImage (largeur, hauteur, bufferedImage.type_int_rgb); pour (int x = 0; x <largeur; x ++) {pour (int y = 0; y <hauteur; y ++) {image.setrgb (x, y, matrix.get (x, y)? noir: blanc); }} Retour image; } public static void writeTofile (BitMatrix Matrix, Format de chaîne, fichier de fichier) lève ioException {BufferedImage image = toblufferedImage (matrix); if (! ImageIo.write (image, format, fichier)) {lancer une nouvelle ioException ("ne peut pas écrire une image de format" + format + "vers" + file); }} public static void writeToStream (Matrix BitMatrix, format de chaîne, flux OutputStream) lève ioException {bufferedImage Image = TobffereDImage (matrix); if (! ImageIo.write (image, format, stream)) {lancer une nouvelle ioException ("ne peut pas écrire une image de format" + format); }}} Il s'agit d'une classe d'outils, et il existe une autre méthode pour afficher le code QR sur l'interface. CreateQrcode utilise principalement des blocs de code:
public static void createCodeStream (Text de chaîne, réponse httpservletResponse) lève l'exception {// réponse.setContentType ("image / jpeg"); ServletOutputStream sos = réponse.getOutputStream (); Int largeur = 500; int hauteur = 500; // QR Code Image Format String Format = "JPG"; MultiformatWriter MultiformatWriter = new MultiformatWriter (); MAP INSTERS = NOUVEAU HASHMAP (); // les indices codés.put (encodeHintType.Character_Set, "UTF-8"); BitMatrix BitMatrix = MultiformatWriter.encode (texte, barcodeformat.qr_code, largeur, hauteur, indices); // générer du code QR MatrixToimageWriter.WriteToStream (BitMatrix, Format, SOS); sos.close (); } 2. Pour convertir les liens longs en liens courts pour générer des codes QR, rédigez une méthode de rappel de paiement de code scan et appelez l'interface unique unifiée
package com.debug.weixin.servlet; Importer java.io.ByteArrayOutputStream; Importer java.io.ioException; import java.io.inputStream; import java.io.printwriter; Importer java.util.date; importation java.util.map; import java.util.sortedmap; import java.util.treemap; Importer javax.servlet.servletException; import javax.servlet.http.httpservlet; Importer javax.servlet.http.httpservletRequest; import 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; import com.debug.weixin.util.paycommonutil; import com.debug.weixin.util.xmlutil; import com.mongodb.dbObject; La classe publique scancodepayservlet étend httpServlet {public void doGet (httpsservletRequest request, httpservletResponse réponse) lance ServletException, ioException {this.dopost (request, réponse); } public void doPost (httpsservletRequest request, httpsservletResponse réponse) lève servletException, ioException {String Flag = request.getParameter ("Flag"); if ("CreateCode" .Equals (Flag)) {createPayCode (request, réponse); } else {try {wxScCodeHandler (request, réponse); } catch (exception e) {// TODO Bloc de capture généré automatiquement e.printStackTrace (); }}} public void CreatePayCode (request httpServLeRequest, HttpServletResponse Response) {String OrderNo = request.getParameter ("OrderNo"); TriMedMap <objet, objet> parAs = new Treemap <objet, objet> (); parAs.put ("appid", configUtil.appid); parAs.put ("mch_id", configUtil.mch_id); ParaS.put ("Time_stamp", long.toString (new Date (). GetTime ())); ParaS.put ("Nonce_Str", PayComMonutil.CreateNonCestl ()); paraS.put ("product_id", ordonnance); // le numéro de produit doit être une chaîne unique Sign = PayComMonutil.CreatIgn ("UTF-8", parAs); ParaS.put ("signe", signe); String url = "weixin: // wxpay / bizpayurl? Sign = Sign & appid = appid & mch_id = mchid & product_id = productid & time_stamp = timestamp & nonce_str = nocestr"; String nativeUrl = url.replace ("signe", signe) .replace ("appid", configUtil.appid) .replace ("mchid", configUtil.mch_id) .replace ("productid", (string) paras.get ("product_id")). Remplace ("timestamp", (string) paras.get ("time_stamp")). (String) ParaS.get ("nonce_str")); TRODMAP <objet, objet> Paramètres = new Treemap <objet, objet> (); Paramètres.put ("appid", configUtil.appid); paramètres.put ("mch_id", configUtil.mch_id); Paramètres.put ("nonce_str", PayComMonutil.CreateNonCestl ()); paramètres.put ("long_url", communautil.urlencodeutf8 (nativeUrl)); String Sign2 = PayComMonutil.CreateSign ("UTF-8", paramètres); Paramètres.put ("Sign", Sign2); String requestxml = PayComMonutil.getRequestXml (paramètres); Résultat de la chaîne = Commonutil.httpsRequestForstr (configUtil.short_url, "post", requestXml); Map <string, string> map = null; essayez {map = xmlutil.doxmlparse (résultat); } catch (JDomexception e) {// TODO Générations de catch Généra E.PrintStackTrace (); } catch (ioException e) {// TODO Bloc de capture généré automatiquement e.printStackTrace (); } String returncode = map.get ("return_code"); String resultCode = map.get ("result_code"); if (returncode.equalSignoreCase ("Success") && resultCode.equalSignoreCase ("Success")) {String shortl = map.get ("short_url"); // TODO GOT Shortl, écrivez le code pour générer le code QR System.out.println ("shortl =" + shortl); essayez {createqrcode.createCodeStream (shortl, réponse); } catch (exception e) {// TODO Bloc de capture généré automatiquement e.printStackTrace (); }}} public void wxScCodeHandler (request httpservletRequest, httpservletResponse réponse) lève exception {inputStream insiteam = request.getInputStream (); BytearrayoutputStream outsteam = new bytearrayoutputStream (); octet [] tampon = nouveau octet [1024]; int len = 0; while ((len = insiteam.read (tampon))! = -1) {outsteam.write (tampon, 0, len); } outsteam.close (); instream.close (); String result = new String (outsteam.toByTearray (), "UTF-8"); // Obtenez les informations de retour de WeChat appelant notre carte notify_url <objet, objet> map = null; essayez {map = xmlutil.doxmlparse (résultat); } catch (JDomexception e) {// TODO Générations de catch Généra E.PrintStackTrace (); } pour (objet keyValue: map.KeySet ()) {System.out.println (keyValue + "=" + map.get (keyValue)); } String orderNo = map.get ("product_id"). ToString (); // Après avoir reçu le paramètre de la demande, appelez l'interface unifiée unique triésmap <objet, objet> Paramètres = new Treemap <objet, objet> (); Paramètres.put ("appid", configUtil.appid); paramètres.put ("mch_id", configUtil.mch_id); Paramètres.put ("Device_info", "1000"); Paramètres.put ("Body", "Test Code pour payer la commande"); Paramètres.put ("nonce_str", PayComMonutil.CreateNonCestl ()); paramètres.put ("out_trade_no", map.get ("product_id")); //Parameters.put("Total_Fee ", String.Valueof (TotalPrice)); paramètres.put ("total_fee", "1"); Paramètres.put ("SPBILL_CREATE_IP", request.getReMoteadDr ()); paramètres.put ("notify_url", configUtil.notify_url); Paramètres.put ("Trade_type", "natif"); paramètres.put ("openId", map.get ("openId")); String Sign = PayComMonutil.CreateSign ("UTF-8", paramètres); Paramètres.put ("signe", signe); String requestxml = PayComMonutil.getRequestXml (paramètres); String result2 = Commonutil.httpsRequestForstr (configUtil.unified_order_url, "post", requestXml); System.out.println ("----------------------------- 统一下单结果 ---------------------------"); System.out.println (result2); Map <string, string> mm = null; essayez {mm = geth5paymap (result2, request); } catch (exception e) {// TODO Bloc de capture généré automatiquement e.printStackTrace (); } // String prepayId = getPrepayId (result2, request); // String returnNonestr = getReturnNonestr (result2, request); String prepayId = mm.get ("prepay_id"); String returnNonestr = mm.get ("nonce_str") ;; TriMedMap <objet, objet> lastsign = new Treemap <objet, objet> (); LastSign.put ("return_code", "succès"); LASTSIGN.PUT ("AppID", configUtil.Appid); LastSign.put ("mch_id", configUtil.mch_id); LASTSIGN.PUT ("NONCE_STR", RETOURNONESTR); LastSign.put ("prepay_id", prepayId); LastSign.put ("result_code", "succès"); LastSign.put ("Key", configUtil.api_key); String LastSignPara = PayComMonutil.CreateSign ("UTF-8", LastSign); StringBuffer buf = new StringBuffer (); buf.append ("<xml>"); buf.append ("<return_code> Success </ return_code>"); buf.append ("<pid>" + configUtil.appid + "</pid>"); 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 + "</paye_id>"); buf.append ("<sultalise_code> succès </cult_code>"); buf.append ("<signe>" + LastSignPara + "</ign>"); buf.append ("</xml>"); réponse.getWriter (). print (buf.toString ()); } public map <string, string> geth5paymap (string result, httpsservletRequest request) lève exception {map <string, string> map = xmlutil.doxmlparse (result); carte de retour; }}Enfin, jetons un coup d'œil à la configuration de WeChat pour le paiement officiel du compte et le paiement du code de numérisation:
J'espère que grâce à cet article, tout le monde peut comprendre que même si vous utilisez Java pour effectuer des comptes publics WeChat et un paiement WeChat sans utiliser le code de triche fourni par GitHub, vous pouvez développer des applications WeChat qui vous satisfont et vos clients. Bien que les démos données par WeChat soient toutes PHP, ce sont tous des nuages. Le langage de développement est deuxième et comprendre la couche sous-jacente que les appels d'interface nécessitent n'est qu'un cours obligatoire pour les programmeurs.