1. Online payment overview
What is online payment? That's right, it's just spending money online! Everyone must have had such an experience. But you may not know much about the "inside story" of online payment, let's learn about it below!
If you start running an e-commerce website now, users must pay if they buy something. Your website must be able to connect to major banks. Then, after the payment is completed, return to your website to display "Payment Success"!
This is what we are going to do today, connect to the bank's online banking system to complete payments. To be more professional, we call it "developing a gateway for online payments"
2. Two ways to pay online
There are two ways to pay online:
*E-commerce directly connects with banks
*E-commerce connects with banks through third-party payment platforms
E-commerce directly connects with banks, which requires the bank's consent, but unfortunately, banks are very "awesome" and not anyone who wants to connect with them. If your e-commerce business has a large daily capital flow, the bank will connect with you because all the money paid by the customer to the e-commerce is deposited into the bank account! But if the capital flow is small, the bank will not pay attention to you!
When small websites are insufficient in funds and cannot connect with banks, they will choose to cooperate with third-party payment companies. Everyone also understands what companies this is, such as Alipay, Yibao, Fortune, Kuaiqian and other companies are relatively famous in China. These companies can connect with banks (because they have enough funds), and then small e-commerce companies can connect with them! But third parties require a fee! Third parties generally charge 1% of e-commerce fees, but they will not charge customers' money.
Through the above picture, you can learn that the mall name, RMB order number, and order time will be displayed on the bank page. . . , how do banks know about these things? Of course, it is passed on to banks by e-commerce. After the e-commerce company connects with the bank, the e-commerce company needs to pass the parameters required by the bank page to the bank page, so the bank page can display these data!
However, our mall cannot only connect to one bank! We must connect with the four companies of BOC, CCB, ABC and ICBC! The docking parameters required by different banks are different, which means that we need to write different docking codes for different banks during development. This is also the disadvantage of directly connecting with banks! Of course, direct connection with banks is also beneficial, that is, security is not required, no handling fees!
Develop different codes for different banks (disadvantages);
Safety (advantages);
No handling fee (advantages);
Small e-commerce banks do not allow connections (disadvantages).
As shown in the figure above, after the customer clicks to confirm payment on the e-commerce website, he will be directed to the third party's website, and then the third party will connect with the bank. This shows that e-commerce needs to pass parameters to third-party! The third party then passes the parameters to the bank. The advantage of this method is that it only needs to be developed for third parties without providing parameters to each bank. It is a third-party task to provide parameters to each bank. However, if a third party is not old and reliable, if the third party goes bankrupt and people run away, then your money will be gone. Because the money paid by the customer does not go to your bank account, it is paid to the third party's bank account, and you have an account on the third party. Moreover, third parties also charge a handling fee, usually 1%, which is not a small number (it's really bad).
3. Through third-party online payment rules
If e-commerce wants to register a merchant with a third party, it needs to provide ICP certification to the third party. An ICP business license is a website business license that must be processed by a business website in accordance with the National "Internet Management Measures". If it does not, it is illegal to operate.
We can’t apply for ICP just because of practice! So we cannot register a merchant with a third party. However, we already have ready-made merchants registered with Yibao, so this step can be ignored.
When you successfully register with Yibao, Yibao will give you the following things:
Open an account in Yibao (i.e. merchant code): 10001126856
Yibao access specification: a chm file symmetric encryption algorithm class: PaymentUtil.java
Key: 69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl
In the Yibao access specification, we can find Yibao's payment gateway, which is actually a URL, a URL used to connect with Yibao: https://www.yeepay.com/app-merchant-proxy/node
In the Yibao access specification, you can also find the parameters required by Yibao. When e-commerce connects with Yibao, these parameters need to be passed to the payment gateway:
Official request address: https://www.yeepay.com/app-merchant-proxy/node
These parameters need to be appended to the URL.
However, be aware that the values of these parameters need to be encrypted. Both the encryption key and the encryption algorithm Yibao will provide!
where p8_Url indicates which page to return to when payment is successful. This means we need to write a page that displays the results. After the payment is successful, a third party will redirect to the return page we specified, and will also bring us some parameters. Our page needs to obtain these parameters and display them in the page. The following are the parameters returned by the third party:
4. Develop a third-party online payment system
step:
index.jsp page: a form submitted to BuyServlet. The form items include: order number, payment amount, bank selection
BuyServlet: Get form data and prepare to connect to a third-party gateway. Because only 3 parameters are given in the index.jsp page, and there are many parameters required by third parties, the parameters not given by the page are supplemented by BuyServlet. And the parameters also need to be encrypted, which also needs to be completed in BuyServlet
BackServlet: When the user pays successfully, the third party will redirect to the return page we specified. We use BackServlet as the return page, which is used to receive parameters passed by the third party and display them in the page.
Because we already have a registered business in Yibao, we don’t have to register a business by ourselves. So here is to use Yibao as a third-party payment platform for testing. Because I don’t have e-commerce (e-commerce that must pass ICP certification), I cannot register a business with a third party either.
The Yibao business we are using now is provided by Chuanzhi Podcast, a business registered by Baba Sports Network on Yibao. So the money paid during the test was given to the company registered by Baba Sports Network on Yibao.
Step 1: index.jsp
<form action="" method="post"> Order number: <input type="text" name="p2_Order"/><br/> Amount: <input type="text" name="p3_Amt"/><br/> Select a bank: <input type="radio" name="pd_FrpId" value="ICBC-NET-B2C"/> Industrial and Commercial Bank of China<img src="bank_img/icbc.bmp" align="middle"/> <input type="radio" name="pd_FrpId" value="BOC-NET-B2C"/>Bank of China<img src="bank_img/icbc.bmp" align="middle"/> <input type="radio" name="pd_FrpId" value="BOC-NET-B2C"/>Bank of China<img src="bank_img/bc.bmp" align="middle"/><br/> <input type="radio" name="pd_FrpId" value="ABC-NET-B2C"/> Agricultural Bank of China<img src="bank_img/abc.bmp" align="middle"/> <input type="radio" name="pd_FrpId" value="CCB-NET-B2C"/> Construction Bank<img src="bank_img/ccb.bmp" align="middle"/><br/> <input type="radio" name="pd_FrpId" value="BOCO-NET-B2C"/>Bank of Communications<img src="bank_img/bcc.bmp" align="middle"/><br/> <input type="submit" value="confirm payment"/></form>
The corresponding value of each bank:
Step 2: BuyServlet.java
public class BuyServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); String p0_Cmd = "Buy";// Business type, fixed value is buy, that is, "buy" String p1_MerId = "10001126856";// The business name String p2_Order = request.getParameter("p2_Order");// Order number String p3_Amt = request.getParameter("p3_Amt");// The amount paid String p4_Cur = "CNY";// The transaction currency, the fixed value is CNY, indicating RMB String p5_Pid = "";// Product name String p6_Pcat = "";// Product name String p7_Pdesc = "";// Product description String p8_Url = "http://localhost:8080/buy/BackServlet";// Product description String p8_Url = "http://localhost:8080/buy/BackServlet";// The return page of e-commerce, when the payment is successful, Yibao will redirect to this page String p9_SAF = "";// Delivery address String pa_MP = "";// Product extension information String pd_FrpId = request.getParameter("pd_FrpId");// Payment channel, that is, select the bank String pr_NeedResponse = "1";// Response mechanism, fixed value is 1 // Key, provided by Yibao, only merchants and Yibao know this key. String keyValue = "69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl"; // Through the above parameters, keys, and encryption algorithms, the hmac value is generated// The order of parameters is necessary. If there is no value, null cannot be given, but an empty string should be given. String hmac = PaymentUtil.buildHmac(p0_Cmd, p1_MerId, p2_Order, p3_Amt, p4_Cur, p5_Pid, p6_Pcat, p7_Pdesc, p8_Url, p9_SAF, pa_MP, pd_FrpId, pr_NeedResponse, keyValue); // Connect all parameters to the gateway address String url = "https://www.yeepay.com/app-merchant-proxy/node"; url += "?p0_Cmd=" + p0_Cmd + "&p1_MerId=" + p1_MerId + "&p2_Order=" + p2_Order + "&p3_Amt=" + p3_Amt + "&p4_Cur=" + p4_Cur + "&p5_Pid=" + p5_Pid + "&p6_Pcat=" + p6_Pcat + "&p7_Pdesc=" + p7_Pdesc=" + p7_Pdesc + "&p8_Url=" + p8_Url=" + p8_Url + "&p9_SAF=" + p9_SAF + "&pa_MP=" + pa_MP + "&pd_FrpId=" + pd_FrpId + "&pr_NeedResponse=" + pr_NeedResponse + "&hmac=" + hmac; System.out.println(url); // Redirect to gateway response.sendRedirect(url); }}Step 3: BackServlet
public class BackServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); /* * Yibao will provide a series of result parameters, we can get what we need in it * Get the payment result: r1_Code, 1 means that the payment is successful. * Get payment amount: r3_Amt * Get e-commerce order number: r6_Order * Get result return type: r9_BType, 1 means redirect return, 2 means point-to-point return, * But we cannot receive point-to-point, because our IPs are all LAN IPs. */ String r1_Code = request.getParameter("r1_Code"); String r3_Amt = request.getParameter("r3_Amt"); String r6_Order = request.getParameter("r6_Order"); String r9_BType = request.getParameter("r9_BType"); if(r1_Code.equals("1")) { if(r9_BType.equals("1")) { response.getWriter().print("<h1>Pay successfully!</h1>");//In fact, when the payment is unsuccessful, Yibao will not return to this Servlet response.getWriter().print("Payment amount is: " + r3_Amt + "<br/>"); response.getWriter().print("Order number is: " + r6_Order + "<br/>"); } } }}Tools for obtaining hmac provided by Yibao Payment
public class PaymentUtil { private static String encodingCharset = "UTF-8"; /** * Generate hmac method* * @param p0_Cmd Business type* @param p1_MerId Merchant number* @param p2_Order Merchant order number* @param p3_Amt Payment amount* @param p4_Cur Transaction currency* @param p5_Pid Product name* @param p6_Pcat Product type* @param p7_Pdesc Product description* @param p8_Url Address of the merchant receiving payment success data* @param p9_SAF Delivery address* @param pa_MP Merchant extension information* @param pd_FrpId Bank code* @param pr_NeedResponse response mechanism* @param keyValue Merchant key* @return */ public static String buildHmac(String p0_Cmd,String p1_MerId, String p2_Order, String p3_Amt, String p4_Cur,String p5_Pid, String p6_Pcat, String p7_Pdesc,String p8_Url, String p9_SAF,String pa_MP,String pd_FrpId, String pr_NeedResponse,String keyValue) { StringBuilder sValue = new StringBuilder(); // Business type sValue.append(p0_Cmd); // Merchant number sValue.append(p1_MerId); // Merchant order number sValue.append(p2_Order); // Payment amount sValue.append(p3_Amt); // Trading currency sValue.append(p4_Cur); // Product name sValue.append(p5_Pid); // Product type sValue.append(p6_Pcat); // Product description sValue.append(p7_Pdesc); // Address of the merchant receiving payment success data sValue.append(p8_Url); // Delivery address sValue.append(p9_SAF); // Merchant extension information sValue.append(pa_MP); // Bank code sValue.append(pd_FrpId); // Response mechanism sValue.append(pr_NeedResponse); return PaymentUtil.hmacSign(sValue.toString(), keyValue); } /** * Return to verification hmac method* * @param hmac Encrypted verification code sent by the payment gateway* @param p1_MerId Merchant number* @param r0_Cmd Business type* @param r1_Code Payment result* @param r2_TrxId Yibao payment transaction flow number* @param r3_Amt Payment amount* @param r4_Cur Transaction currency* @param r5_Pid Product name* @param r6_Order Merchant order number* @param r7_Uid Yibao Payment member ID * @param r8_MP Merchant extension information* @param r9_BType Transaction result return type* @param keyValue key* @return */ public static boolean verifyCallback(String hmac, String p1_MerId, String r0_Cmd, String r1_Code, String r2_TrxId, String r3_Amt, String r4_Cur, String r5_Pid, String r6_Order, String r7_Uid, String r8_MP, String r9_BType, String keyValue) { StringBuilder sValue = new StringBuilder(); // Merchant number sValue.append(p1_MerId); // Business type sValue.append(r0_Cmd); // Payment result sValue.append(r1_Code); // Yibao payment transaction number sValue.append(r2_TrxId); // Payment amount sValue.append(r3_Amt); // Transaction currency sValue.append(r4_Cur); // Product name sValue.append(r5_Pid); // Merchant order number sValue.append(r6_Order); // Yibao Payment member ID sValue.append(r7_Uid); // Merchant extension information sValue.append(r8_MP); // Transaction result return type sValue.append(r9_BType); String sNewString = PaymentUtil.hmacSign(sValue.toString(), keyValue); return sNewString.equals(hmac); } /** * @param aValue * @param aKey * @return */ public static String hmacSign(String aValue, String aKey) { byte k_ipad[] = new byte[64]; byte k_opad[] = new byte[64]; byte keyb[]; byte value[]; try { keyb = aKey.getBytes(encodingCharset); value = aValue.getBytes(encodingCharset); } catch (UnsupportedEncodingException e) { keyb = aKey.getBytes(); value = aValue.getBytes(); } Arrays.fill(k_ipad, keyb.length, 64, (byte) 54); Arrays.fill(k_opad, keyb.length, 64, (byte) 92); for (int i = 0; i < keyb.length; i++) { k_ipad[i] = (byte) (keyb[i] ^ 0x36); k_opad[i] = (byte) (keyb[i] ^ 0x5c); } MessageDigest md = null; try { md = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { return null; } md.update(k_ipad); md.update(value); byte dg[] = md.digest(); md.reset(); md.update(k_opad); md.update(dg, 0, 16); dg = md.digest(); return toHex(dg); } public static String toHex(byte input[]) { if (input == null) return null; StringBuffer output = new StringBuffer(input.length * 2); for (int i = 0; i < input.length; i++) { int current = input[i] & 0xff; if (current < 16) output.append("0"); output.append(Integer.toString(current, 16)); } return output.toString(); } /** * * @param args * @param key * @return */ public static String getHmac(String[] args, String key) { if (args == null || args.length == 0) { return (null); } StringBuffer str = new StringBuffer(); for (int i = 0; i < args.length; i++) { str.append(args[i]); } return (hmacSign(str.toString(), key)); } /** * @param aValue * @return */ public static String digest(String aValue) { aValue = aValue.trim(); byte value[]; try { value = aValue.getBytes(encodingCharset); } catch (UnsupportedEncodingException e) { value = aValue.getBytes(); } MessageDigest md = null; try { md = MessageDigest.getInstance("SHA"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } return toHex(md.digest(value)); }// public static void main(String[] args) {// System.out.println(hmacSign("AnnulCard1000043252120080620160450.0http://localhost/SZXpro/callback.asp海?4564868265473632445648682654736324511","8UPp0KE8sq73zVP370vko7C39403rtK1YwX40Td6irH216036H27Eb12792t"));// }}Yibao callback
Peer-to-peer: Yibao directly accesses e-commerce, there is no client here.
This method is a must-use, and we cannot receive it this way! Because we don't have a fixed IP
Yibao has a resend mechanism. If it visits you and you don’t send it back the message, it will keep resending!
E-commerce needs to return a string starting with SUCCESS!
Guide the client browser to redirect to the e-commerce. It is to let clients access e-commerce!
Can not be used!
hmac: 13 parameter value + keyValue (key) + algorithm (md5)
13 Parameter value: Set by yourself!
keyValue: The one Yibao sent to us after we registered, only we and Yibao knew about this thing!
The algorithm with the underlying md5: PaymentUtil.buildHmac (14), which returns hmac
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.