WeChat 결제는 점점 더 인기를 얻었으며 WeChat 결제에 빠르게 액세스 할 수있는 많은 제품이 있습니다. 그러나 편리 할뿐만 아니라 우리는 점차적으로 제 3 자에게 일을하고 독립적으로 생각할 수있는 능력을 잃게됩니다. 이번에는 이전에 개발 한 WeChat 지불을 공유 할 계획입니다.
1. H5 공식 계정 지불
키 포인트 : OpenID를 올바르게 얻고 단일 인터페이스를 통합하고 결제 결과 알림을 올바르게 처리하며 지불 인증 디렉토리를 올바르게 구성합니다.
H5의 지불 방법은 널리 사용되는 방법입니다. 이 결제 방법은 주로 WeChat에 사용자 정의 메뉴가있는 웹 페이지에 사용됩니다. 휴대폰에 설치된 WeChat 클라이언트에 의존합니다. WeChat을 지원하는 더 높은 버전의 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 과도기 // en"> <html> <head> <base href = "<%= basepath%>"> <title> wechat 결제 예 </title> <meta name = "viewport"contment = "width = 1.0 maverimume = 1.0 <!-<link rel = "stylesheet"type = "text/css"href = "styles.css">-> </head> <body> <form action = "oauthservlet"method = "post"> 주문 번호 : <입력 유형 = "orderno"/> <input type = "value"h5 지불 "/form> </br> action = "scancodepayservlet? flag = createcode"method = "post"> 주문 번호 : <input type = "text"name = "orderno"/> <input type = "제출"value = "코드를 지불하기 위해 코드를 스캔합니다"/</form> </body> </html>
2 Oauth를 통해 코드를 얻기위한 서블릿을 작성하십시오
패키지 com.debug.weixin.servlet; import java.io.ioexception; import java.io.printwriter; import javax.servlet.requestdispatcher; javax.servlet.servletexception import; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; com.debug.weixin.util.commonutil import; com.debug.weixin.util.serverconfig import; Public Class Oauthservlet는 httpservlet {public void doget (httpservletrequest 요청, httpservletresponse 응답)을 servletexception, ioexception {this.dopost (요청, 응답); } public void dopost (httpservletRequest 요청, httpservletResponse 응답) servletexception, ioexception {string orderno = request.getParameter ( "OrderNo"); // weChat OAuth2.0을 호출하려면 OpenID String redirectUrl = serverConfig.serverdomain+"/Basicweixin/PayserVletforh5? orderno ="+OrderNo; 문자열 redirecturi = ""; try {redirecturi = commonutil.initopenid (redirecturl); } catch (예외 e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); } //system.out.println(redirecturi); // requestDispatcher dis = request.getRequestDispatcher (redirecturi); //dis.forward(request, 응답); 응답 .sendredirect (Redirecturi); }} 3 코드를 얻은 후 Redirecturi를 통해 OpenID를 얻고 통합 단일 인터페이스를 호출하십시오.
패키지 com.debug.weixin.servlet; import java.io.ioexception; import java.io.printwriter; java.util.sortedMap import; Java.util.treemap import; import javax.servlet.requestdispatcher; javax.servlet.servletexception import; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; com.debug.weixin.pojo.weixinoauth2token import; import com.debug.weixin.pojo.weixinqrcode; import com.debug.weixin.util.advancedutil; com.debug.weixin.util.commonutil import; com.debug.weixin.util.configutil import; com.debug.weixin.util.paycommonutil import; Public Class PayserVletforh5는 httpservlet {public void doget (httpservletrequest 요청, httpservletreponse responsk)을 servletexception, ioexception {this.dopost (요청, 응답); } public void dopost (httpservletRequest 요청, httpservletResponse 응답) servletexception, ioexception {string orderno = request.getParameter ( "OrderNo"); 문자열 코드 = request.getParameter ( "Code"); // accesstoken get to weixinoauth2token token = advancedutil.getoauth2accesstoken (configutil.appid, configutil.app_secrect, code); String OpenID = token.getOpenid (); // WeChat Unified 결제 인터페이스를 호출 SortedMap <객체, 객체> 매개 변수 = new Treemap <객체, 개체> (); 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.createnoncest ()); 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); 문자열 부호 = paycommonutil.createsign ( "UTF-8", 매개 변수); Parameters.put ( "부호", 부호); 문자열 requestXml = payCommonUtil.getRequestXml (매개 변수); 문자열 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"); 문자열 payjson = ""; try {payjson = commonutil.geth5paystr (result, request); } catch (예외 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 (문자열 결과, httpservletrequest 요청) 예외 {map <string, string> map = xmlutil.doxmlparse (결과); SortedMap <객체, 개체> params = new Treemap <개체, 개체> (); params.put ( "appid", configutil.appid); params.put ( "timestamp", long.tostring (new date (). gettime ())); params.put ( "noncest", paycommonutil.createnoncest ()); params.put ( "package", "prepay_id ="+map.get ( "prepay_id")); params.put ( "signtype", configutil.sign_type); 문자열 paysign = paycommonutil.createsign ( "utf-8", params); params.put ( "PaySign", PaySign); // PaySign의 생성 규칙은 부호 string의 생성 규칙과 일치합니다. 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 전환 // en"> <html> <head> <base href = "<%= basepath%>"> <title> wechat h5 지불 </tita name = "viewport"contment = "width = 1.0 maxiume = 1.0, cale = 1.0, cale = 1.0. <script type = "text/javaScript"> function jsapicall () {weixinjsbridge.invoke ( 'getBrandwcpayRequest', <%= (string) request.getAttribute ( "Uniediorder")%>, function (res) {weixinjsbridge.log (res.err_msg); //alert(Res.err_code+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> <입력 유형 = "버튼"vale = "pay"onclick = "callpay ()"/> </body> </html> 5. WeChat 결제 결과 알림 처리
패키지 com.debug.weixin.servlet; import java.io.BytearRayoutputStream; import java.io.ioexception; import java.io.inputstream; import java.io.printwriter; java.util.map import; javax.servlet.servletexception import; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import org.jdom.jdomexception; com.debug.weixin.util.paycommonutil import; import com.debug.weixin.util.xmlutil; Public Class Payhandlerservlet는 httpservlet {public void doget (httpservletrequest request, httpservletresponse 응답)을 servletexception, ioexception {this.dopost (요청, 응답); } public void dopost (httpservletRequest 요청, httpservletResponse 응답) servletexception, ioexception {inputStream instream = request.getInputStream (); BytearRayoutputStream OutSteam = New ByTearRayoutputStream (); 바이트 [] 버퍼 = 새로운 바이트 [1024]; int len = 0; while ((len = instream.read (buffer))! = -1) {outsteam.write (buffer, 0, len); } outsteam.close (); instream.close (); String result = new String (outsteam.tobytearRay (), "UTF-8"); // weChat의 반환 정보를 얻습니다. try {map = xmlutil.doxmlparse (결과); } 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 ( "success")) {Orders System.out.println ( "--------------------------------------------------------------------------------------------- response.getWriter (). 쓰기 (PayCommonUtil.setxml ( "success", "")); // WeChat 서버에 메시지를 받았다고 말하고 콜백 작업을 호출하지 마십시오}}} 위의 코드의 경우 많은 코드의 경우 http://blog.csdn.net/u011160656/article/details/41759195를 참조하므로 코드 의이 부분은 게시되지 않습니다. 필요한 경우이 블로그를 읽음으로써 알게 될 것입니다.
2. WeChat 스캔 코드 지불 (모드 1)
키 포인트 : 짧은 링크 인터페이스에 대한 긴 링크를 호출하고 콜백 URL을 지불하도록 스캔 코드를 올바르게 구성해야합니다.
1 주문 번호에 따라 WeChat 결제 QR 코드 생성
QR 코드를 생성하는 몇 가지 방법은 다음과 같습니다.
패키지 com.debug.weixin.util; import com.google.zxing.common.bitmatrix; import javax.imageio.imageio; import java.io.file; import java.io.outputStream; import java.io.ioexception; java.awt.image.bufferedimage import; 공개 최종 클래스 MatrixToImageWriter {private static final int black = 0xff000000; 개인 정적 최종 int white = 0xfffffff; private matrixtoimagewriter () {} public static bufferedimage tobufferedimage (bitmatrix matrix) {int width = matrix.getWidth (); int height = matrix.getheight (); BufferedImage image = 새로운 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 matrix, 문자열 형식, 파일 파일)은 ioexception {bufferedImage image = tobufferedImage (matrix); if (! imageio.write (image, format, file)) {trash new ioException ( "" + format + "형식의 이미지를" + 파일에 쓸 수 없음); }} public static void writeToStream (bitmatrix matrix, String format, outputStream 스트림)은 ioException {bufferedImage image = TobufferedImage (matrix); if (! imageio.write (image, format, stream)) {Throw New IoException ( "형식 이미지를 쓸 수 없음" + 형식); }}} 이것은 도구 클래스이며 인터페이스에 QR 코드를 표시하는 또 다른 방법이 있습니다. CreateQrCode는 주로 코드 블록을 사용합니다.
public static void createCodestream (문자열 텍스트, httpservletResponse 응답)은 예외 {// response.setContentType ( "image/jpeg"); ServletOutputStream SOS = response.getOutputStream (); int 너비 = 500; int 높이 = 500; // QR 코드 이미지 형식 문자열 형식 = "jpg"; multiformatwriter multiformatwriter = new multiformatwriter (); 지도 힌트 = new Hashmap (); // 인코딩 된 hints.put (encodeHintType.character_set, "utf-8"); bitmatrix bitmatrix = multiformatwriter.encode (텍스트, barcodeformat.qr_code, 너비, 높이, 힌트); // QR 코드 생성 matrixtoImageWriter.writeToStream (bitmatrix, format, sos); sos.close (); } 2. 긴 링크를 짧은 링크로 변환하여 QR 코드를 생성하려면 스캔 코드 결제 콜백 메소드를 작성하고 Unified Single Interface를 호출하십시오.
패키지 com.debug.weixin.servlet; import java.io.BytearRayoutputStream; import java.io.ioexception; import java.io.inputstream; import java.io.printwriter; import java.util.date; java.util.map import; java.util.sortedMap import; Java.util.treemap import; javax.servlet.servletexception import; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import org.jdom.jdomexception; com.debug.weixin.util.commonutil import; com.debug.weixin.util.configutil import; import com.debug.weixin.util.createqrcode; com.debug.weixin.util.paycommonutil import; import com.debug.weixin.util.xmlutil; import com.mongodb.dbobject; 공개 클래스 scancodepayservlet는 httpservlet {public void doget (httpservletrequest 요청, httpservletresponse 응답)을 servletexception, ioexception {this.dopost (요청, 응답); } public void dopost (httpservletRequest 요청, httpservletResponse 응답) servletexception, ioexception {string flag = request.getParameter ( "flag"); if ( "createCode".Equals (flag)) {createPayCode (요청, 응답); } else {try {wxscancodehandler (요청, 응답); } catch (예외 e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); }}} public void createPayCode (httpservletRequest request, httpservletResponse 응답) {string orderno = request.getParameter ( "OrderNo"); SortedMap <객체, 개체> paras = new Treemap <개체, 개체> (); 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.createnoncest ()); paras.put ( "product_id", orderno); // 제품 번호는 고유 한 문자열 부호 = paycommonutil.createsign ( "utf-8", paras)이어야합니다. paras.put ( "부호", 부호); 문자열 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", (string) paras.get ( "product_id")). Replar ( "timestamp", (string) paras.get ( "time_stamp")). (문자열) paras.get ( "nonce_str")); SortedMap <객체, 개체> 매개 변수 = new Treemap <개체, 개체> (); parameters.put ( "appid", configutil.appid); parameters.put ( "mch_id", configutil.mch_id); parameters.put ( "nonce_str", paycommonutil.createnoncest ()); parameters.put ( "long_url", commonutil.urlencodeutf8 (avatier)); 문자열 sign2 = paycommonutil.createsign ( "UTF-8", 매개 변수); Parameters.put ( "부호", sign2); 문자열 requestXml = payCommonUtil.getRequestXml (매개 변수); 문자열 result = commonutil.httpsRequestForstr (configutil.short_url, "post", requestxml); map <string, String> map = null; try {map = xmlutil.doxmlparse (결과); } catch (jdomexception e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); } catch (ioexception e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); } 문자열 returnCode = map.get ( "return_code"); 문자열 resultCode = map.get ( "result_code"); if (returnCode.equalSeignoreCase ( "success") && resultCode.equalSignoreCase ( "success")) {String ShortUrl = map.get ( "short_url"); // TODO GET GET GET GET GET GET QR 코드 System.out.println ( "shorturl ="+shorturl); try {createqrcode.createCodestream (shorturl, response); } catch (예외 e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); }}} public void wxscancodehandler (httpservletrequest request, httpservletresponse responsk) 예외 {inputStream instream = request.getInputStream (); BytearRayoutputStream OutSteam = New ByTearRayoutputStream (); 바이트 [] 버퍼 = 새로운 바이트 [1024]; int len = 0; while ((len = instream.read (buffer))! = -1) {outsteam.write (buffer, 0, len); } outsteam.close (); instream.close (); String result = new String (outsteam.tobytearRay (), "UTF-8"); // weChat의 반환 정보를 얻습니다. try {map = xmlutil.doxmlparse (결과); } 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 (); // 요청 매개 변수를 수신 한 후 통합 된 단일 인터페이스 SortedMap을 호출하십시오. SortedMap <개체> 매개 변수 = new Treemap <object, object> (); parameters.put ( "appid", configutil.appid); parameters.put ( "mch_id", configutil.mch_id); parameters.put ( "device_info", "1000"); parameters.put ( "Body", "Test Code to Pay Order"); parameters.put ( "nonce_str", paycommonutil.createnoncest ()); 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", "avire"); parameters.put ( "OpenID", map.get ( "OpenID")); 문자열 부호 = paycommonutil.createsign ( "UTF-8", 매개 변수); Parameters.put ( "부호", 부호); 문자열 requestXml = payCommonUtil.getRequestXml (매개 변수); 문자열 result2 = commonutil.httpsRequestForstr (configutil.unified_order_url, "post", requestxml); system.out.println ( "------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------AOIOOOOOOUOOOYAYS함 ("------------------------- System.out.println (result2); Map <String, String> mm = null; try {mm = geth5paymap (result2, request); } catch (예외 e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); } // string prepayId = getPrepayId (result2, request); // String returnNonest = getReturnNonest (result2, request); String prepayid = mm.get ( "prepay_id"); 문자열 returnnonest = mm.get ( "nonce_str") ;; SortedMap <객체, 개체> lastSign = new Treemap <개체, 개체> (); lastSign.put ( "return_code", "success"); lastSign.put ( "appid", configutil.appid); lastSign.put ( "mch_id", configutil.mch_id); LastSign.put ( "nonce_str", returnnonest); lastSign.put ( "pleray_id", propayid); lastSign.put ( "result_code", "success"); lastSign.put ( "key", configutil.api_key); String lastSignpara = payCommonUtil.CreatesIgn ( "UTF-8", LastSign); StringBuffer buf = new StringBuffer (); buf.append ( "<xml>"); buf.append ( "<return_code> 성공 </return_code>"); buf.append ( "<pupid>"+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 ( "<propay_id>"+propayid+"</propay_id>"); buf.append ( "<result_code> success </result_code>"); buf.append ( "<sign>"+lastSignpara+"</sign>"); buf.append ( "</xml>"); response.getWriter (). print (buf.toString ()); } public map <string, string> geth5paymap (문자열 결과, httpservletrequest 요청) 예외 {map <string, string> map = xmlutil.doxmlparse (결과); 리턴 맵; }}마지막으로 공식 계정 결제 및 스캔 코드 결제에 대한 WeChat 구성을 살펴 보겠습니다.
이 기사를 통해 모든 사람이 Java를 사용하여 Github에서 제공하는 부정 행위 코드를 사용하지 않고 WeChat 공개 계정 및 WeChat 결제를하더라도 귀하와 고객을 만족시키는 WeChat 응용 프로그램을 개발할 수 있다는 것을 이해할 수 있기를 바랍니다. WeChat이 제공 한 데모는 모두 PHP이지만 모두 구름입니다. 개발 언어는 두 번째이며 인터페이스 호출이 요구하는 기본 계층을 이해하는 것은 프로그래머를위한 강제 과정 일뿐입니다.