Pembayaran WeChat telah menjadi semakin populer sekarang, dan ada banyak produk yang dapat dengan cepat mengakses pembayaran WeChat. Namun, selain menjadi nyaman, itu juga membuat kami secara bertahap mengandalkan pihak ketiga untuk melakukan sesuatu dan kehilangan kemampuan untuk berpikir secara mandiri. Kali ini, kami berencana untuk membagikan pembayaran WeChat yang telah saya kembangkan sebelumnya.
1. H5 Pembayaran Akun Resmi
Poin -Poin Kunci: Dapatkan dengan benar OpenID dan menyatukan antarmuka tunggal, memproses pemberitahuan hasil pembayaran dengan benar, dan mengkonfigurasi dengan benar direktori otorisasi pembayaran
Metode pembayaran H5 adalah metode yang banyak digunakan. Metode pembayaran ini terutama digunakan untuk halaman web dengan menu khusus di WeChat. Ini bergantung pada klien WeChat yang diinstal di ponsel. Hanya versi WeChat yang lebih tinggi mendukung pembayaran WeChat. Harap perhatikan instruksi berikut untuk mengikuti proses saya.
1. Tulis halaman untuk pembayaran, karena ini adalah tes, ini sedikit lebih sederhana.
<%@ halaman bahasa = "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 payment example</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"> <!-- <link rel = "stylesheet" type = "text/css" href = "styles.css"> -> </head> <body> <Form Action = "oAuthServlet" Metode = "POST"> Nomor pesanan: <input type = "Text" name = "orderno"/<input type = "submit" value = "h5 h5 h5 h5.> action = "scancodepayservlet? flag = createCode" method = "Post"> Nomor pesanan: <input type = "text" name = "orderno"/> <input type = "kirim" value = "Pindai kode untuk membayar"/> </form> </body> </ html>
2 Tulis servlet untuk mendapatkan kode melalui oauth
paket com.debug.weixin.servlet; impor java.io.ioException; impor java.io.printwriter; impor javax.servlet.requestdispatcher; impor javax.servlet.servletException; impor javax.servlet.http.httpservlet; impor javax.servlet.http.httpservletRequest; impor javax.servlet.http.httpservletResponse; impor com.debug.weixin.util.commonutil; impor com.debug.weixin.util.serverconfig; OAuthSerVlet kelas publik memperluas httpservlet {public void doGet (httpservletRequest, respons httpservletResponse) melempar servletException, ioException {this.dopost (permintaan, respons); } public void dopost (permintaan httpservletRequest, respons httpservletResponse) melempar servletException, ioException {string orderno = request.getParameter ("orderno"); // hubungi wechat oauth2.0 untuk mendapatkan string openId redirecturl = serverconfig.serverdomain+"/basicweixin/payserverforh5? Orderno ="+orderno; String redirectur = ""; coba {redirectur = commonutil.initopenid (redirecturl); } catch (Exception e) {// TODO Auto-Entoerated Catch Block E.PrintStackTrace (); } //System.out.println(redirecturi); // requestDispatcher dis = request.getRequestDispatcher (redirectur); //dis.forward(request, respons); response.sendredirect (redirectur); }} 3 Setelah mendapatkan kode, dapatkan OpenId melalui Redirectur dan hubungi antarmuka tunggal terpadu
paket com.debug.weixin.servlet; impor java.io.ioException; impor java.io.printwriter; impor java.util.sortedmap; impor java.util.treemap; impor javax.servlet.requestdispatcher; impor javax.servlet.servletException; impor javax.servlet.http.httpservlet; impor javax.servlet.http.httpservletRequest; impor javax.servlet.http.httpservletResponse; impor com.debug.weixin.pojo.weixinoauth2token; impor com.debug.weixin.pojo.weixinqrcode; impor com.debug.weixin.util.advancedutil; impor com.debug.weixin.util.commonutil; impor com.debug.weixin.util.configutil; impor com.debug.weixin.util.paycommonutil; Public Class PayServletForH5 memperluas httpservlet {public void doGet (httpservletRequest, respons httpservletResponse) melempar servletException, ioException {this.dopost (permintaan, respons); } public void dopost (permintaan httpservletRequest, respons httpservletResponse) melempar servletException, ioException {string orderno = request.getParameter ("orderno"); Kode string = request.getParameter ("kode"); // Dapatkan AccessToken WeixinoAuth2Token token = Advancedutil.getoAuth2AccessToken (configutil.appid, configutil.app_secrect, kode); String openId = token.getOpenId (); // Memanggil WeChat Unified Payment Interface SortedMap <Object, Object> Parameters = TREEMAP baru <Object, Object> (); parameter.put ("appid", configutil.appid); parameter.put ("mch_id", configutil.mch_id); parameter.put ("device_info", "1000"); parameter.put ("body", "order tes saya"); parameter.put ("nonce_str", paycommonutil.createNoncestr ()); parameter.put ("out_trade_no", orderno); //parameters.put("total_fee ", string.valueof (total)); parameter.put ("total_fee", "1"); parameter.put ("spbill_create_ip", request.getRemoteAddr ()); parameter.put ("notify_url", configutil.notify_url); parameter.put ("trade_type", "jsapi"); parameter.put ("OpenId", OpenID); String Sign = payCommonutil.createSign ("UTF-8", parameter); parameter.put ("tanda", tanda); String requestXml = payCommonutil.getRequestXml (parameter); Hasil string = commonutil.httpsRequestForStr (configutil.unified_order_url, "post", requestXml); System.out.println ("----------------------------------"); System.out.println (hasil); System.out.println ("----------------------------------"); request.setAttribute ("orderno", orderno); request.setAttribute ("TotalPrice", "0,01"); String payjson = ""; coba {payjson = commonutil.geth5paystr (hasil, permintaan); } catch (Exception e) {// TODO Auto-Entoerated Catch Block E.PrintStackTrace (); } //System.out.println(payjson); request.setAttribute ("UnifiedOrder", PayJson); RequestDispatcher dis = request.getRequestDispatcher ("h5pay.jsp"); dis.forward (permintaan, respons); }} Memanggil WeChat untuk menyatukan antarmuka tunggal membutuhkan perhatian pada algoritma tanda tangan. Hanya jika perhitungan tanda tangan benar, pembayaran dapat dengan lancar
string statis public geth5paystr (hasil string, permintaan httpservletRequest) melempar pengecualian {peta <string, string> peta = xmlutil.doxmlparse (hasil); Sortedmap <object, object> params = new treemap <object, object> (); params.put ("appid", configutil.appid); params.put ("timestamp", long.toString (tanggal baru (). getTime ())); params.put ("noncestr", paycommonutil.createNoncestr ()); params.put ("paket", "prepay_id ="+map.get ("prepay_id")); params.put ("SignType", configutil.sign_type); String paySign = paycommoneTil.createSign ("UTF-8", params); params.put ("paySign", paySign); // Aturan pembuatan PaySign konsisten dengan aturan pembuatan string tanda json = jsonObject.fromObject (params) .toString (); mengembalikan json; } 4 Tulis antarmuka pembayaran akhir untuk menyesuaikan pembayaran WeChat H5
<%@ halaman bahasa = "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"), function (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 ('weixinjsbridgeready', jsapicall, false); } else if (document.attachevent) {document.attachevent ('weixinjsbridgeready', jsapicall); document.attachevent ('onweixinjsbridgeready', jsapicall); }} else {jsapicall (); }} </script> </head> <body> <input type = "tombol" value = "pay" ontClick = "callpay ()"/> </body> </html> 5. Memproses pemberitahuan hasil pembayaran weChat
paket com.debug.weixin.servlet; impor java.io.bytearrayoutputStream; impor java.io.ioException; impor java.io.inputstream; impor java.io.printwriter; impor java.util.map; impor javax.servlet.servletException; impor javax.servlet.http.httpservlet; impor javax.servlet.http.httpservletRequest; impor javax.servlet.http.httpservletResponse; impor org.jdom.jdomexception; impor com.debug.weixin.util.paycommonutil; impor com.debug.weixin.util.xmlutil; Kelas Publik PayHandLerServlet memperluas httpservlet {public void doGet (httpservletRequest, respons httpservletResponse) melempar servletException, ioException {this.dopost (permintaan, respons); } public void dopost (permintaan httpservletRequest, respons httpservletResponse) melempar servletException, ioException {inputStream instream = request.getInputStream (); BytearrayoutputStream outSteam = bytearrayoutputStream baru (); byte [] buffer = byte baru [1024]; int len = 0; while ((len = instream.read (buffer))! = -1) {outsteam.write (buffer, 0, len); } outsteam.close (); instream.close (); String result = string baru (outsteam.tObyTeArray (), "UTF-8"); // Dapatkan informasi pengembalian WeChat yang memanggil peta notify_url kami <objek, objek> peta = null; coba {peta = xmlutil.doxmlparse (hasil); } catch (jdomexception e) {// todo auto-generated catch block e.printstacktrace (); } untuk (objek keyValue: peta.keyset ()) {System.out.println (keyValue+"="+Map.get (keyValue)); } if (map.get ("result_code"). ToString (). EqualSignorecase ("Success")) {// Operasi Bisnis pada Pesanan System.out.println ("--------------------------- OK"); response.getWriter (). tulis (paycommoneTil.setxml ("sukses", "")); // Beri tahu server WeChat bahwa saya menerima pesan, jangan panggil tindakan panggilan balik}}} Untuk kode di atas, banyak dari mereka merujuk ke http://blog.csdn.net/u011160656/article/details/41759195, jadi bagian kode ini tidak akan diposting. Jika Anda membutuhkannya, Anda akan mengetahuinya dengan membaca blog ini.
2. Kode pemindaian WeChat untuk dibayar (Mode 1)
Poin Kunci: Anda harus memanggil tautan panjang ke antarmuka tautan pendek dan mengkonfigurasi kode pemindaian dengan benar untuk membayar URL callback
1 menghasilkan kode QR pembayaran weChat berdasarkan nomor pesanan
Berikut adalah beberapa cara untuk menghasilkan kode QR:
paket com.debug.weixin.util; impor com.google.zxing.common.bitmatrix; impor javax.imageio.imageio; impor java.io.file; impor java.io.outputStream; impor java.io.ioException; impor java.awt.image.bufferedimage; Kelas Akhir Publik MatrixtoimageWriter {private static final int black = 0xff000000; private static final int white = 0xfffffff; matrixtoimageWriter private () {} public static bufferedImage TobufferedImage (matriks bitmatrix) {int width = matrix.getWidth (); int height = matrix.getHeight (); BufferedImage Image = BufferedImage baru (lebar, tinggi, bufferedImage.type_int_rgb); untuk (int x = 0; x <lebar; x ++) {untuk (int y = 0; y <tinggi; y ++) {image.setrgb (x, y, matrix.get (x, y)? Hitam: putih); }} mengembalikan gambar; } public static void writeToFile (matriks bitmatrix, format string, file file) melempar ioException {bufferedImage gambar = TobufferedImage (matriks); if (! imageo.write (gambar, format, file)) {lempar ioException baru ("tidak dapat menulis gambar format" + format + "ke" + file); }} public static void writeToStream (matriks bitmatrix, format string, outputStream stream) melempar ioException {bufferedImage gambar = TobufferedImage (matriks); if (! imageo.write (gambar, format, stream)) {lempar ioException baru ("tidak dapat menulis gambar format" + format); }}} Ini adalah kelas alat, dan ada metode lain untuk menampilkan kode QR pada antarmuka. CreateQrcode terutama menggunakan blok kode:
public static void createCodestream (string text, httpservletResponse response) melempar Exception {// response.setContentType ("Image/JPEG"); ServETOutputStream sos = response.getoutputStream (); Int Width = 500; tinggi int = 500; // Format Kode QR Format Format String = "jpg"; Multiformatwriter multiformatwriter = multiformatwriter baru (); Petunjuk peta = hashmap baru (); // hints.put yang dikodekan (encodehinttype.character_set, "UTF-8"); Bitmatrix bitmatrix = multiformatwriter.encode (teks, barcodeformat.qr_code, lebar, tinggi, petunjuk); // Hasilkan kode QR Matrixtoimagewriter.WriteToStream (Bitmatrix, Format, SOS); sos.close (); } 2. Untuk mengonversi tautan panjang ke tautan pendek untuk menghasilkan kode QR, tulis metode panggilan balik pembayaran kode pemindai dan hubungi antarmuka tunggal terpadu
paket com.debug.weixin.servlet; impor java.io.bytearrayoutputStream; impor java.io.ioException; impor java.io.inputstream; impor java.io.printwriter; impor java.util.date; impor java.util.map; impor java.util.sortedmap; impor java.util.treemap; impor javax.servlet.servletException; impor javax.servlet.http.httpservlet; impor javax.servlet.http.httpservletRequest; impor javax.servlet.http.httpservletResponse; impor org.jdom.jdomexception; impor com.debug.weixin.util.commonutil; impor com.debug.weixin.util.configutil; impor com.debug.weixin.util.createqrcode; impor com.debug.weixin.util.paycommonutil; impor com.debug.weixin.util.xmlutil; impor com.mongodb.dbObject; Kelas Publik ScancodepayServlet memperluas httpservlet {public void doGet (httpservletRequest, respons httpservletResponse) melempar servletException, ioException {this.dopost (permintaan, respons); } public void dopost (permintaan httpservletRequest, respons httpservletResponse) melempar servletException, ioException {string flag = request.getParameter ("flag"); if ("createCode" .Equals (flag)) {createPayCode (request, response); } else {coba {wxscancodeHandler (request, response); } catch (Exception e) {// TODO Auto-Entoerated Catch Block E.PrintStackTrace (); }}} public void createPayCode (permintaan httpservletRequest, respons httpservletResponse) {string orderno = request.getParameter ("orderno"); Sortedmap <objek, objek> paras = treemap baru <objek, objek> (); paras.put ("appid", configutil.appid); paras.put ("mch_id", configutil.mch_id); paras.put ("time_stamp", long.tostring (tanggal baru (). getTime ())); paras.put ("nonce_str", paycommonutil.createNoncestr ()); paras.put ("product_id", orderno); // nomor produk harus unik string tanda = paycommonutil.createSign ("UTF-8", paras); paras.put ("tanda", tanda); 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 ("tanda", tanda) .replace ("appid", configutil.appid) .replace ("mchid", configutil.mch_id) .replace ("productId", (string) paras.get ("product_id"). Ganti ("timestamp" ("nocvet) (" product_id "). Ganti (" timestamp "(" nocvet) ("product_id"). REPLACE ("" timestamp "(" NOCEST (") (" product_id "). REPLACE (" "timestamp" (") (" nOCEST ("product_id"). REPLACE ("" timestamp "(") ("nOCEST (" product_id "). REPLACE (" "timestamp" ("nOCEST (" "). (String) paras.get ("nonce_str")); Sortedmap <object, object> parameter = treemap baru <object, object> (); parameter.put ("appid", configutil.appid); parameter.put ("mch_id", configutil.mch_id); parameter.put ("nonce_str", paycommonutil.createNoncestr ()); parameter.put ("long_url", commonutil.urlencodeutf8 (nativeUrl)); String Sign2 = paycommoneTil.createSign ("UTF-8", parameter); parameter.put ("tanda", tanda2); String requestXml = payCommonutil.getRequestXml (parameter); String result = commonutil.httpsRequestForStr (configutil.short_url, "post", requestXml); Peta <string, string> peta = null; coba {peta = xmlutil.doxmlparse (hasil); } catch (jdomexception e) {// todo auto-generated catch block e.printstacktrace (); } catch (ioException e) {// TODO AUTO-ENCEALATED Catch Block E.PrintStackTrace (); } String returnCode = MAP.get ("return_code"); String resultCode = map.get ("result_code"); if (returnCode.equalsignorecase ("Success") && resultCode.equalSignorecase ("Success")) {string shorturl = map.get ("short_url"); // TODO Dapatkan Shorturl, tulis kode untuk menghasilkan kode QR System.out.println ("shorturl ="+shorturl); coba {createqrcode.createCodestream (shorturl, response); } catch (Exception e) {// TODO Auto-Entoerated Catch Block E.PrintStackTrace (); }}} public void wxscancodeHandler (httpservletRequest, respons httpservletResponse) melempar pengecualian {inputStream = request.getInputStream (); BytearrayoutputStream outSteam = bytearrayoutputStream baru (); byte [] buffer = byte baru [1024]; int len = 0; while ((len = instream.read (buffer))! = -1) {outsteam.write (buffer, 0, len); } outsteam.close (); instream.close (); String result = string baru (outsteam.tObyTeArray (), "UTF-8"); // Dapatkan informasi pengembalian WeChat yang memanggil peta notify_url kami <objek, objek> peta = null; coba {peta = xmlutil.doxmlparse (hasil); } catch (jdomexception e) {// todo auto-generated catch block e.printstacktrace (); } untuk (objek keyValue: peta.keyset ()) {System.out.println (keyValue+"="+Map.get (keyValue)); } String orderno = map.get ("Product_id"). ToString (); // Setelah menerima parameter permintaan, panggil antarmuka tunggal terpadu SortedMap <Object, Object> Parameter = TREEMAP baru <Object, Object> (); parameter.put ("appid", configutil.appid); parameter.put ("mch_id", configutil.mch_id); parameter.put ("device_info", "1000"); parameter.put ("body", "uji kode untuk membayar pesanan"); parameter.put ("nonce_str", paycommonutil.createNoncestr ()); parameter.put ("out_trade_no", map.get ("product_id")); //parameters.put("total_fee ", string.ValueOf (TotalPrice)); parameter.put ("total_fee", "1"); parameter.put ("spbill_create_ip", request.getRemoteAddr ()); parameter.put ("notify_url", configutil.notify_url); parameter.put ("trade_type", "asli"); parameter.put ("OpenId", Map.get ("OpenId")); String Sign = payCommonutil.createSign ("UTF-8", parameter); parameter.put ("tanda", tanda); String requestXml = payCommonutil.getRequestXml (parameter); String result2 = commonutil.httpsRequestForStr (configutil.unified_order_url, "post", requestXml); System.out.println ("----------------------------- 统一下单结果 ---------------------------"); System.out.println (result2); Peta <String, String> mm = null; coba {mm = geth5paymap (result2, request); } catch (Exception e) {// TODO Auto-Entoerated Catch Block E.PrintStackTrace (); } // string prepayid = getPrepayId (result2, request); // string returnNonestr = getReturnNonestr (result2, request); String prepayId = mm.get ("prepay_id"); String returnNoneStr = mm.get ("nonce_str") ;; Sortedmap <objek, objek> lastSign = treemap baru <objek, objek> (); lastSign.put ("return_code", "Success"); lastSign.put ("appid", configutil.appid); lastSign.put ("mch_id", configutil.mch_id); lastSign.put ("nonce_str", returnNoneStr); lastSign.put ("prepay_id", prepayid); lastSign.put ("result_code", "sukses"); lastSign.put ("key", configutil.api_key); String lastSignPara = paycommonutil.createSign ("UTF-8", LastSign); StringBuffer buf = new StringBuffer (); buf.append ("<xml>"); buf.append ("<agulat_code> Sukses </return_code>"); buf.append ("<PrepId>"+configutil.appid+"</pesid>"); buf.append ("<Ch_id>"+configutil.mch_id+"</cch_id>"); buf.append ("<Ch_id>"+configutil.mch_id+"</cch_id>"); buf.append ("<nonce_str>"+returnNoneStr+"</sce_str>"); buf.append ("<Prepay_id>"+prepayid+"</prepay_id>"); buf.append ("<Rances_code> Sukses </rence_code>"); buf.append ("<Sign>"+lastSignPara+"</dianat>"); buf.append ("</xml>"); response.getWriter (). print (buf.tostring ()); } peta publik <string, string> geth5paymap (hasil string, permintaan httpservletrequest) melempar pengecualian {peta <string, string> peta = xmlutil.doxmlparse (hasil); peta mengembalikan; }}Akhirnya, mari kita lihat konfigurasi WeChat untuk pembayaran akun resmi dan pembayaran kode pemindaian:
Saya berharap melalui artikel ini, semua orang dapat memahami bahwa bahkan jika Anda menggunakan Java untuk membuat akun publik WeChat dan pembayaran WeChat tanpa menggunakan kode curang yang disediakan oleh GitHub, Anda dapat mengembangkan aplikasi WeChat yang memuaskan Anda dan pelanggan Anda. Meskipun demo yang diberikan oleh WeChat semuanya adalah PHP, ini semua adalah awan. Bahasa pengembangan adalah yang kedua, dan memahami lapisan yang mendasari yang dibutuhkan oleh panggilan antarmuka hanyalah kursus wajib untuk pemrogram.