WeChat Payment стал все более и более популярным, и есть много продуктов, которые могут быстро получить доступ к выплате WeChat. Тем не менее, в дополнение к тому, что он удобен, это также заставляет нас постепенно полагаться на то, что третьи стороны делают вещи и терять способность мыслить самостоятельно. На этот раз мы планируем поделиться платежом WeChat, который я разработал ранее.
1. Официальный оплата счета H5 H5
Ключевые точки: правильно получить OpenID и объединить отдельный интерфейс, правильно обработать уведомления о результатах оплаты и правильно настроить каталог авторизации оплаты
Метод оплаты H5 является широко используемым методом. Этот способ оплаты в основном используется для веб -страниц с пользовательскими меню в WeChat. Он опирается на клиент WeChat, установленную на мобильном телефоне. Только более высокие версии WeChat Support 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 Photall Пример </title> <meta name = "viewport" = "width = defince-width, начальный шкал = 1.0, 1.0-то-томел = repale = 1.0, 1.0, 1.0, 1.0, 1. <link rel = "styleSheet" type = "text/css" href = "styles.css"> -> </head> <body> <form action = "oauthservlet" method = "post"> Номер заказа: <input type = "text" name = "orderno"/> <input = value = "H5 платеж"/> </> </br> </br> </br> </br> </br> </br> </br> </br> </br> </br> </br> </br> </br> </br> </br> </br> </br> action = "Scancodepayservlet? flag = createCode" method = "post"> Номер заказа: <input type = "text" name = "orderno"/> <input type = "Отправить" value = "Код для оплаты"/> </form> </body> </html>
2 Напишите сервлет для получения кода через 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; Import com.debug.weixin.util.serverconfig; открытый класс oauthservlet расширяет httpservlet {public void doget (httpservletrequest, httpservletresponse response) Throws servletexception, ioException {this.dopost (запрос, ответ); } public void dopost (httpservletrequest, httpservletresponse response) throws servletexception, ioexception {string orderno = request.getParameter ("orderno"); // Вызов weChat OAuth2.0, чтобы получить OpenID string redirecturl = serverconfig.serverdomain+"/basicweixin/payservletforh5? Orderno ="+orderno; String redirecturi = ""; try {redirecturi = commonutil.initopenid (redirecturl); } catch (Exception e) {// todo автоматически сгенерированный блок e.printstacktrace (); } //System.out.println(redirecturi); // requestDispatcher dis = request.getRequestDispatcher (redirecturi); //dis.forward(Request, ответ); response.sendredirect (redirecturi); }} 3 После получения кода получите OpenID через redirecturi и вызовите единый единый интерфейс
пакет 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; Import 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; Public Class PayServletForh5 Extens Httpservlet {public void Doget (httpservletrequest запрос, httpservletresponse response), выбрасывает Servletexception, ioException {this.dopost (запрос, ответ); } public void dopost (httpservletrequest, httpservletresponse response) throws servletexception, ioexception {string orderno = request.getParameter ("orderno"); String Code = request.getParameter ("code"); // получить AccessToken weixinoAuth2token token = arvenceutil.getoauth2accesstoken (configutil.appid, configutil.app_secrect, code); String openId = token.getOpenid (); // Вызов WeChat Unified Payment Interface CortedMap <Object, Object> Parameters = New TreeMap <Object, Object> (); parameters.put ("appid", configutil.appid); parameters.put ("mch_id", configutil.mch_id); Parameters.put ("device_info", "1000"); Parameters.put («Body», «Мой тестовый порядок»); parameters.put ("nonce_str", paycommonutil.createnoncestr ()); 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 ()); parameters.put ("notify_url", configutil.notify_url); parameters.put ("trade_type", "jsapi"); parameters.put ("openid", openid); String sign = paycommonutil.createSign ("UTF-8", параметры); Parameters.put ("знак", знак); String requestxml = 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"); String payjson = ""; try {payjson = commonutil.geth5paystr (результат, запрос); } catch (Exception e) {// todo автоматически сгенерированный блок e.printstacktrace (); } //System.out.println(payjson); request.setattribute ("Unifiedorder", Payjson); RequestDispatcher dis = request.getRequestDispatcher ("h5pay.jsp"); dis.forward (запрос, ответ); }} Вызов WeChat для объединения одного интерфейса требует внимания к алгоритму подписи. Только когда вычисление подписи правильное может быть плавно платеж
public Static String geth5paystr (Result Result, HttpservletRequest) Throws Exception {map <string, string> map = xmlutil.doxmlparse (result); SortedMap <объект, объект> params = new TreeMap <Object, Object> (); params.put ("appid", configutil.appid); params.put ("timeStamp", long.toString (new Date (). getTime ())); params.put ("uncestr", paycommonutil.createnoncestr ()); params.put ("package", "preapay_id ="+map.get ("prepay_id")); params.put ("signtype", configutil.sign_type); String paysign = paycommonutil.createSign ("utf-8", params); params.put ("paysign", paysign); // Правила генерации PaySign согласуются с правилами генерации строки знака json = jsonObject.fromObject (params) .toString (); вернуть 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 Оплата </title> <meta name = "viewport" = "width = defice-width, inembal = 1.0. 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 = "ald 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; Public Class PayHandlerservlet Extens Httpservlet {public void Doget (httpservletrequest -запрос, httpservletresponse response) Throws servletexception, ioException {this.dopost (запрос, ответ); } public void dopost (httpservletrequest, httpservletresponse response), бросает ServletException, ioException {inputStream instream = request.getInputStream (); BytearrayOutputStream outsteam = new BytearRayOutputStream (); Byte [] buffer = новый байт [1024]; int len = 0; while ((len = instream.read (buffer))! = -1) {outsteam.write (буфер, 0, len); } outsteam.close (); instream.close (); String result = new String (outsteam.tobytearray (), "utf-8"); // Получить информацию о возврате WeChat, вызывая нашу notify_url map <object, object> map = null; try {map = xmlutil.doxmlparse (result); } catch (jdomexception e) {// todo автоматически сгенерированный блок e.printstacktrace (); } for (object keyvalue: map.keyset ()) {system.out.println (keyvalue+"="+map.get (keyvalue)); } if (map.get ("result_code"). toString (). equalsIgnoreCase ("Успех")) {// Бизнес-операции на Orders System.out.println ("--------------------------- OK"); response.getWriter (). write (paycommonutil.setxml ("успех", "")); // Расскажите серверу WeChat, что я получил сообщение, не вызовите действие обратного вызова}}} Для приведенного выше кода многие из них относятся к http://blog.csdn.net/u011160656/article/details/41759195, поэтому эта часть кода не будет размещена. Если вам это нужно, вы узнаете это, прочитав этот блог.
2. WeChat Scan Code для оплаты (режим 1)
Ключевые моменты: вы должны вызвать длинную ссылку на интерфейс короткой ссылки и правильно настроить код сканирования, чтобы оплатить URL -адрес обратного вызова
1 Сгенерировать QR -код 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 Final Class MatrixtoImageWriter {Private Static Final Int Black = 0xff000000; Частный статический конечный int white = 0xffffffff; Private MatrixtoImageWriter () {} public Static BufferedImage TobufferedImage (Bitmatrix Matrix) {int width = matrix.getWidth (); int height = matrix.getheight (); BufferedImage Image = new BufferedImage (ширина, высота, bufferedimage.type_int_rgb); for (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 {buffereMage image = tobufferedImage (matrix); if (! Imageio.write (image, format, file)) {бросить новое ioException («Не удалось бы написать изображение формата» + format + »в" + file); }} public static void writeToStream (матрица Bitmatrix, формат строки, выходной поток) Throws IOException {BuffereMage Image = tobufferedImage (matrix); if (! Imageio.write (Image, Format, Stream)) {бросить новое ioException («Не может написать изображение формата» + формат); }}} Это класс инструментов, и есть еще один метод отображения QR -кода на интерфейсе. CreateQrCode в основном использует кодовые блоки:
public static void createcodestream (строковый текст, httpservletresponse response) Throws Exception {// response.setContentType ("Image/jpeg"); ServletOutputStream sos = response.getOutputStream (); int width = 500; int height = 500; // QR -код изображение формата string format = "jpg"; MultiformatTwriter MultiformatWriter = new MultiformatWriter (); Map nts = new hashmap (); // кодированный nts.put (encodehinttype.character_set, "utf-8"); Bitmatrix Bitmatrix = MultiformatWriter.encode (Text, 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 Extens Httpservlet {public void Doget (httpservletrequest запрос, httpservletresponse response) Throws ServletException, ioException {this.dopost (запрос, ответ); } public void dopost (httpservletrequest, httpservletresponse response) throws servletexception, ioexception {String flag = request.getParameter ("flag"); if ("createCode" .equals (flag)) {createPayCode (запрос, ответ); } else {try {wxscancodehandler (запрос, ответ); } catch (Exception e) {// todo автоматически сгенерированный блок e.printstacktrace (); }}} public void createPayCode (запрос httpservletRequest, httpservletresponse response) {string orderno = request.getParameter ("orderno"); SortedMap <объект, объект> paras = new TreeMap <Object, Object> (); 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.createnoncestr ()); paras.put ("product_id", orderno); // номер продукта должен быть уникальным строковым знаком = paycommonutil.createSign ("utf-8", paras); paras.put ("знак", знак); 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 ("sign", sign) .replace ("appid", configutil.appid) .replace ("mchid", configutil.mch_id) .Replace ("productId", (строка) paras.get ("product_id")). Заменить ("timestamp", (строка) paras.get ("time_stamp"). (String) paras.get ("nonce_str")); SortedMap <объект, объект> параметры = new TreeMap <Object, Object> (); parameters.put ("appid", configutil.appid); parameters.put ("mch_id", configutil.mch_id); parameters.put ("nonce_str", paycommonutil.createnoncestr ()); parameters.put ("long_url", commonutil.urlencodeutf8 (cnieturl)); String sign2 = paycommonutil.createSign ("UTF-8", параметры); Parameters.put ("sign", sign2); String requestxml = paycommonutil.getRequestxml (параметры); String result = commonutil.httpsrequestforstr (configutil.short_url, "post", requestxml); Map <string, string> map = null; try {map = xmlutil.doxmlparse (result); } catch (jdomexception e) {// todo автоматически сгенерированный блок e.printstacktrace (); } catch (ioException e) {// todo автоматически сгенерированный блок 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 получить ShortUrl, напишите код для генерации QR -кода System.out.println ("shortUrl ="+shortUrl); try {createqrcode.createcodestream (shortUrl, response); } catch (Exception e) {// todo автоматически сгенерированный блок e.printstacktrace (); }}} public void wxscancodehandler (httpservlectrequest, httpservletresponse response) throws Exception {inputStream vestream = request.getInputStream (); BytearrayOutputStream outsteam = new BytearRayOutputStream (); Byte [] buffer = новый байт [1024]; int len = 0; while ((len = instream.read (buffer))! = -1) {outsteam.write (буфер, 0, len); } outsteam.close (); instream.close (); String result = new String (outsteam.tobytearray (), "utf-8"); // Получить информацию о возврате WeChat, вызывая нашу notify_url map <object, object> map = null; try {map = xmlutil.doxmlparse (result); } catch (jdomexception e) {// todo автоматически сгенерированный блок e.printstacktrace (); } for (object keyvalue: map.keyset ()) {system.out.println (keyvalue+"="+map.get (keyvalue)); } String orderno = map.get ("product_id"). ToString (); // После получения параметра запроса вызовите унифицированный отдельный интерфейс CortedMap <Object, Object> Parameters = New TreeMap <Object, Object> (); parameters.put ("appid", configutil.appid); parameters.put ("mch_id", configutil.mch_id); Parameters.put ("device_info", "1000"); Parameters.put («Body», «код испытаний для оплаты заказа»); parameters.put ("nonce_str", paycommonutil.createnoncestr ()); 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 ()); parameters.put ("notify_url", configutil.notify_url); parameters.put ("trade_type", "Native"); parameters.put ("openid", map.get ("openid")); String sign = paycommonutil.createSign ("UTF-8", параметры); Parameters.put ("знак", знак); String requestxml = paycommonutil.getRequestxml (параметры); String result2 = commonutil.httpsrequestforstr (configutil.unified_order_url, "post", requestxml); System.out.println ("----------------------------- 统一下单结果 ---------------------------"); System.out.println (Result2); Карта <string, string> mm = null; try {mm = geth5paymap (result2, request); } catch (Exception e) {// todo автоматически сгенерированный блок e.printstacktrace (); } // string predayId = getPrepAyid (result2, Question); // string returnnonest = getReturnNonest (result2, request); String predayId = mm.get ("prepay_id"); String returnnonest = 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", returnnonest); lastsign.put ("prepay_id", predayid); lastSign.put ("result_code", "успех"); lastSign.put ("key", configutil.api_key); String lastSignPara = paycommonutil.createSign ("utf-8", last-sysign); StringBuffer buf = new StringBuffer (); buf.append ("<xml>"); buf.append ("<return_code> успех </return_code>"); buf.append ("<papd>"+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>"+returnnonest+"</nonce_str>"); buf.append ("<prepay_id>"+predayid+"</preapay_id>"); buf.append ("<sesult_code> успех </result_code>"); buf.append ("<cint>"+lastSignPara+"</sign>"); buf.append ("</xml>"); response.getWriter (). print (buf.toString ()); } public map <string, string> geth5paymap (string result, httpservletrequest) throws exception {map <string, string> map = xmlutil.doxmlparse (result); карта возврата; }}Наконец, давайте посмотрим на конфигурацию WeChat для официальной оплаты учетной записи и оплаты кода сканирования:
Я надеюсь, что благодаря этой статье каждый может понять, что даже если вы используете Java для создания публичных учетных записей WeChat и оплаты WeChat без использования кода мошенничества, предоставленного GitHub, вы можете разработать приложения WeChat, которые удовлетворяют вас и вашим клиентам. Хотя демо, данные WeChat, являются PHP, это все облака. Язык развития является вторым, а понимание основного уровня, который требует интерфейсных вызовов, является лишь обязательным курсом для программистов.