In the previous section, we have done the display of the payment page. From the jsp code displayed in the previous section, we can see that when the user clicks to confirm payment, it will jump to the action of ${shop}/pay_goBank.action . That is to say, after submitting, we have to process some logic in the goBank method in the payAction (that is, the logic of the flowchart in Section 21 demo), that is, obtain the plain text, encrypt the plain text into a signature (ciphertext) and then visit the Yibao server, Yibao connects to the bank to complete the payment.
However, considering the MVC design pattern, we will put the above business logic into the Service layer for processing, so let’s implement the payment logic of the demo in Section 21.
1. Write a Model to encapsulate parameters
First of all, we need to write a Model (SendData) to receive the parameters transmitted from the jsp page, and add other parameters that need to be sent by ourselves. These parameters are stipulated in the official documents of Yibao. We can strictly follow the regulations on the documents:
/* * The information sent by the mall to Yibao Payment is encapsulated as an entity* */public class SendData implements Serializable { private static final long serialVersionUID = -6304103739907145812L; //(*) indicates the required field private String p0_Cmd; //Business type (*), fixed as: Buy private String p1_MerId;//Merchant number (*) private String p2_Order;//Merchant order number private String p3_Amt;//Payment amount private String p4_Cur;//Trading currency (*) private String p5_Pid;//Product name private String p6_Pcat;//Product type private String p7_Pdesc;//Product description private String p8_Url;//Address for merchants to receive payment success data private String p9_SAF;//Delivery address private String pa_MP;//Merchant extension information private String pd_FrpId;//Payment channel encoding, that is, bank private String pr_NeedResponse;//Response mechanism//Omit get and set methods}The above attributes are all parameters to be transmitted to Yibao. You can choose the parameters you need. Not all of them are transmitted. Depending on the situation, we generally pass them over except p5, p6, and p7. Let's take a look at the code of Action:
2. Implementation of payAction
In payAction, we mainly encapsulate some parameters passed in the jsp page into the model, and then call the service layer method to initialize other parameters, as follows:
@Controller("payAction")@Scope("prototype")public class PayAction extends BaseAction<Object> implements ParameterAware{ public String goBank() { //1. Complete parameters: P2 p3 pd Pa, you need to get Forder forder = (Forder) session.get("oldForder"); User user = (User) session.get("user"); model.setP2_Order(forder.getId().toString()); //Merchant order number model.setP3_Amt(forder.getTotal().toString()); //Payment amount model.setPa_MP(user.getEmail() + "," + user.getPhone()); //Merchant extension information//2. Append parameters //3. Encrypt and get signature //4. Store in the request domain to payService.saveDataToRequest(request, model); //2,3,4 business logic is handed over to the service layer for processing //5. Jump to the payment page return "pay"; }}Next, let’s write the code of the Service layer. The service layer mainly implements the logic of the above 2, 3, and 4 steps:
3. Implementation of Service layer
The specific code is as follows:
//payService interface public interface PayService { //Storage the encrypted information in the requestMap public abstract Map<String, Object> saveDataToRequest( Map<String, Object> request, SendData sendData); //Encrypt the returned data to obtain the ciphertext, and compare it with the sent back ciphertext (we will implement it later) public boolean checkBackData(BackData backData);}//payServiceImpl implementation class @Service("payService")public class PayServiceImpl implements PayService { //Key @Value("#{prop.key}") private String key; @Value("#{prop.p1_MerId}") //Mer account (not order number) private String p1_MerId; //The return address for successful payment @Value("#{prop.p8_Url}") private String p8_Url; //The above three attributes are all fixed values, I put them in the pay.properties configuration file, and directly use Spring annotation @Value to obtain // Complete the data of SendData, P2 p3 pd Pa is a front-end injection, and there is no need to fill it here. I have already obtained private SendData finishSendData(SendData sendData) { sendData.setP0_Cmd("Buy"); sendData.setP1_MerId(p1_MerId); sendData.setP4_Cur("CNY"); sendData.setP5_Pid(""); sendData.setP6_Pcat(""); sendData.setP7_Pdesc(""); sendData.setP8_Url(p8_Url); sendData.setP9_SAF("0"); sendData.setPr_NeedResponse("0"); return sendData; } // Complete the data addition and return the appended plaintext private String joinSendDataParam(SendData sendData) { // All data filled sendData = this.finishSendData(sendData); StringBuffer infoBuffer = new StringBuffer(); infoBuffer.append(sendData.getP0_Cmd()); infoBuffer.append(sendData.getP1_MerId()); infoBuffer.append(sendData.getP2_Order()); infoBuffer.append(sendData.getP3_Amt()); infoBuffer.append(sendData.getP4_Cur()); infoBuffer.append(sendData.getP5_Pid()); infoBuffer.append(sendData.getP6_Pcat()); infoBuffer.append(sendData.getP7_Pdesc()); infoBuffer.append(sendData.getP8_Url()); infoBuffer.append(sendData.getP9_SAF()); infoBuffer.append(sendData.getPa_MP()); infoBuffer.append(sendData.getPd_FrpId()); infoBuffer.append(sendData.getPr_NeedResponse()); return infoBuffer.toString(); } // Store the encrypted information in the requestMap @Override public Map<String, Object> saveDataToRequest(Map<String, Object> request, SendData sendData) { // Return the string to be appended (i.e. plaintext) String joinParam = joinSendDataParam(sendData); request.put("p0_Cmd", sendData.getP0_Cmd()); request.put("p1_MerId", sendData.getP1_MerId()); request.put("p2_Order", sendData.getP2_Order()); request.put("p3_Amt", sendData.getP3_Amt()); request.put("p4_Cur", sendData.getP4_Cur()); request.put("p5_Pid", sendData.getP5_Pid()); request.put("p6_Pcat", sendData.getP6_Pcat()); request.put("p7_Pdesc", sendData.getP7_Pdesc()); request.put("p8_Url", sendData.getP8_Url()); request.put("p9_SAF", sendData.getP9_SAF()); request.put("pa_MP", sendData.getPa_MP()); request.put("pd_FrpId", sendData.getPd_FrpId()); request.put("pr_NeedResponse", sendData.getPr_NeedResponse()); request.put("hmac", DigestUtil.hmacSign(joinParam, key));//Add signature (ciphertext) return request; } }We can see that the implementation principle is actually the same as the servlet in the previous demo. The above code uses the pay.properties file and annotations. Let's take a look at the configuration in the pay.properties file and beans.xml:
#pay.propertieskey=w0P75wMZ203fr46r5i70V556WHFa94j14yW5J6vuh4yo3nRl5jsqF3c41677p1_MerId=10000940764p8_Url=https/://www.hao123.com
<!-- beans.xml --><bean id="prop"> <property name="locations"> <array> <value>classpath:public.properties</value><!--之前用到的--> <value>classpath:pay.properties</value> </array> </property></bean>
Okay, now that the Action and Service layers are written, let's configure the struts.xml file again:
4. struts.xml configuration and pay.jsp page
<action name="pay_*" method="{1}"> <result name="pay">/user/pay.jsp</result></action>The configuration of struts.xml is very simple. It mainly jumps to the user/pay.jsp page according to the return value, and sends the plaintext (parameters) and ciphertext (signature) set above to the Yibao server:
<div> <span>Order number: </span><strong>${requestScope.p2_Order }</strong><span>[Please remember this number so that you can use it when making payments and inquiries] </span> </div> <div> <span>Payment amount: </span><strong>¥${requestScope.p3_Amt }</strong> </div> <div> <span>Payment method: </span><img src="${shop }/files/yibao.jpg" /> </div> <div> <span>Payment bank: </span><img src="${shop }/files/bankImages/${pd_FrpId}.gif" /> </div> <div> <form name="yeepay" action='https://www.yeepay.com/app-merchant-proxy/node' method='POST' target="_blank"> <input type='hidden' name='p0_Cmd' value='${requestScope.p0_Cmd}'> <input type='hidden' name='p1_MerId' value='${requestScope.p1_MerId}'> <input type='hidden' name='p2_Order' value='${requestScope.p2_Order}'> <input type='hidden' name='p2_Order' value='${requestScope.p2_Order}'> <input type='hidden' name='p3_Amt' value='${requestScope.p3_Amt}'> <input type='hidden' name='p4_Cur' value='${requestScope.p4_Cur}'> <input type='hidden' name='p5_Pid' value='${requestScope.p5_Pid}'> <input type='hidden' name='p6_Pcat' value='${requestScope.p6_Pcat}'> <input type='hidden' name='p7_Pdesc' value='${requestScope.p7_Pdesc}'> <input type='hidden' name='p8_Url' value='${requestScope.p8_Url}'> <input type='hidden' name='p9_SAF' value='${requestScope.p9_SAF}'> <input type='hidden' name='pa_MP' value='${requestScope.pa_MP}'> <input type='hidden' name='pd_FrpId' value='${requestScope.pd_FrpId}'> <input type="hidden" name="pr_NeedResponse" value="${requestScope.pr_NeedResponse}"> <input type='hidden' name='hmac' value='${requestScope.hmac}'> <div> <input type="submit" value="Pay now" /> </div> </form> </div></div> Pay.jsp will send all the plain text we want to pass and the corresponding cipher text to Yibao server. Yibao will encrypt it into cipher text in the same way based on these plain texts, and then match it with the cipher text we have transmitted. If the same means that the data is safe, it is not tampered with during the transmission process, and jump to the payment page normally, and then make a normal payment; if it is not the same, payment is not allowed, and a friendly prompt page pops up.
At this point, I have already made it clear about this online payment process. The reason is very simple. It is nothing more than adding parameters together to form them, adding a password to generate a ciphertext, and then sending these parameters and ciphertext to a third party. He also adds a password in the same encryption method and compares it with what I sent it. As for how to call the bank interface, it is not what we have to do. This is the responsibility of the third party, including some security things. Everyone can focus on their own affairs: I just need to connect with the third party and pass on useful information to him; the third party only needs to focus on how to connect with different banks, which brings great convenience to development. Because the interfaces connected with different banks are definitely different. If we go directly to connect with banks, the cost is too high and it is inconvenient to maintain. If the bank upgrades, I have to upgrade them as well... With a third party, we will never have to worry about it. Upgrading is a matter of a third party, and our interface with a third party will not change~
Original link: http://blog.csdn.net/eson_15/article/details/51464415
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.