ในส่วนนี้เราจะเขียนตัวอย่างง่ายๆเพื่อทดสอบกระบวนการชำระเงิน Yibao หลังจากทำความคุ้นเคยกับกระบวนการนี้เราจะทำการพัฒนาจริง เนื่องจากเป็นตัวอย่างฉันไม่ได้พิจารณารูปแบบการออกแบบบางอย่าง แต่เพียงแค่ใช้ฟังก์ชั่นการชำระเงินโดยตรง ในการใช้ฟังก์ชั่นการชำระเงิน Yibao จำเป็นต้องมี API ที่ให้ไว้กับเรา ดังนั้นคำถามคือสิ่งที่สำคัญที่สุดเมื่อใช้แพลตฟอร์มการชำระเงินของบุคคลที่สามคือการได้รับ API ของแพลตฟอร์ม ก่อนอื่นเราต้องได้รับ API และเอกสารการพัฒนาของพวกเขาจากนั้นเราสามารถทำการพัฒนาเพิ่มเติมได้
1. รับ API ของ Yibao
ขั้นตอนแรกในการรับ API คือการลงทะเบียนบัญชีใน Yibao บัญชีนี้เป็นบัญชีของผู้ค้า หลังจากผู้ซื้อจ่ายเขาจะฝากเงินเข้าบัญชีและผู้ค้าจะถอนมันไปยังบัตรธนาคารด้วยตัวเอง Yibao จะเรียกเก็บค่าธรรมเนียมการจัดการที่แน่นอนในระหว่างกระบวนการถอน นี่คือรูปแบบกำไรของ Yibao อย่างไรก็ตามข้อกำหนดเบื้องต้นสำหรับการลงทะเบียนที่ประสบความสำเร็จคือคุณต้องมีเว็บไซต์หรือ บริษัท บาร่าบารา ฯลฯ อย่างไรก็ตามคุณต้องมีคุณสมบัติที่จะสมัคร Yibao จะตรวจสอบจุดนี้ เมื่อคุณพบกันเท่านั้นมันจะช่วยให้คุณลงทะเบียนและจัดหาอินเทอร์เฟซให้คุณได้ ไม่ใช่ทุกคนที่สามารถลงทะเบียนได้ ฉันใช้มันเช่นเดียวกับคนอื่น ๆ ที่ลงทะเบียน แต่ฉันไม่มีอะไรเลย ... ฉันไม่สามารถลงทะเบียนได้ ... ฉันรู้เรื่องนี้ แต่โดยทั่วไปเมื่อพัฒนาใน บริษัท จะไม่มีปัญหานี้ จะต้องมีบัญชี สิ่งที่สำคัญที่สุดคือการควบคุมกระบวนการพัฒนาและเทคโนโลยีที่เกี่ยวข้อง
2. ทดสอบกระบวนการชำระเงิน
ด้วย API อย่างเป็นทางการและเอกสารทางเทคนิคคุณสามารถเริ่มพัฒนาได้ ที่นี่เราเขียนตัวอย่างง่ายๆเพื่อทดสอบกระบวนการชำระเงิน Yibao โครงสร้างของการสาธิตนั้นง่ายมาก servlet ตัวกรองหน้า JSP สองหน้าและคลาสเครื่องมือที่เข้ารหัส Servlet เกี่ยวข้องกับฝั่งเซิร์ฟเวอร์ Yibao เราทำการประมวลผลบางอย่างที่เกี่ยวข้องกับอินเทอร์เฟซ Yibao ตัวกรองถูกใช้เพื่อจัดการกับปัญหาที่เป็นไปไม่ได้ของจีน หนึ่งในสอง JSP คือหน้าส่วนหน้า
ก่อนอื่นวิเคราะห์กระบวนการคำขอการชำระเงินดังที่แสดงด้านล่าง:
ตกลงวิเคราะห์รหัสที่เกี่ยวข้องในการสาธิตโดยละเอียด:
2.1 หน้าทดสอบแผนกต้อนรับส่วนหน้า
ก่อนอื่นมาดูรหัสเฉพาะของหน้าแผนกต้อนรับส่วนหน้า index.jsp
<%@ page language = "java" pageencoding = "utf-8"%> <! doctype html public "-// w3c // dtd html 4.01 การเปลี่ยนผ่าน // en"> <html> <head> <title> action = "$ {pageContext.Request.ContextPath}/servlet/payservlet" method = "post"> หมายเลขคำสั่งซื้อสำหรับการช็อปปิ้งนี้ <อินพุตประเภท = "text" name = "p2_order"/> <br> เงิน <อินพุตประเภท = "text" name = "p3_amt" value = "0.01"/> name = "pd_frpid"> ธนาคารก่อสร้าง <อินพุตประเภท = "วิทยุ" value = "ccb-net" name = "pd_frpid"> <br> <อินพุต type = "ส่ง" value = "ส่ง"/> <อินพุต type = "hidden" value = "pay" name = "สถานะ"จากหน้า JSP ด้านบนเราจะเห็นว่าค่าแอตทริบิวต์ชื่อในแท็กอินพุตเหล่านี้แปลกมาก pi_function (i = 0,1,2, …, 9) และแน่นอนว่าฉันมีค่าอื่น สิ่งนี้ต้องอ้างถึงเอกสารอย่างเป็นทางการของ Yibao ชื่อเหล่านี้แสดงถึงแอตทริบิวต์ที่สอดคล้องกันและจะถูกส่งผ่านไปยัง Sevlet สำหรับการประมวลผล เกี่ยวกับค่าแอตทริบิวต์เหล่านี้ฉันมีรูปภาพดังนี้:
ชื่อพารามิเตอร์เหล่านี้บางส่วนจะถูกส่งจากแผนกต้อนรับในโครงการจริงเช่นหมายเลขคำสั่งซื้อที่เขียนไว้ข้างต้นค่าใช้จ่ายในการจ่ายเท่าไหร่และสิ่งเหล่านี้จะถูกนำไปใช้เมื่อได้รับการยืนยันคำสั่งซื้อ หากจำเป็นต้องมีพารามิเตอร์อื่น ๆ จะต้องระบุไว้ใน servlet หากไม่จำเป็นต้องใช้ฟิลด์พวกเขาอาจว่างเปล่า ที่ว่างเปล่าที่นี่ไม่ได้เป็นโมฆะ แต่ "" ซึ่งจะถูกกล่าวถึงใน servlet ในภายหลัง
มาดูค่ามูลค่าที่สอดคล้องกันในสองธนาคาร Yibao จะให้มูลค่ามูลค่าของธนาคารทั้งหมดที่สนับสนุน สิ่งเหล่านี้ได้รับการแก้ไขและไม่สามารถแก้ไขได้ นี่คือสองธนาคารเพื่อทดสอบผลกระทบ
ฟิลด์ที่ซ่อนอยู่สุดท้ายใช้เพื่อตัดสินใน servlet ไม่ว่าจะเป็นการชำระเงินหรือผลตอบแทนหลังจากการชำระเงินสำเร็จจะมีการอธิบายใน Sevlet ด้านล่าง
2.2 คำขอจัดการ
Servlet ส่วนใหญ่จัดการคำขอที่เกี่ยวข้องกับ Yibao มีสองส่วนของเนื้อหา ส่วนหนึ่งคือการส่งข้อความธรรมดาและข้อความรหัสไปยัง Yibao และอีกส่วนหนึ่งคือการตัดสินข้อความธรรมดาและข้อความรหัสที่ส่งโดย Yibao มาดูรหัสการใช้งานเฉพาะในการสาธิต:
PAYSERVLET ระดับสาธารณะขยาย HTTPSERVLET {โมฆะสาธารณะ DOGET (คำขอ HTTPSERVLETREQUEST, การตอบสนอง HTTPSERVLETRESSSESSESS) โยน ServleTexception, iOException {สถานะสตริง = request.getParameter ("สถานะ"); if (status.equals ("pay")) {// ฟิลด์ที่ซ่อนอยู่ใน index.jsp จ่ายดังนั้นส่วนการชำระเงินจะถูกประมวลผล // คีย์การเข้ารหัสถูกใช้ในอัลกอริทึมการเข้ารหัสและจัดทำโดยตัวกลางการชำระเงิน ผู้ค้าแต่ละรายมีคีย์วัลสตริงที่ไม่ซ้ำกัน = "W0P75WMZ203FR46R5I70V556WHFA94J14YW5J6VUH4YO3NRL5JSQF3C41677"; // 1: กำหนดค่าให้กับพารามิเตอร์ พารามิเตอร์เหล่านี้ (เช่นข้อความธรรมดา) ถูกกำหนดไว้ในเอกสารที่จัดทำโดย Yibao เราไม่สามารถเปลี่ยนชื่อสตริง p0_cmd = formatstring ("ซื้อ"); สตริง p1_merid = formatString ("10000940764"); String p2_order = formatString (request.getParameter ("p2_order")); สตริง p3_amt = formatString (request.getParameter ("P3_AMT")); สตริง p4_cur = formatstring ("cny"); สตริง p5_pid = ""; สตริง p6_pcat = ""; สตริง p7_pdesc = ""; String p8_url = "http://www.tongji.edu.cn"; // นี่คือหน้าคุณข้ามไปหลังจากการชำระเงินสำเร็จ คุณสามารถตั้งค่าเป็นโฮมเพจของห้างสรรพสินค้า การสาธิตนี้เพียงพอที่จะใช้หน้าแรกของมหาวิทยาลัย Tongji ... String P9_SAF = "0"; สตริง pa_mp = ""; String PD_FRPID = FormatString (request.getParameter ("PD_FRPID")); pd_frpid = pd_frpid.touppercase (); String pr_needResponse = "0"; สตริง hmac = formatstring (""); // HMAC ใช้ในการจัดเก็บ ciphertext/*ธรรมดาทั้งหมดด้านบนจะถูกห่อด้วยวิธี formatstring วิธีการด้านล่างส่วนใหญ่แปลง null เป็น "" *เพราะ null ไม่สามารถแปลงเป็น ciphertext *// แก้ปัญหาความปลอดภัยของข้อมูล: เข้ารหัสข้อความธรรมดา ---> ciphertext แล้วส่งทั้งข้อความธรรมดาและ ciphertext ไปยัง yibao // Merchant และ Yibao ใช้คีย์เดียวกันเมื่อเข้ารหัส) // ผนวกข้อมูล PlainText ไปยัง StringBuffer โปรดทราบว่าลำดับของการผนวกไม่สามารถเปลี่ยนแปลงได้มิฉะนั้น ciphertext ที่สร้างขึ้นจะแตกต่างกัน // คุณต้องเขียนอย่างเคร่งครัดตามชื่อของเอกสารอย่างเป็นทางการของ Yibao เนื่องจาก Yibao ถูกเพิ่มตามคำสั่งซื้อในเอกสาร infoBuffer = new StringBuffer (); InfoBuffer.Append (P0_CMD); InfoBuffer.Append (P1_Merid); InfoBuffer.Append (P2_ORDER); infoBuffer.Append (p3_amt); InfoBuffer.Append (P4_CUR); InfoBuffer.Append (P5_PID); InfoBuffer.Append (P6_PCAT); InfoBuffer.Append (P7_PDESC); InfoBuffer.Append (P8_URL); InfoBuffer.Append (P9_SAF); InfoBuffer.Append (PA_MP); InfoBuffer.Append (PD_FRPID); infoBuffer.Append (pr_needresponse); // ciphertext ที่เข้ารหัสถูกเก็บไว้ใน HMAC และอัลกอริทึมการเข้ารหัส Yibao จะให้มันเพราะมันยังต้องใช้อัลกอริทึมเดียวกัน HMAC = Digestutil.hmacsign (infobuffer.toString () // จัดเก็บทั้งข้อความข้อความธรรมดาและข้อความรหัสใน request.setAttribute request.setAttribute ("p0_cmd", p0_cmd); request.setAttribute ("p1_merid", p1_merid); request.setAttribute ("p2_order", p2_order); request.setAttribute ("p3_amt", p3_amt); request.setAttribute ("p4_cur", p4_cur); request.setAttribute ("p5_pid", p5_pid); request.setAttribute ("p6_pcat", p6_pcat); request.setAttribute ("p7_pdesc", p7_pdesc); request.setAttribute ("p8_url", p8_url); request.setAttribute ("p9_saf", p9_saf); request.setAttribute ("PA_MP", PA_MP); request.setAttribute ("PD_FRPID", PD_FRPID); request.setAttribute ("pr_needresponse", pr_needresponse); request.setAttribute ("HMAC", HMAC); System.out.println ("HMAC->" + HMAC); // ข้ามไปยัง reqpay.jsp และส่งข้อมูลนี้ไปยัง yibao request.getRequestDispatcher ("/reqpay.jsp") ส่งต่อ (คำขอ, ตอบกลับ); } อื่นถ้า (status.equals ("ความสำเร็จ")) {// สิ่งที่มาจาก yibao คือความสำเร็จการประมวลผลส่งคืนชิ้นส่วนการตรวจสอบ printwriter out = response.getWriter (); String KeyValue = "W0P75WMZ203FR46R5I70V556WHFA94J14YW5J6VUH4YO3NRL5JSQF3C41677"; // รับสตริงธรรมดาทั้งหมด r0_cmd = formatstring (request.getParameter ("R0_CMD")); สตริง p1_merid = request.getParameter ("p1_merid"); String R1_Code = FormatString (request.getParameter ("R1_Code")); String R2_trxid = formatString (request.getParameter ("R2_TRXID")); String R3_AMT = FormatString (request.getParameter ("R3_AMT")); String R4_Cur = FormatString (request.getParameter ("R4_Cur")); String R5_PID = สตริงใหม่ (formatString (request.getParameter ("R5_PID")). getBytes ("ISO-8859-1"), "UTF-8"); String r6_order = formatString (request.getParameter ("R6_Order")); String R7_UID = formatString (request.getParameter ("R7_UID")); String R8_MP = สตริงใหม่ (formatString (request.getParameter ("R8_MP")). getBytes ("ISO-8859-1"), "UTF-8"); String R9_BType = FormatString (request.getParameter ("R9_BTYPE")); // ผนวกข้อมูลไปยังสตริง plaintext hmac = formatstring (request.getParameter ("HMAC")); StringBuffer infoBuffer = new StringBuffer (); InfoBuffer.Append (P1_Merid); InfoBuffer.Append (R0_CMD); InfoBuffer.Append (R1_Code); InfoBuffer.Append (R2_TRXID); InfoBuffer.Append (R3_AMT); InfoBuffer.Append (R4_CUR); InfoBuffer.Append (R5_PID); InfoBuffer.Append (R6_ORDER); InfoBuffer.Append (R7_UID); InfoBuffer.Append (R8_MP); InfoBuffer.Append (R9_BTYPE); // เข้ารหัสสตริงธรรมดาที่ส่งคืน md5 = digestutil.hmacsign (infobuffer.toString (), keyValue); // ตรวจสอบว่า ciphertext ที่เข้ารหัสมีค่าเท่ากับบูลีนข้อมูลลายเซ็นข้อมูลที่ส่งผ่าน isok = md5.equals (HMAC); if (isok && r1_code.equals ("1")) {// r1_code คือ 1 เพื่อระบุความสำเร็จ // เปลี่ยนสถานะการสั่งซื้อที่ประสบความสำเร็จเป็นการชำระเงินและแสดงข้อมูลความสำเร็จในการชำระเงินให้กับผู้ใช้ // โทรอินเตอร์เฟสบริการอีเมล, SMS ส่งบริการ ฯลฯ } else {out.println ("ล้มเหลว !!!"); }}} โมฆะสาธารณะ dopost (คำขอ httpservletRequest, การตอบสนอง httpservletResponse) พ่น ServleTexception, ioException {doGet (คำขอ, การตอบกลับ); } string formatstring (ข้อความสตริง) {if (text == null) {return ""; } ส่งคืนข้อความ; -2.3 อัลกอริทึมการเข้ารหัส
อัลกอริทึมการเข้ารหัสที่ใช้ในการแปลงข้อความธรรมดาเป็น ciphertext นั้นจัดทำโดย Yibao เราจำเป็นต้องใช้มันเพื่อแปลงข้อความธรรมดาเป็น ciphertext อัลกอริทึมมีดังนี้:
คลาสสาธารณะ DigestUtil {สตริงคงที่ส่วนตัว encodingCharset = "UTF-8"; สตริงคงที่สาธารณะ hmacsign (string avalue, string akey) {byte k_ipad [] = byte ใหม่ [64]; byte k_opad [] = byte ใหม่ [64]; ไบต์ keyb []; ค่าไบต์ []; ลอง {keyb = akey.getBytes (encodingCharset); value = avalue.getBytes (encodingCharset); } catch (unsupportencodingexception e) {keyb = akey.getBytes (); value = avalue.getBytes (); } arrays.fill (k_ipad, keyb.length, 64, (ไบต์) 54); array.fill (k_opad, keyb.length, 64, (ไบต์) 92); สำหรับ (int i = 0; i <keyb.length; i ++) {k_ipad [i] = (byte) (keyb [i] ^ 0x36); k_opad [i] = (ไบต์) (keyb [i] ^ 0x5c); } MESAGEDIGEST MD = NULL; ลอง {md = messageDigest.getInstance ("MD5"); } catch (nosuchalgorithmexception e) {return null; } md.update (k_ipad); md.update (ค่า); byte dg [] = md.digest (); md.reset (); md.update (k_opad); md.update (dg, 0, 16); dg = md.digest (); RETURN TOHEX (DG); } สตริงคงที่สาธารณะ tohex (อินพุตไบต์ []) {ถ้า (อินพุต == null) ส่งคืน null; stringbuffer output = new StringBuffer (input.length * 2); สำหรับ (int i = 0; i <input.length; i ++) {int current = input [i] & 0xff; ถ้า (ปัจจุบัน <16) output.Append ("0"); เอาท์พุท. Append (Integer.toString (ปัจจุบัน, 16)); } return output.toString (); } สตริงคงที่สาธารณะ gethmac (สตริง [] args, คีย์สตริง) {ถ้า (args == null || args.length == 0) {return (null); } StringBuffer str = new StringBuffer (); สำหรับ (int i = 0; i <args.length; i ++) {str.append (args [i]); } return (hmacsign (str.toString (), key)); } / ** * @param Avalue * @return * / String String Public String (String Avalue) {Avalue = Avalue.Trim (); ค่าไบต์ []; ลอง {value = avalue.getBytes (encodingCharset); } catch (unsupportencodingexception e) {value = avalue.getBytes (); } MESAGEDIGEST MD = NULL; ลอง {md = messageDigest.getInstance ("sha"); } catch (nosuchalgorithmexception e) {e.printstacktrace (); คืนค่า null; } return tohex (md.digest (value)); } // โมฆะคงที่สาธารณะหลัก (สตริง [] args) {// พารามิเตอร์ 1: plaintext (ข้อมูลที่จะเข้ารหัส) พารามิเตอร์ 2: ระบบคีย์. out.out.println (digestutil.hmacsign ("11111", "abc"); System.out.println (Digestutil.hmacsign ("11111", "ABD")); // แก้ปัญหาความปลอดภัยของข้อมูล: เข้ารหัสข้อความธรรมดา ---> ข้อความลับและข้อความธรรมดาถึง Yibao // หลังจาก Yibao ได้รับข้อมูลเข้ารหัสข้อความธรรมดาที่ส่งและเปรียบเทียบกับข้อความ Cipher ที่ส่งผ่าน หากข้อมูลที่เท่าเทียมกันไม่ได้ถูกดัดแปลงด้วย (Merchant และ Yibao ทั้งคู่ใช้คีย์เดียวกันเมื่อเข้ารหัส)}}ฉันยังไม่ได้ศึกษาอัลกอริทึมการเข้ารหัสมากเกินไป ดูเหมือนว่าจะเป็นอัลกอริทึมการเข้ารหัส MD5 รุ่นที่สอง อย่างไรก็ตามเพียงแค่โยนข้อความธรรมดาเข้าไปในนั้นและมันจะถูกเข้ารหัสลงใน ciphertext อย่างแน่นอน มาดูหน้า reqpay.jsp:
<%@page language = "java" contentType = "text/html; charset = gbk"%> <html> <head> <title> ไปยังหน้า yeepay </title> </head> <body> <form name = "yeepay" action = 'https: //ww.yeepay.com type = 'hidden' name = 'p0_cmd' value = '$ {requestscope.p0_cmd}'> <อินพุต type = 'hidden' name = 'p1_merid' value = '$ {requestscope.p1_merid}' name = 'p3_amt' value = '$ {requestscope.p3_amt}'> <อินพุตประเภท = 'hidden' name = 'p4_cur' value = '$ {requestCope.p4_cur}'> <อินพุตประเภท = 'hidden' name = 'p5_pid' value = '$ {requestscope.p6_pcat}'> <อินพุต type = 'hidden' name = 'p7_pdesc' value = '$ {requestscope.p7_pdesc}'> <อินพุต type = 'hidden' name = 'p8_url' value = '$ {requestscope.p8_url}' value = '$ {requestscope.p9_saf}'> <อินพุตประเภท = 'ซ่อน' name = 'pa_mp' value = '$ {requestscope.pa_mp}'> <อินพุตประเภท = 'hidden' name = 'pa_mp' value = '$ {requestscope.pa_mp} value = '$ {requestscope.pa_mp}'> <อินพุตประเภท = 'hidden' name = 'pd_frpid' value = '$ {requestscope.pd_frpid}'> <อินพุต type = "hidden" name = "pr_needResponse" value = "$ {requestScope.prope value = '$ {requestscope.hmac}'> <อินพุตประเภท = 'ส่ง'/> </form> </body> </html> ในความเป็นจริงหน้านี้ง่ายมาก มันคือการส่งข้อความธรรมดาและข้อความรหัสไปยัง Yibao ผ่านรูปแบบ <form> URL ที่ได้รับของ Yibao คือ https://www.yeepay.com/app-merchant-proxy/node สิ่งนี้จัดทำโดยเจ้าหน้าที่ Yibao และเราสามารถเขียนสิ่งนี้ได้ ในความเป็นจริงมีเพียงปุ่ม submit คลิกปุ่ม submit เพื่อส่งข้อความธรรมดาและข้อความรหัส มาดูผลการทดสอบ:
3. ผลการทดสอบการชำระเงิน
Test Test Front Desk Index.jsp ~~~:
หลังจากส่งแล้วคุณจะไปที่ REQPAY และ JSP เอฟเฟกต์หลังจากคลิกปุ่มส่งมีดังนี้ เราจะทดสอบทั้ง ICBC และ CCB:
ไม่มีปัญหากับกระบวนการชำระเงิน เดิมทีฉันวางแผนที่จะจ่าย 1 เซ็นต์ให้กับ ICBC เพื่อดูผลลัพธ์หลังจากการชำระเงินเสร็จสมบูรณ์ แต่ฉันพบว่า U-shield หมดอายุเพราะมันสะดวกกว่าที่จะใช้ Aliipay ตอนนี้ ... ฉันไม่ได้อัปเดต U-Shield แต่ฉันเปิด E-Payment ผ่าน ICBC
จากนั้นจะข้ามไปที่หน้าเว็บที่เราระบุไว้ก่อนหน้านี้คือมหาวิทยาลัย Tongji ... โอเคการทดสอบเสร็จสมบูรณ์และกระบวนการชำระเงินทั้งหมดสิ้นสุดลง!
ส่วนนี้ส่วนใหญ่ทดสอบผ่านการสาธิตอย่างง่ายเพื่อดูว่าสามารถเชื่อมต่อกับอินเทอร์เฟซการชำระเงินของธนาคารได้หรือไม่ ตอนนี้การทดสอบไม่เป็นไรมันเชื่อมต่อกันและคุณสามารถจ่ายได้ตามปกติในภายหลัง มาแนะนำตัวอย่างง่ายๆ จากนั้นเราจะพัฒนาโมดูลการชำระเงินออนไลน์ของโครงการห้างสรรพสินค้าออนไลน์ก่อนหน้าของเราต่อไป
ที่อยู่ดั้งเดิม: http://blog.csdn.net/eson_15/article/details/51447492
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น