O pagamento do WeChat se tornou cada vez mais popular agora, e há muitos produtos que podem acessar rapidamente o pagamento do WeChat. No entanto, além de ser conveniente, também nos faz depender gradualmente de terceiros para fazer as coisas e perder a capacidade de pensar de forma independente. Desta vez, planejamos compartilhar o pagamento do WeChat que eu desenvolvi antes.
1. Pagamento de conta oficial H5
Pontos -chave: obtenha corretamente o OpenID e unifique a interface única, processando corretamente as notificações de resultado do pagamento e configure corretamente o diretório de autorização de pagamento
O método de pagamento do H5 é um método amplamente utilizado. Este método de pagamento é usado principalmente para páginas da Web com menus personalizados no WeChat. Ele depende do cliente WeChat instalado no telefone celular. Apenas versões mais altas do WeChat suportam o pagamento do WeChat. Observe as seguintes instruções para seguir meu processo.
1. Escreva uma página para pagamento, porque é um teste, é um pouco mais simples.
<%@ página de página = "java" import = "java.util.*" pageEncoding = "utf-8"%> <%string path = request.getContextPath (); String basalepath = request.getScheme ()+": //"+request.getServername ()+":"+request.getServerport ()+path+"/"; %> <! Doctype html public "-// w3c // dtd html 4.01 transitória // pt"> <html> <head> <base href = "<%= Basepath%>"> <title> Exemplo de pagamento wechat </title> <meta = "viewport" <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <form action="oauthServlet" method="POST"> Order number: <input type="text" name="orderNo" /> <input type="submit" value="H5 payment"/> </form> </br></br> <form action = "scancodePayServlet? sinalizador = createCode" method = "post"> número do pedido: <input type = "text" name = "orderno"/> <input type = "submit" value = "digitalize o código a pagar"/> </form> </body> </html>
2 Escreva um servlet para obter código através do OAuth
pacote com.debug.weixin.servlet; importar java.io.ioException; importar java.io.printwriter; importar javax.servlet.requestDispatcher; importar javax.servlet.servletexception; importar javax.servlet.http.httpServlet; importar javax.servlet.http.httpServletRequest; importar javax.servlet.http.httpServletResponse; importar com.debug.weixin.util.commonutil; importar com.debug.weixin.util.serverconfig; classe pública OAuthServlet estende httpServlet {public void Doget (solicitação HttPervletRequest, httpServletResponse resposta) lança servletexception, ioexception {this.DoPost (solicitação, resposta); } public void DoPost (solicitação httpServletRequest, httpServletResponse resposta) lança servletexception, ioexception {string orderno = request.getParameter ("orderno"); // Ligue para o weChat OAuth2.0 para obter o OpenId String redirecturl = serverconfig.ServerDomain+"/Basicweixin/payServletForh5? OrderNo ="+OrderNo; String redirecturi = ""; tente {redirecturi = Commonutil.initopenid (redirecturl); } Catch (Exceção e) {// TODO BLOCO DE CAPAGEM AUTOMENTADO E.PRINTSTACKTRACE (); } //System.out.println(redirecturi); // requestDispatcher dis = request.getRequestDispatcher (redirecturi); //dis.forward(request, resposta); Response.sendRedirect (Redirecturi); }} 3 Depois de obter o código, obtenha o OpenID através do Redirecture e chame a interface única unificada
pacote com.debug.weixin.servlet; importar java.io.ioException; importar java.io.printwriter; importar java.util.sortedmap; importar java.util.treemap; importar javax.servlet.requestDispatcher; importar javax.servlet.servletexception; importar javax.servlet.http.httpServlet; importar javax.servlet.http.httpServletRequest; importar javax.servlet.http.httpServletResponse; importar com.debug.weixin.pojo.weixinoauth2Token; importar com.debug.weixin.pojo.weixinqrcode; importar com.debug.weixin.util.advancedutil; importar com.debug.weixin.util.commonutil; importar com.debug.weixin.util.configuil; importar com.debug.weixin.util.paycommonutil; classe pública PayServletForH5 estende httpServlet {public void Doget (solicitação httpSerTrequest, httpServletResponse resposta) lança servletexception, ioexception {this.DoPost (solicitação, resposta); } public void DoPost (solicitação httpServletRequest, httpServletResponse resposta) lança servletexception, ioexception {string orderno = request.getParameter ("orderno"); String code = request.getParameter ("código"); // obtenha o accessToken weixinoauth2Token token = Advancedutil.getoauth2AccessToken (configutil.appid, configutil.app_secrect, código); String openId = token.getOpenId (); // Chamando a interface de pagamento WeChat Unified SatedMap <Object, Object> Parameters = new Treemap <Object, object> (); parâmetros.put ("appid", configuil.appid); parâmetros.put ("mch_id", configutil.mch_id); parâmetros.put ("device_info", "1000"); parâmetros.put ("corpo", "minha ordem de teste"); parameters.put ("nonce_str", payCommonutil.createNoCest ()); parâmetros.put ("out_trade_no", orderno); //parameters.put("total_fee ", string.valueof (total)); parâmetros.put ("total_fee", "1"); parameters.put ("spbill_create_ip", request.getRemoteaddr ()); parameters.put ("notify_url", configutil.notify_url); parâmetros.put ("trade_type", "jsapi"); parâmetros.put ("OpenId", OpenId); String signo = paycommonutil.createSign ("utf-8", parâmetros); parâmetros.put ("sinal", sinal); String requestXml = payCommonutil.getRequestxml (parâmetros); String resultado = Commonutil.httpsRequestForstr (configutil.unified_order_url, "post", requestXml); System.out.println ("--------------------------------"); System.out.println (resultado); System.out.println ("--------------------------------"); request.setAttribute ("orderno", ordem); request.setAttribute ("TotalPrice", "0,01"); String payjson = ""; tente {Payjson = Commonutil.geth5Paystr (resultado, solicitação); } Catch (Exceção e) {// TODO BLOCO DE CAPAGEM AUTOMENTADO E.PRINTSTACKTRACE (); } //System.out.println(payjson); request.setattribute ("UnifiedOrder", Payjson); RequestDispatcher dis = request.getRequestDispatcher ("h5pay.jsp"); Dis.forward (solicitação, resposta); }} Chamar o WeChat para unificar uma única interface requer atenção ao algoritmo de assinatura. Somente quando o cálculo da assinatura está correto, o pagamento pode ser suavemente
public static string geth5Paystr (resultado da string, solicitação httpServletRequest) lança a exceção {map <string, string> map = xmlutil.doxmlParse (resultado); STORDMAP <Object, Object> params = new Treemap <Object, Object> (); params.put ("Appid", configuil.appid); params.put ("timestamp", long.toString (new Date (). getTime ())); params.put ("não -cest", payCommonutil.CreateNoCest ()); params.put ("pacote", "pré -any_id ="+map.get ("pré -any_id")); params.put ("SignType", configuil.sign_type); String PaySign = PayCommonutil.CreateSign ("UTF-8", Params); params.put ("PaySign", PaySign); // As regras de geração do PaySign são consistentes com as regras de geração do sinal string json = jsonObject.FromObject (params) .ToString (); retornar JSON; } 4 Escreva a interface de pagamento final para ajustar o pagamento do WeChat H5
<%@ página de página = "java" import = "java.util.*" pageEncoding = "utf-8"%> <%string path = request.getContextPath (); String basalepath = request.getScheme ()+": //"+request.getServername ()+":"+request.getServerport ()+path+"/"; %> <! Doctype html public "-// w3c // dtd html 4.01 transitória // pt"> <html> <head> <base href = "<%= Basepath%>"> <title> weChat h5 page </title> <meta name = viewport "" content = white = whechth = 1. Wechat H5 Payment </title> <meta-name = "viewport" <script type = "text/javascript"> function jsapicall () {weixinjsbridge.invoke ('getBrandwcpayRequest', <%= (string) request.getAttribute ("unifiedorder")%>, function (res) {weixinjsbridge.log (res.m.g); //alert(res.err_code+res.err_desc+res.err_msg); } function callapay () {if (typeof weixinjsbridge == "indefinido") {if (document.addeventListener) {document.addeventListener ('weixinjsbridgeready', jsapicall, false); } else if (document.attachevent) {document.attachevent ('weixinjsbridgeready', jsapicall); document.attachevent ('onweixinjsbridgeready', jsapicall); }} else {JSapicall (); }} </script> </ad Head> <body> <input type = "button" value = "pay" onclick = "callpay ()"/> </body> </html> 5. Notificação do processamento de resultados de pagamento do WECHAT
pacote com.debug.weixin.servlet; importar java.io.byteArrayOutputStream; importar java.io.ioException; importar java.io.inputStream; importar java.io.printwriter; importar java.util.map; importar javax.servlet.servletexception; importar javax.servlet.http.httpServlet; importar javax.servlet.http.httpServletRequest; importar javax.servlet.http.httpServletResponse; importar org.jdom.jdomexception; importar com.debug.weixin.util.paycommonutil; importar com.debug.weixin.util.xmlutil; public class PayHandlerServlet estende httpServlet {public void Doget (solicitação HttPervletRequest, httpServletResponse resposta) lança servletexception, ioexception {this.DoPost (solicitação, resposta); } public void DoPost (solicitação httpServletRequest, httpServletResponse Response) lança servletexception, ioexception {inputStream unstrateam = request.getInputStream (); ByteArrayOutputStream Outsteam = new ByteArrayOutputStream (); byte [] buffer = novo byte [1024]; int len = 0; while ((len = Instream.read (buffer))! = -1) {Outsteam.Write (buffer, 0, len); } Outsteam.close (); Instruam.close (); String result = new String (outsteam.tobytearray (), "utf-8"); // obtenha as informações de retorno do WeChat chamando nosso mapa notify_url <objeto, objeto> map = null; tente {map = xmlutil.doxmlParse (resultado); } catch (jdomexception e) {// TODO BLOCO DE CAPAGEM AUTOMENTADO E.PRINTSTACKTRACE (); } para (objeto keyValue: map.keyset ()) {System.out.println (keyvalue+"="+map.get (keyvalue)); } if (map.get ("result_code"). tostring (). Equalsignorecase ("succcess")) {// operações de negócios no ordens system.out.println ("------------------------- OK"); Response.getWriter (). Write (PayCommonutil.Setxml ("Sucesso", ""); // Diga ao servidor WeChat que recebi a mensagem, não ligue para a ação de retorno de chamada}}} Para o código acima, muitos deles se referem a http://blog.csdn.net/u011160656/article/details/41759195, portanto, essa parte do código não será publicada. Se você precisar, você saberá lendo este blog.
2. Código de varredura do WeChat a pagar (modo 1)
Pontos -chave: você deve chamar o link longo para interface de link curto e configurar corretamente o código de varredura para pagar URL de retorno de chamada
1 Gere o código QR de pagamento do WeChat com base no número do pedido
Aqui estão algumas maneiras de gerar códigos QR:
pacote com.debug.weixin.util; importar com.google.zxing.common.bitmatrix; importar javax.imageio.imageio; importar java.io.file; importar java.io.OutputStream; importar java.io.ioException; importar java.awt.image.bufferiMage; Classe final pública MatrixToImageWriter {private estático final int preto = 0xff000000; private estático final int branco = 0xfffffff; private matrixToImageWriter () {} public static bufferImage TobBufferedImage (matriz bitMatrix) {int width = matrix.getWidth (); int height = matrix.getHeight (); Imagem bufferedImage = new bufferImage (largura, altura, bufferImage.type_int_rgb); for (int x = 0; x <width; x ++) {for (int y = 0; y <altura; y ++) {image.setrgb (x, y, matrix.get (x, y)? preto: branco); }} retornar imagem; } public static void writetofile (matriz bitMatrix, formato de string, arquivo de arquivo) lança IoException {bufferEdImage imagem = TobBufferedImage (matriz); if (! imageio.write (imagem, formato, arquivo)) {lança a nova ioException ("não pudesse escrever uma imagem do formato" + formato + "para" arquivo +); }} public static void writeToStream (matriz bitMatrix, formato de string, fluxo de saída de saída) lança IoException {bufferedImage imagem = TobBufferedImage (matriz); if (! imageio.write (imagem, formato, stream)) {lança a nova ioException ("não pudesse escrever uma imagem de formato" + formato); }}} Esta é uma classe de ferramentas e há outro método para exibir o código QR na interface. CreateQRCode usa principalmente blocos de código:
public static void createCodestream (texto da string, httpServletResponse Response) lança exceção {// Response.SetContentType ("Image/jpeg"); ServletOutputStream SOS = Response.getOutputStream (); int width = 500; int altura = 500; // Código QR Format String format = "jpg"; MultiformatWriter multInFalMatWriter = new MultiformatWriter (); Dicas de mapa = new hashmap (); // as dicas codificadas.put (codehinttype.character_set, "utf-8"); BitMatrix bitMatrix = multiformatswriter.encode (texto, barcodeFormat.qr_code, largura, altura, dicas); // gerar código QR matrixtoimageWriter.WriteToStream (BitMatrix, Format, SOS); sos.close (); } 2. Para converter links longos em links curtos para gerar códigos QR, escreva um método de retorno de chamada de pagamento de código de varredura e ligue para a interface única unificada
pacote com.debug.weixin.servlet; importar java.io.byteArrayOutputStream; importar java.io.ioException; importar java.io.inputStream; importar java.io.printwriter; importar java.util.date; importar java.util.map; importar java.util.sortedmap; importar java.util.treemap; importar javax.servlet.servletexception; importar javax.servlet.http.httpServlet; importar javax.servlet.http.httpServletRequest; importar javax.servlet.http.httpServletResponse; importar org.jdom.jdomexception; importar com.debug.weixin.util.commonutil; importar com.debug.weixin.util.configuil; import com.debug.weixin.util.createqrcode; importar com.debug.weixin.util.paycommonutil; importar com.debug.weixin.util.xmlutil; importação com.mongodb.dbobject; classe pública ScancodePayServlet estende httpServlet {public void Doget (solicitação HttPervletRequest, resposta httpServletResponse) lança servletexception, ioexception {this.DoPost (solicitação, resposta); } public void DoPost (solicitação httpServletRequest, httpServletResponse Response) lança servletexception, ioexception {string flag = request.getParameter ("sinalizador"); if ("createCode" .equals (sinalizador)) {createPayCode (solicitação, resposta); } else {tente {wxscancodeHandler (request, resposta); } Catch (Exceção e) {// TODO BLOCO DE CAPAGEM AUTOMENTADO E.PRINTSTACKTRACE (); }}} public void CreatePayCode (solicitação httpServletRequest, httpServletResponse resposta) {string orderno = request.getParameter ("orderno"); STORDMAP <Object, Object> Paras = novo Treemap <Object, Object> (); paras.put ("Appid", configuil.appid); paras.put ("mch_id", configuil.mch_id); paras.put ("time_stamp", long.toString (new Date (). getTime ())); paras.put ("nonce_str", payCommonutil.createnoCest ()); paras.put ("product_id", orderno); // O número do produto deve ser um sinal de string exclusivo = payCommonutil.CreateSign ("UTF-8", parágrafos); paras.put ("sinal", sinal); String url = "weixin: // wxpay/bizpayurl? Signe = signe & Appid = Appid & mch_id = mchid & product_id = productId & time_stamp = timestamp & nonece_str = nocest"; String nativeurl = url.replace ("signo", sinal) .Place ("Appid", configutil.appid) .replace ("mchid", confgutil.mch_id) .replace ("productId", (string) paras.get ("product_id"). (String) paras.get ("nonce_str")); STORDMAP <Object, Object> Parameters = new Treemap <Object, Object> (); parâmetros.put ("appid", configuil.appid); parâmetros.put ("mch_id", configutil.mch_id); parameters.put ("nonce_str", payCommonutil.createNoCest ()); parameters.put ("long_url", Commonutil.urlencodeUtf8 (nativo)); String signo2 = payCommonutil.createsign ("utf-8", parâmetros); parâmetros.put ("Sign", Sign2); String requestXml = payCommonutil.getRequestxml (parâmetros); String resultado = Commonutil.httpSReQuestForStr (configutil.short_url, "post", requestXml); Mapa <string, string> map = null; tente {map = xmlutil.doxmlParse (resultado); } catch (jdomexception e) {// TODO BLOCO DE CAPAGEM AUTOMENTADO E.PRINTSTACKTRACE (); } catch (ioexception e) {// TODO GATO GENERADO AUTOMENTADO BLOCO E.PRINTSTACKTRACE (); } String returnCode = map.get ("return_code"); String resultcode = map.get ("resultado_code"); if (returncode.equalsignorecase ("succcess") && resultCode.EqualSignorecase ("Success")) {string shorturl = map.get ("short_url"); // TODO Get Shorturl, escreva o código para gerar o código QR System.out.println ("Shorturl ="+Shorturl); tente {createqrcode.createCodestream (shorturl, resposta); } Catch (Exceção e) {// TODO BLOCO DE CAPAGEM AUTOMENTADO E.PRINTSTACKTRACE (); }}} public void wxscancodeHandler (solicitação httpServLeTrequest, httpServletResponse resposta) lança exceção {inputStream untrineam = request.getInputStream (); ByteArrayOutputStream Outsteam = new ByteArrayOutputStream (); byte [] buffer = novo byte [1024]; int len = 0; while ((len = Instream.read (buffer))! = -1) {Outsteam.Write (buffer, 0, len); } Outsteam.close (); Instruam.close (); String result = new String (outsteam.tobytearray (), "utf-8"); // obtenha as informações de retorno do WeChat chamando nosso mapa notify_url <objeto, objeto> map = null; tente {map = xmlutil.doxmlParse (resultado); } catch (jdomexception e) {// TODO BLOCO DE CAPAGEM AUTOMENTADO E.PRINTSTACKTRACE (); } para (objeto keyValue: map.keyset ()) {System.out.println (keyvalue+"="+map.get (keyvalue)); } String orderno = map.get ("product_id"). Tostring (); // Depois de receber o parâmetro de solicitação, chame a interface única unificada classificada <objeto, objeto> parâmetros = new Treemap <object, object> (); parâmetros.put ("appid", configuil.appid); parâmetros.put ("mch_id", configutil.mch_id); parâmetros.put ("device_info", "1000"); parâmetros.put ("corpo", "código de teste para pagar a ordem"); parameters.put ("nonce_str", payCommonutil.createNoCest ()); parameters.put ("out_trade_no", map.get ("product_id")); //parameters.put("total_fee ", string.valueof (totalPrice)); parâmetros.put ("total_fee", "1"); parameters.put ("spbill_create_ip", request.getRemoteaddr ()); parameters.put ("notify_url", configutil.notify_url); parâmetros.put ("trade_type", "nativo"); parâmetros.put ("OpenId", map.get ("OpenId")); String signo = paycommonutil.createSign ("utf-8", parâmetros); parâmetros.put ("sinal", sinal); String requestXml = payCommonutil.getRequestxml (parâmetros); String result2 = Commonutil.httpsRequestForstr (configutil.unified_order_url, "post", requestXml); System.out.println ("--------------------------- 统一下单结果 -----------------------------"); System.out.println (resultado2); Mapa <string, string> mm = null; tente {mm = geth5paymap (resultado2, solicitação); } Catch (Exceção e) {// TODO BLOCO DE CAPAGEM AUTOMENTADO E.PRINTSTACKTRACE (); } // string pré -PAYID = getPrepayId (resultado2, solicitação); // string returnNoNEstr = getreturnNoST (resultado2, solicitação); String pré -PAYID = mm.get ("pré -paga_id"); String returnNoNEST = mm.get ("nonce_str") ;; ClassEdMap <objeto, objeto> lastSign = new Treemap <object, object> (); lastSign.put ("return_code", "sucesso"); lastSign.put ("Appid", configuil.appid); lastSign.put ("mch_id", configuil.mch_id); lastSign.put ("nonce_str", returnnonest); lastSign.put ("pré -PAY_ID", pré -condyID); lastSign.put ("result_code", "sucesso"); lastSign.put ("key", configuil.api_key); String lastSignPara = payCommonutil.CreateSign ("UTF-8", LastSign); Stringbuffer buf = new StringBuffer (); buf.append ("<xml>"); BUF.Append ("<Bret_Code> Sucesso </rort_code>"); buf.append ("<ppid>"+configutil.appid+"</ppid>"); buf.append ("<mch_id>"+configutil.mch_id+"</mch_id>"); buf.append ("<mch_id>"+configutil.mch_id+"</mch_id>"); buf.append ("<Nonce_Str>"+returnNonest+"</once_str>"); buf.append ("<prapay_id>"+pré -yid+"</plapay_id>"); BUF.Append ("<SIFORD_CODE> SUCCESS </Ilt_Code>"); buf.append ("<Sign>"+lastSignPara+"</Sign>"); buf.append ("</xml>"); Response.getWriter (). print (buf.toString ()); } mapa public <string, string> geth5paymap (resultado da string, httpServletRequest request) lança Exceção {map <string, string> map = xmlutil.doxmlParse (resultado); mapa de retorno; }}Por fim, vamos dar uma olhada na configuração do WeChat para pagamento oficial da conta e pagamento do código do código:
Espero que, durante este artigo, todos possam entender que, mesmo que você use o Java para fazer contas públicas do WeChat e o pagamento do WeChat sem usar o código de trapaça fornecido pelo GitHub, você possa desenvolver aplicativos do WeChat que atendam a você e seus clientes. Embora as demos dadas pelo WeChat sejam todos PHP, essas são todas nuvens. A linguagem de desenvolvimento é a segunda, e entender a camada subjacente que as chamadas de interface exigem é apenas um curso obrigatório para programadores.