Recently, I want to do JavaWeb project, which uses Alipay.
Start the topic:
Alipay test environment code test
1. Download the official demo of the computer website:
Download address: https://docs.open.alipay.com/270/106291/
2. Download, extract and import eclipse
readme.txt please have a good look.
There is only one Java configuration class, and the rest are JSP S.
3. Configure AlipayConfig
(1). Register ant financial service developer account (free, unlike Apple's charge)
Registered address: https://open.alipay.com Use your Alipay account scan code to log in, improve personal information and choose the type of service (I choose self research).
(2). Set app_id and gatewayUrl
The key needs to be generated by itself. The appID and Alipay gateway have been given good, and the gateway has the dev word, indicating that it is used for development and testing.
(3). Set key
Click "generation method" to open the interface as follows:
Next week's key generation tool. After unpacking and opening, select 2048 bits to generate the key:
If it has not been set, the displayed text is "set application public key", which I have set here.
Setting method, "open key file path":
Copy application public key 2048 Txt to the pop-up box of "set application public key" and save:
-
merchant_private_key
Copy application private key 2048 Txt to merchant_private_key.
-
Alipay public key (alipay_public_key)
Click the link shown in the figure above to copy the contents in the pop-up box to alipay_public_key.
If this setting is incorrect, the result is: the payment is successful, but the signature verification fails.
If it is a formal environment, it needs to be uploaded to the corresponding application:
(4). Server asynchronous notification page path (notify_url)
If you don't change your name, you can modify the IP and port number. My own is as follows:
http://localhost:8080/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp
(5). Page Jump synchronization notification page path (return_url)
http://localhost:8080/alipay.trade.page.pay-JAVA-UTF-8/return_url.jsp
4. Test run
Alipay buyers account for testing can be found on the "sandbox account" page.
After successful payment, the signature verification result:
2: Docking to SSM
The interface process of Alipay:
The important step is step 6, 7 and 8. Step 6 is synchronous callback, which can only indicate that your interface is successfully docked and return your docking information, but it can not indicate that the payment is successful. Therefore, step 7, asynchronous callback, appears at this time. When the asynchronous callback is successful, it can indicate that the payment is successful. However, this is not accurate. If the asynchronous callback fails to come back, you will not know. Therefore, step 8 appears. Take the initiative to query the order information. If you can find the order information, it means that the payment is successful.
OK, that's all for the description. Here's the code:
The project mainly adds two java classes,
I: AlipayController, which mainly involves front and back-end data processing and logical access, such as synchronous callback, asynchronous callback code, page jump code, etc
Two: AlipayConfig, which is about the configuration of Alipay configuration information. For example: public key, private key, gateway, callback address, etc....
AlipayController code is as follows:
import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.internal.util.AlipaySignature; import com.alipay.api.request.AlipayTradePagePayRequest; import com.alipay.api.request.AlipayTradeQueryRequest; import com.ischoolbar.programmer.entity.admin.Log; import com.ischoolbar.programmer.entity.admin.News; import com.ischoolbar.programmer.entity.admin.Order; import com.ischoolbar.programmer.entity.admin.User; import com.ischoolbar.programmer.page.admin.Page; import com.ischoolbar.programmer.service.admin.LogService; import com.ischoolbar.programmer.service.admin.NewsCategoryService; import com.ischoolbar.programmer.service.admin.NewsService; import com.ischoolbar.programmer.service.admin.OrderService; import com.ischoolbar.programmer.service.admin.SiteService; import com.ischoolbar.programmer.util.AlipayConfig; import com.ischoolbar.programmer.util.GetSystemTime; @RequestMapping("/alipay") @Controller public class AlipayController { @Autowired private NewsService newsService; @Autowired private NewsCategoryService newsCategoryService; @Autowired private OrderService orderService; @Autowired private SiteService siteService; @RequestMapping(value="/toPay",method=RequestMethod.POST,produces = "text/html;charset=utf-8") @ResponseBody public String getList(HttpServletRequest request,@RequestParam(name="id",required=true,defaultValue="")Long id,@RequestParam(name="telephone",required=true,defaultValue="")String telephone) throws UnsupportedEncodingException, AlipayApiException{ //Get the initialized AlipayClient AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type); //Set request parameters AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest(); alipayRequest.setReturnUrl(AlipayConfig.return_url); alipayRequest.setNotifyUrl(AlipayConfig.notify_url); //Payment amount, required String total_amount = new String(news.getMoney().toString()); //Order Name: Product id + product name String subject = new String(news.getId()+":"+news.getTitle()); //Product description, summary String body = new String(news.getAbstrs()); alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\"," + "\"total_amount\":\""+ total_amount +"\"," + "\"subject\":\""+ subject +"\"," + "\"body\":\""+ body +"\"," + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}"); //If you want to add other optional request parameters to BizContent, you can add the custom timeout parameter timeout_express to illustrate //alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\"," // + "\"total_amount\":\""+ total_amount +"\"," // + "\"subject\":\""+ subject +"\"," // + "\"body\":\""+ body +"\"," // + "\"timeout_express\":\"10m\"," // + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}"); //For request parameters, please refer to the chapter of [API document for payment on computer website - alipay.trade.page.pay - request parameters] //request String result = alipayClient.pageExecute(alipayRequest).getBody(); return result; } /** * This function depends on whether the payment is successful and can be implemented asynchronously * @throws UnsupportedEncodingException * @throws AlipayApiException * */ @RequestMapping(value="/notifyInfo",method=RequestMethod.POST) @ResponseBody public String notifyInfo(HttpServletRequest request) throws UnsupportedEncodingException, AlipayApiException{ /* * * Function: asynchronous notification page of Alipay server: successful deduction * Date: March 30, 2017 * explain: * The following code is only the sample code provided to facilitate the merchant's test. The merchant can write it according to the technical documents according to the needs of its own website, but it is not necessary to use the code. * This code is for studying and studying Alipay interface only, providing a reference. *************************Page function description************************* * When creating the page file, please note that there are no HTML codes and spaces in the page file. * This page cannot be tested on the local computer. Please test on the server. Make sure that the page is accessible externally. * If you do not receive the success returned by this page * It is recommended that this page only handle the business logic of successful payment, and the refund processing shall be subject to the result of calling the refund query interface. */ //Get feedback from Alipay POST Map<String,String> params = new HashMap<String,String>(); Map<String,String[]> requestParams = request.getParameterMap(); for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) { String name = (String) iter.next(); String[] values = (String[]) requestParams.get(name); String valueStr = ""; for (int i = 0; i < values.length; i++) { valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; } //Garbled code solution, this code is used in case of garbled code //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8"); params.put(name, valueStr); } boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //Call SDK to verify signature //——Please write your program here (the following code is for reference only)—— /* In the actual verification process, the merchant is recommended to add the following verification: 1,You need to verify the out in the notification data_ trade_ Is no the order number created in the merchant system, 2,Judge total_ Is the amount really the actual amount of the order (i.e. the amount when the merchant order is created), 3,Verify the seller in the notification_ Is the ID (or seller_email) out_trade_no the corresponding operator of this document (sometimes, a merchant may have multiple seller_id/seller_email) 4,Validate app_ Whether the ID is the merchant itself. */ if(signVerified) {//Verification successful //Merchant order number String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8"); //Alipay transaction number String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8"); //Get the initialized AlipayClient AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type); /** * Reconfirm whether the deduction is successful * */ //Set request parameters AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest(); alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","+"\"trade_no\":\""+ trade_no +"\"}"); String result = alipayClient.execute(alipayRequest).getBody(); boolean one = result.contains("\"msg\":\"Success\""); boolean two = result.contains("\"sub_msg\":\"Transaction does not exist\""); if(one||!two) { orderService.updateStatus(out_trade_no); } // if(trade_status.equals("TRADE_FINISHED")){ // //Judge whether the order has been processed in the merchant website // //If it has not been processed, check the details of the order in the order system on the merchant's website according to the order number (out_trade_no), and execute the merchant's business procedures // //If it has been handled, the merchant's business procedures will not be executed // // //Note: // / / the refund date is longer than the refundable period (if three months can be refunded), the Alipay system sends the transaction status notification. // }else if (trade_status.equals("TRADE_SUCCESS")){ // //Judge whether the order has been processed in the merchant website // //If it has not been processed, check the details of the order in the order system on the merchant's website according to the order number (out_trade_no), and execute the merchant's business procedures // //If it has been handled, the merchant's business procedures will not be executed // // //Note: // / / after payment is completed, the Alipay system sends the transaction status notification. // } }else {//Validation failed System.out.println("notifyInfo Signature verification failed"); //Debug and try, write text function to record whether the program is running normally //String sWord = AlipaySignature.getSignCheckContentV1(params); //AlipayConfig.logResult(sWord); } //——Please write your program here (the above code is for reference only)—— return "success"; } /** * Yes, the request is successful, and the non deduction is successful. This involves page Jump * @throws UnsupportedEncodingException * @throws AlipayApiException * */ @SuppressWarnings("unused") @RequestMapping(value="/returnInfo",method=RequestMethod.GET) @ResponseBody public ModelAndView returnInfo(HttpServletRequest request) throws UnsupportedEncodingException, AlipayApiException{ /* * * Function: Alipay server synchronization notification page * Date: March 30, 2017 * explain: * The following code is only the sample code provided to facilitate the merchant's test. The merchant can write it according to the technical documents according to the needs of its own website, but it is not necessary to use the code. * This code is for studying and studying Alipay interface only, providing a reference. * Call succeeded *************************Page function description************************* * This page is only for page display. Please do not perform business logic processing on this page * * This is not a successful deduction. It cannot be used as a standard */ //Synchronization parameter acquisition Map<String,String> params = new HashMap<String,String>(); Map<String,String[]> requestParams = request.getParameterMap(); for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) { String name = (String) iter.next(); String[] values = (String[]) requestParams.get(name); String valueStr = ""; for (int i = 0; i < values.length; i++) { valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; } //Garbled code solution, this code is used in case of garbled code valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8"); params.put(name, valueStr); } //Signature verification boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //Call SDK to verify signature ModelAndView mv = new ModelAndView(); //——Please write your program here (the following code is for reference only)—— if(signVerified) { System.out.println("returnInfo The signature verification is successful, and preparations such as page Jump are made"); /** * The signature verification is successful. Get all the items purchased under this mobile phone number * */ Map<String, Object> queryMap = new HashMap<String, Object>(); //Merchant order number String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8"); String telephone = orderService.searchTelephone(out_trade_no) }else { System.out.println("returnInfo Signature verification failed"); } return mv; } }
Profile settings:
package com.ischoolbar.programmer.util; import java.io.FileWriter; import java.io.IOException; /* * *Class name: AlipayConfig *Function: basic configuration class *Details: set account information and return path *Revision date: April 5, 2017 *explain: *The following code is only the sample code provided to facilitate the merchant's test. The merchant can write it according to the technical documents according to the needs of its own website, but it is not necessary to use the code. *This code is for studying and studying Alipay interface only, providing a reference. */ public class AlipayConfig { //↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ please configure your basic information here ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ // With ID, your APPID account is your APPID corresponding Alipay account. public static String app_id = ""; private static String ip_address = ""; // Merchant private key, your RSA2 private key in PKCS8 format public static String merchant_private_key = "; // Alipay public key, see address: https://openhome.alipay.com/platform/keyManage.htm The Alipay public key corresponding to APPID. public static String alipay_public_key = ""; // The server asynchronous notification page path requires a full path in the format of http: / / and cannot be added? User defined parameters such as id=123 must be accessible from the Internet public static String notify_url = "http://"+ip_address+"/alipay/notifyInfo"; // The page path of page Jump synchronization notification requires a full path in http: / / format, which cannot be added? User defined parameters such as id=123 must be accessible from the Internet public static String return_url = "http://"+ip_address+"/alipay/returnInfo"; // Signature method public static String sign_type = "RSA2"; // Character encoding format public static String charset = "utf-8"; // Alipay gateway public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do"; // Alipay gateway public static String log_path = "/soft/alipay"; //↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ please configure your basic information here ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ /** * Write a log to facilitate testing (depending on the needs of the website, you can also change to store the records in the database) * @param sWord Text content to be written to the log */ public static void logResult(String sWord) { FileWriter writer = null; try { writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis()+".txt"); writer.write(sWord); } catch (Exception e) { e.printStackTrace(); } finally { if (writer != null) { try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } } } }