Java access Alipay payment tutorial

Java access Alipay payment tutorial

1, Create application

1. login Alipay open platform

Alipay open platform web site: https://open.alipay.com/platform/developerIndex.htm

2. Create an application


?

Figure 1

2, Set application key

1. download and install Alipay open platform assistant

Software download address: https://gw.alipayobjects.com/os/bmw-prod/0e6297a2-89b9-4cab-972b-f9534ba07082.exe )As shown in Figure 3

Figure 3

2. use Alipay open platform assistant to generate key.

Please note that two keys will be generated here, one is the application of the public key, the other is the application of the private key, and the application of the public key should be completed to the open platform of Alipay - see the picture below, please use the private key to save the developer's attention and keep it confidential. For example, figure 4

Figure 4

3. fill in the generated application public key to Alipay open platform.

Figure 5

Duplicate the public key generated by Alipay open platform assistant, such as: Figure 6

Figure 6

Fill in the public key to Alipay open platform and click "Save Settings" as shown in Figure 7.

Figure 7

Submit for review

Figure 8

3, Sandbox environment control configuration

Note: (because the application audit above takes time, the sandbox environment is used for testing before it fails)

Sandbox environment website: https://openhome.alipay.com/platform/appDaily.htm?tab=info

1 set sandbox environment key

I have set it here before. Operate according to the above steps: "II. Set application key" (note that the application private key also needs to be saved by the developer), as shown in Figure 9

Figure 9

Four, building Alipay open environment

Note: the project structure here adopts spring + spring MVC + mybatis, which is almost the same as other frameworks

1. import jar package (Alipay SDK)

JDK 1.8 and above

1.1maven mode

Put the following code into the POM in your project XML file

<!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java -->
<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.10.209.ALL</version>
</dependency>

1.2 download jar import

Jar package download address: https://repo1.maven.org/maven2/com/alipay/sdk/alipay-sdk-java/4.10.209.ALL/alipay-sdk-java-4.10.209.ALL.jar

Import the jar package into the lib folder in the project

2 create zfbinfo Properties resource file

Enter the following code (please note whether there is a space after the parameter value)

# Alipay gateway name, partnerId and appId
open_api_domain = https://openapi.alipay.com/gateway.do
mcloud_api_domain = http://mcloudmonitor.com/gateway.do
#Please fill in your PID here
pid = 
#Please fill in your face-to-face APPID here
appid =

# RSA private key, public key and Alipay public key
#Please fill in your application private key here and transfer it to PKCS8 format
private_key =
#Please fill in your app public key here
public_key = 

#SHA256withRsa corresponds to Alipay public key
alipay_public_key = 

# Signature type: RSA - > sha1withrsa, RSA2 - > sha256withrsa
sign_type = RSA2
# Maximum query times and query interval for face-to-face payment (MS)
max_query_retry = 5
query_duration = 5000

# Maximum cancellation times and cancellation interval for face-to-face payment (MS)
max_cancel_retry = 3
cancel_duration = 2000

# First scheduling delay and scheduling interval of transaction guarantee thread (seconds)
heartbeat_delay = 5
heartbeat_duration = 900

#Asynchronous notification URL (note whether the interceptor intercepts)
NotifyUrl=http://8u862c.natappfree.cc/NBOSTA_WSBM/Alipay/ZFBcallbackAction.do

Write the "appid" and "Alipay gateway" in Figure 10 below to zfbinfo.. In the variable corresponding to the properties resource file

Figure 10

Write "" and "" in Figure 11 below to the variables corresponding to the resource file (and)

Fill the pid in Figure 12 into zfbinfo In the variable corresponding to the properties resource file

Figure 12

3. Create commonutils Java tool class

Getzfbinfo(): used to get zfbinfo Parameters in the properties resource file

package Alipay.util;

import java.util.Properties;

public class CommonUtils {
    /**
     * Get zfbinfo Values in the properties file
     * @param name key
     * @return
     * @throws Exception
     */
    public String getZFBinfoValue(String name) throws Exception{
        Properties props = new Properties();
        props.load(getClass().getResourceAsStream("/zfbinfo.properties"));
        String filepath = props.getProperty(name);;
        return filepath;
    }
}

3. Project structure diagram

5, Payment face to face (code scanning payment)

1. Make an appointment to place an order

1.1main function execution

The following code is pre ordered, and the main function can be invoked. This method can be run. After calling this method, Alipay will return a json format string containing the two-dimensional code address, then use the two-dimensional code generator to generate the two-dimensional code, and then use Alipay to pay the payment, such as: Figure 13

package Alipay;

import Alipay.util.CommonUtils;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;

import java.util.Properties;

/**
 * Alipay face-to-face payment
 */
public class AlipayFaceToFace {
    public static void main(String[] srgs) throws Exception {
        CommonUtils commonUtils=new CommonUtils();
        /** Alipay gateway **/
        String URL =  commonUtils.getZFBinfoValue("open_api_domain");

        /** For application id, please refer to: https://opensupport.alipay.com/support/helpcenter/190/201602493024  **/
        String APP_ID = commonUtils.getZFBinfoValue("appid");

        /** Please refer to: https://opensupport.alipay.com/support/helpcenter/207/201602469554  **/
        String APP_PRIVATE_KEY = commonUtils.getZFBinfoValue("private_key");

        /** How to get the Alipay public key, please refer to: https://opensupport.alipay.com/support/helpcenter/207/201602487431  **/
        String ALIPAY_PUBLIC_KEY =commonUtils.getZFBinfoValue("alipay_public_key");

        /** Initialization**/
        AlipayClient alipayClient = new DefaultAlipayClient(URL,APP_ID,APP_PRIVATE_KEY,"json","UTF-8",ALIPAY_PUBLIC_KEY,"RSA2");

        /** Instantiate specific API corresponding to request class, class name and interface name corresponding, the current call interface name: alipay.trade.precreate (pre creation of transactions under unified receipt line (code scanning payment))**/
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();

        /** Set business parameters**/
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();

        /** Merchant order number, customized by the merchant, shall not be repeated at the merchant end, such as 20200612000001**/
        model.setOutTradeNo("20200612000005");

        /**Order title**/
        model.setSubject("Hairy test");

        /** Order amount, accurate to two decimal places**/
        model.setTotalAmount("0.01");

        /** Order description**/
        model.setBody("");

        /** Business extension parameters**/
        //ExtendParams extendParams = new ExtendParams();

        /** The system provider number, fill in the PID of the service provider, and use it to obtain the Commission return. The prerequisite for value transfer of commission return parameters: the value transfer account needs to sign a commission return agreement for isv merchants**/
        //extendParams.setSysServiceProviderId("2088511****07846");

        /** Prerequisite for transferring the value of the flower installment parameter: there must be the flower installment collection access condition of the interface, and the flower installment must be signed**/
        /** Specify the number of optional periods. Only 3 / 6 / 12 periods are supported. The longer the number of repayment periods, the higher the handling fee**/
        // extendParams.setHbFqNum("3");

        /** Specify the way to bear the service charge of Huabai installment. The service charge can be fully borne by the user (the value is 0) or by the merchant (the value is 100), but it can not be shared, that is, other values other than 0 and 100 are not acceptable. 			**/
        //extendParams.setHbFqSellerPercent("0");

        //model.setExtendParams(extendParams);

        /** Pass business parameters to request**/
        request.setBizModel(model);

        /** Asynchronous notification address, starting with http or HTTPS, the asynchronous address of post can be used to receive the payment result returned by Alipay. If the notification is not received, it can be confirmed by referring to the document. 			 https://opensupport.alipay.com/support/helpcenter/193/201602475759  **/
        request.setNotifyUrl("");

        /**Third party call (service provider mode). After transferring the value app_auth_token, the payment will be received to the merchant account corresponding to the authorized app_auth_token. Please refer to the document for how to obtain the value app_auth_token: 				 https://opensupport.alipay.com/support/helpcenter/79/201602494631  **/
        //request.putOtherTextParam("app_auth_token", "pass in the obtained app_auth_token value");

        AlipayTradePrecreateResponse response = null;
        try {

            /** Call the API through alipayClient to obtain the corresponding response class**/
            response = alipayClient.execute(request);

        } catch (AlipayApiException e) {

            e.printStackTrace();
        }

        /** Get the interface call result. If the call fails, you can find the troubleshooting scheme in the document according to the returned error information: https://opensupport.alipay.com/support/helpcenter/101  **/
        System.out.println(response.getBody());
    }
}

Figure 13

1.2 combined with front-end code scanning payment

1.2. 1 create ZFBFaceToFaceModel entity object
package com.test.model;

import com.alipay.api.domain.GoodsDetail;

import java.util.List;

/**
 * Alipay pays face-to-face entities
 * @author 20201217 sqy
 *
 */
public class ZFBFaceToFaceModel {
   private String outTradeNo;// (required) the unique order number in the order system of the merchant website, within 64 characters, can only contain letters, numbers and underscores. It is necessary to ensure that the merchant system can not be repeated. It is recommended to generate it through database sequence
   private String subject; // (required) Order title, which roughly describes the user's payment purpose. Such as "consumption of xisduo (Pudong store)"
   private String totalAmount;// (required) the total order amount is in yuan, which cannot exceed 100 million yuan. If discount amount, non discount amount and total order amount are passed in at the same time, the following conditions must be met: [total order amount] = [discount amount] + [non discount amount]
   private String undiscountableAmount;// (optional) the non discount amount of the order can be configured with the merchant platform. If the drinks do not participate in the discount, the corresponding amount will be filled in this field. If the value is not passed in, but the total order amount and discount amount are passed in, the default value is total order amount - discount amount
   private String sellerId;// The seller's Alipay account ID is used to support a signed account to support the payment to different account receipts. (to sellerId corresponding Alipay account) / / if the field is empty, the default is PID, which is signed by Alipay, which is the PID corresponding to appid.
   private String body;// //Order description can describe the transaction or goods in detail, such as filling in "2 purchased goods, a total of 15.00 yuan"
   private String operatorId; // Merchant operator number. Add this parameter to make sales statistics for merchant operators
   private String storeId; // (required) merchant shop number, through the store number and business backstage can be configured to store discount information accurately, detailed inquiry Alipay technical support
   private String timeoutExpress;//Payment timeout, such as "120m", is defined as 120 minutes
   private List<GoodsDetail> goodsDetailList; //Detailed list of goods, details of purchased goods shall be filled in,
   private String NotifyUrl;// The interface address that Alipay calls asynchronously after the payment is successful.
   private String MoblieReturnUrl;//Mobile payment synchronization notification page address;
   /**
    * (Required) the unique order number in the merchant website order system, which is within 64 characters and can only contain letters, numbers and underscores. It is necessary to ensure that the merchant system side cannot be repeated. It is recommended to generate it through database sequence
    * @return
    */
   public String getOutTradeNo() {
      return outTradeNo;
   }
   /**
    * (Required) the unique order number in the merchant website order system, which is within 64 characters and can only contain letters, numbers and underscores. It is necessary to ensure that the merchant system side cannot be repeated. It is recommended to generate it through database sequence
    * @param outTradeNo
    */
   public void setOutTradeNo(String outTradeNo) {
      this.outTradeNo = outTradeNo;
   }
   /**
    * ((required) Order title, which roughly describes the user's payment purpose. Such as "consumption of xisduo (Pudong store)"
    * @return
    */
   public String getSubject() {
      return subject;
   }
   /**
    * ((required) Order title, which roughly describes the user's payment purpose. Such as "consumption of xisduo (Pudong store)"
    * @param subject
    */
   public void setSubject(String subject) {
      this.subject = subject;
   }
   /**
    *  ((required) the total order amount is in Yuan and cannot exceed 100 million yuan. If discount amount, non discount amount and total order amount are passed in at the same time, the following conditions must be met: [total order amount] = [discount amount] + [non discount amount]
    * @return
    */
   public String getTotalAmount() {
      return totalAmount;
   }
   /**
    *  ((required) the total order amount is in Yuan and cannot exceed 100 million yuan. If discount amount, non discount amount and total order amount are passed in at the same time, the following conditions must be met: [total order amount] = [discount amount] + [non discount amount]
    * @param totalAmount
    */
   public void setTotalAmount(String totalAmount) {
      this.totalAmount = totalAmount;
   }
   /**
    * ((optional) the non discount amount of the order can be configured with the merchant platform. If the drinks do not participate in the discount, the corresponding amount will be filled in this field. If the value is not passed in, but the total order amount and discount amount are passed in, the default value is total order amount - discount amount
    * @return
    */
   public String getUndiscountableAmount() {
      return undiscountableAmount;
   }
   /**
    * ((optional) the non discount amount of the order can be configured with the merchant platform. If the drinks do not participate in the discount, the corresponding amount will be filled in this field. If the value is not passed in, but the total order amount and discount amount are passed in, the default value is total order amount - discount amount
    * @param undiscountableAmount
    */
   public void setUndiscountableAmount(String undiscountableAmount) {
      this.undiscountableAmount = undiscountableAmount;
   }
   /**
    * // The seller's Alipay account ID is used to support a signed account to support the payment to different account receipts. (to sellerId corresponding Alipay account) / / if the field is empty, the default is PID, which is signed by Alipay, which is the PID corresponding to appid.
    * @return
    */
   public String getSellerId() {
      return sellerId;
   }
   /**
    * // The seller's Alipay account ID is used to support a signed account to support the payment to different account receipts. (to sellerId corresponding Alipay account) / / if the field is empty, the default is PID, which is signed by Alipay, which is the PID corresponding to appid.
    * @param sellerId
    */
   public void setSellerId(String sellerId) {
      this.sellerId = sellerId;
   }
   /**
    * Order description can describe the transaction or goods in detail, such as filling in "2 purchased goods, a total of 15.00 yuan"
    * @return
    */
   public String getBody() {
      return body;
   }
   /**
    * Order description can describe the transaction or goods in detail, such as filling in "2 purchased goods, a total of 15.00 yuan"
    * @param body
    */
   public void setBody(String body) {
      this.body = body;
   }
   /**
    *Merchant operator number. Add this parameter to make sales statistics for merchant operators
    * @return
    */
   public String getOperatorId() {
      return operatorId;
   }
   /**
    *Merchant operator number. Add this parameter to make sales statistics for merchant operators
    * @param operatorId
    */
   public void setOperatorId(String operatorId) {
      this.operatorId = operatorId;
   }
   /**
    * (The number of merchant stores is specified, and the discount information can be configured accurately through store numbers and merchant backstage. Detailed information about Alipay technical support is given.
    * @return
    */
   public String getStoreId() {
      return storeId;
   }
   /**
    * (The number of merchant stores is specified, and the discount information can be configured accurately through store numbers and merchant backstage. Detailed information about Alipay technical support is given.
    * @param storeId
    */
   public void setStoreId(String storeId) {
      this.storeId = storeId;
   }
   /**
    *Payment timeout, such as "120m", is defined as 120 minutes
    * @return
    */
   public String getTimeoutExpress() {
      return timeoutExpress;
   }
   /**
    *Payment timeout, such as "120m", is defined as 120 minutes
    * @param timeoutExpress
    */
   public void setTimeoutExpress(String timeoutExpress) {
      this.timeoutExpress = timeoutExpress;
   }
   /**
    *Detailed list of goods, details of purchased goods shall be filled in,
    * @return
    */
   public List<GoodsDetail> getGoodsDetailList() {
      return goodsDetailList;
   }
   /**
    *Detailed list of goods, details of purchased goods shall be filled in,
    * @param goodsDetailList
    */
   public void setGoodsDetailList(List<GoodsDetail> goodsDetailList) {
      this.goodsDetailList = goodsDetailList;
   }
   /**
    *The interface address that Alipay calls asynchronously after the payment is successful.
    * @return
    */
   public String getNotifyUrl() {
      return NotifyUrl;
   }
   /**
    *The interface address that Alipay calls asynchronously after the payment is successful.
    * @param notifyUrl
    */
   public void setNotifyUrl(String notifyUrl) {
      NotifyUrl = notifyUrl;
   }
   /**
    * Page address to jump after mobile payment
    * @return
    */
   public String getMoblieReturnUrl() {
      return MoblieReturnUrl;
   }
   /**
    * Page address to jump after mobile payment
    * @return
    */
   public void setMoblieReturnUrl(String moblieReturnUrl) {
      MoblieReturnUrl = moblieReturnUrl;
   }
}
1.2. 2. Write the AlipayFaceToFace class

The control layer calls the zfbpriorder method Alipay pre order Returns a json string, including the QR code address

package Alipay;

import Alipay.util.CommonUtils;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.test.model.ZFBFaceToFaceModel;

/**
 * Alipay face-to-face payment
 */
public class AlipayFaceToFace {
    /**
     * Alipay pre order
     * @param zfbFaceToFaceModel
     * @return
     */
    public static String ZFBPreorder(ZFBFaceToFaceModel zfbFaceToFaceModel) {
        try {
            CommonUtils commonUtils = new CommonUtils();
            /** Alipay gateway **/
            String URL = commonUtils.getZFBinfoValue("open_api_domain");

            /** For application id, please refer to: https://opensupport.alipay.com/support/helpcenter/190/201602493024  **/
            String APP_ID = commonUtils.getZFBinfoValue("appid");

            /** Please refer to: https://opensupport.alipay.com/support/helpcenter/207/201602469554  **/
            String APP_PRIVATE_KEY = commonUtils.getZFBinfoValue("private_key");

            /** How to get the Alipay public key, please refer to: https://opensupport.alipay.com/support/helpcenter/207/201602487431  **/
            String ALIPAY_PUBLIC_KEY = commonUtils.getZFBinfoValue("alipay_public_key");

            /** Initialization**/
            AlipayClient alipayClient = new DefaultAlipayClient(URL, APP_ID, APP_PRIVATE_KEY, "json", "UTF-8", ALIPAY_PUBLIC_KEY, "RSA2");

            /** Instantiate specific API corresponding to request class, class name and interface name corresponding, the current call interface name: alipay.trade.precreate (pre creation of transactions under unified receipt line (code scanning payment))**/
            AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();

            /** Set business parameters**/
            AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();

            /** Merchant order number, customized by the merchant, shall not be repeated at the merchant end, such as 20200612000001**/
            model.setOutTradeNo(zfbFaceToFaceModel.getOutTradeNo());

            /**Order title**/
            model.setSubject(zfbFaceToFaceModel.getSubject());

            /** Order amount, accurate to two decimal places**/
            model.setTotalAmount(zfbFaceToFaceModel.getTotalAmount());

            /** Order description**/
            model.setBody(zfbFaceToFaceModel.getBody());

            /** Business extension parameters**/
            //ExtendParams extendParams = new ExtendParams();

            /** The system provider number, fill in the PID of the service provider, and use it to obtain the Commission return. The prerequisite for value transfer of commission return parameters: the value transfer account needs to sign a commission return agreement for isv merchants**/
            //extendParams.setSysServiceProviderId("2088511****07846");

            /** Prerequisite for transferring the value of the flower installment parameter: there must be the flower installment collection access condition of the interface, and the flower installment must be signed**/
            /** Specify the number of optional periods. Only 3 / 6 / 12 periods are supported. The longer the number of repayment periods, the higher the handling fee**/
            // extendParams.setHbFqNum("3");

            /** Specify the way to bear the service charge of Huabai installment. The service charge can be fully borne by the user (the value is 0) or by the merchant (the value is 100), but it can not be shared, that is, other values other than 0 and 100 are not acceptable**/
            //extendParams.setHbFqSellerPercent("0");

            //model.setExtendParams(extendParams);

            /** Pass business parameters to request**/
            request.setBizModel(model);

            /** Asynchronous notification address, starting with http or HTTPS, the asynchronous address of post can be used to receive the payment result returned by Alipay. If the notification is not received, it can be confirmed by referring to the document. https://opensupport.alipay.com/support/helpcenter/193/201602475759  **/
            request.setNotifyUrl(zfbFaceToFaceModel.getNotifyUrl());

            /**Third party call (service provider mode). After transferring the value app_auth_token, the payment will be received to the merchant account corresponding to the authorized app_auth_token. Please refer to the document for how to obtain the value app_auth_token: https://opensupport.alipay.com/support/helpcenter/79/201602494631  **/
            //request.putOtherTextParam("app_auth_token", "pass in the obtained app_auth_token value");

            /** Call the API through alipayClient to obtain the corresponding response class**/
            AlipayTradePrecreateResponse response = alipayClient.execute(request);

            /** Get the interface call result. If the call fails, you can find the troubleshooting scheme in the document according to the returned error information: https://opensupport.alipay.com/support/helpcenter/101  **/
            System.out.println(response.getBody());
            return response.getBody();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
1.2. 3. Write zfbpriorderaction class
package com.test.controller;

import Alipay.AlipayFaceToFace;
import Alipay.util.CommonUtils;
import com.alibaba.fastjson.JSONObject;
import com.test.model.ZFBFaceToFaceModel;
import com.test.service.TestService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/AlipayFaceToFaceController")
public class AlipayFaceToFaceController {

    /**
     * Alipay booking order
     * It is used to accept the front-end request and return it to the front-end QR code address and the merchant's unique order number
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/ZFBPreorderAction")
    @ResponseBody
    public Map<String,Object> ZFBPreorderAction(HttpServletRequest request,HttpServletResponse response){
        Map<String,Object> resultMap=new HashMap<String, Object>();
        try {
            CommonUtils commonUtils=new CommonUtils();
            //(required) merchant unique order number
            String outTradeNo= CommonUtils.getUuid();
            // (required) Order title, which roughly describes the user's payment purpose. Such as "consumption of xisduo (Pudong store)"
            String subject ="Gross consumption (China)";
            // (required) total order amount, in yuan, which cannot exceed 100 million yuan
            String totalAmount = "0.01";
            //(required) payment of the interface address of Alipay's asynchronous notification.
            String NotifyUrl=commonUtils.getZFBinfoValue("NotifyUrl");
            //Placing parameters in a solid object
            ZFBFaceToFaceModel zfbFaceToFaceModel=new ZFBFaceToFaceModel();
            zfbFaceToFaceModel.setOutTradeNo(outTradeNo);
            zfbFaceToFaceModel.setSubject(subject);
            zfbFaceToFaceModel.setTotalAmount(totalAmount);
            zfbFaceToFaceModel.setNotifyUrl(NotifyUrl);
            //Alipay pre order
            String json=AlipayFaceToFace.ZFBPreorder(zfbFaceToFaceModel);
            //Parsing json data
            JSONObject jsonObject=JSONObject.parseObject(json);
            //Get Alipay_ trade_ precreate_ After the response data, the JSONObject is forcibly converted
            JSONObject jsonobj_two=(JSONObject)jsonObject.get("alipay_trade_precreate_response");
            //Then through jsonobj_two get QR code address
            String qrcode=jsonobj_two.get("qr_code").toString();

            resultMap.put("qrcode",qrcode);
            resultMap.put("outTradeNo",outTradeNo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultMap;
    }
}
1.2. 4. The front page calls zfbpriorderaction method to generate payment QR code

Please note that you must refer to jQuery qrcode. Min.js or you can't generate QR code

Run the project and click "click to generate payment QR code" on the page, and then you can scan the code for payment using your mobile phone

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Alipay two-dimensional code payment</title>
    <script type="text/javascript" src="js/jquery-1.11.2.min.js"></script>
    <script type="text/javascript" src="js/jquery.qrcode.min.js"></script>
</head>
<body>
    <a href="javascript:void(0);" onclick="Pay()">Click to generate payment QR code</a>
    <div id="Orcode_div" style="height: 165px;width: 165px"></div>
</body>
<script type="application/javascript">
    //entry name
    var basePath="/byyu";
    //Merchant order number
	var outTradeNo;
    //Pre order
    function Pay(){
        $.ajax({
            url: basePath + '/AlipayFaceToFaceController/ZFBPreorderAction.action',
            method: 'post',
            async: false,  //Asynchronous request (truefalse is synchronous request by default, and true is asynchronous request)
            dataType: 'JSON',
            success: function (res) {
                //Merchant order number
                outTradeNo=res.outTradeNo;
                //Create order QR code
                createQrcode(res.qrcode);
            }
        })
    }
    var zfbQRCode;
    //Generate payment QR code
    function createQrcode(url){
        if (zfbQRCode!=undefined && zfbQRCode!='') {
            //Clear previous QR code
            $("#Orcode_div canvas").remove()
            $("#yes_qrcode").hide();
        }
        //Generate QR code and put it into "orcode"_ div“ div
        zfbQRCode=$('#Orcode_div').qrcode({
            width: 168, //width
            height: 168, //height
            text:url
        });
    }
</script>
</html>
1.2. 5. The effect drawing is shown in Figure 14

Figure 14

2. Transaction status query

Preface: we have called Alipay at the top. Pre order The function generates a QR code. Next, you need to query the transaction status and prompt the user that the payment is successful

Note: do not use any system business logic to query the transaction status. Even if the user pays successfully, do not use business logic processing. Business logic processing needs to be processed in asynchronous callback, as will be described below

2.1 create findZFB_trade method

Copy the following methods into the AlipayFaceToFace class

public static String findZFB_trade(ZFBFaceToFaceModel zfbFaceToFaceModel) throws Exception{
    CommonUtils commonUtils = new CommonUtils();
    /** Alipay gateway **/
    String URL = commonUtils.getZFBinfoValue("open_api_domain");

    /** For application id, please refer to: https://opensupport.alipay.com/support/helpcenter/190/201602493024  **/
    String APP_ID = commonUtils.getZFBinfoValue("appid");

    /** Please refer to: https://opensupport.alipay.com/support/helpcenter/207/201602469554  **/
    String APP_PRIVATE_KEY = commonUtils.getZFBinfoValue("private_key");

    /** How to get the Alipay public key, please refer to: https://opensupport.alipay.com/support/helpcenter/207/201602487431  **/
    String ALIPAY_PUBLIC_KEY = commonUtils.getZFBinfoValue("alipay_public_key");

    /** Initialization**/
    AlipayClient alipayClient = new DefaultAlipayClient(URL,APP_ID,APP_PRIVATE_KEY,"json","UTF-8",ALIPAY_PUBLIC_KEY,"RSA2");

    /** Instantiate specific API corresponding to request class, class name and interface name corresponding, the current call interface name: alipay.trade.query (transaction query under unified receipt line)**/
    AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();

    /** Set business parameters**/
    AlipayTradeQueryModel model = new AlipayTradeQueryModel();

    /** Note: one of the transaction number (TradeNo) and the order number (OutTradeNo) can be imported. If two are imported at the same time, the transaction number shall prevail**/
    /** Merchant order number passed in from the payment interface. For example: 20200616012900011200000140004**/
    model.setOutTradeNo(zfbFaceToFaceModel.getOutTradeNo());

    /** The Alipay transaction number returned by the asynchronous notification / query interface, such as: 2020061622001473951448314322 **/
    //model.setTradeNo("2020061622001473951448314322");

    /** Pass business parameters to request**/
    request.setBizModel(model);

    /** For the third-party call (service provider mode), the app_auth_token with the same value as the payment interface must be passed**/
    //request.putOtherTextParam("app_auth_token", "pass in the obtained app_auth_token value");

    /** Call the API through alipayClient to obtain the corresponding response class**/
    AlipayTradeQueryResponse response = alipayClient.execute(request);

    /** Get the interface call result. If the call fails, you can find the troubleshooting scheme in the document according to the returned error information: https://opensupport.alipay.com/support/helpcenter/101  **/
    return response.getBody();
}

2.2 create findZFB_tradeAction method

Copy the following methods into the alipayfacetofafecontroller class

@RequestMapping("/findZFB_tradeAction")
@ResponseBody
public Map<String,Object> findZFB_tradeAction(HttpServletRequest request,HttpServletResponse response){
    Map<String,Object> resultMap=new HashMap<String, Object>();
    try {
        //(required) merchant unique order number
        String outTradeNo=request.getParameter("outTradeNo");
        ZFBFaceToFaceModel zfbFaceToFaceModel=new ZFBFaceToFaceModel();
        zfbFaceToFaceModel.setOutTradeNo(outTradeNo);
        //Query transaction status
        String json=AlipayFaceToFace.findZFB_trade(zfbFaceToFaceModel);
        System.out.println(json);
        JSONObject jsonObject=JSONObject.parseObject(json);
        JSONObject jsonobj_two=(JSONObject)jsonObject.get("alipay_trade_query_response");
        //Gateway return code, see the document for details https://opendocs.alipay.com/open/common/105806
        String ZFBCode=(String)jsonobj_two.get("code");
        //Service return code
        String ZFBSubCode=(String)jsonobj_two.get("sub_code");
        //Service return code description
        String sub_msg=(String)jsonobj_two.get("sub_msg");
        //Transaction status: WAIT_BUYER_PAY (transaction creation, waiting for buyer's payment), TRADE_CLOSED (overdue transaction closed, or full refund after payment is completed), TRADE_SUCCESS (transaction payment succeeded), TRADE_FINISHED (transaction closed, non refundable)
        String trade_status=(String)jsonobj_two.get("trade_status");
        if (ZFBCode.equals("40004") && ZFBSubCode.equals("ACQ.TRADE_NOT_EXIST")) {
            //The order was not created (the user did not scan the code)
            resultMap.put("code", ZFBCode);
            resultMap.put("data", "The user did not scan the code");
        } else if (ZFBCode.equals("10000") && trade_status.equals("WAIT_BUYER_PAY")) {
            //The order has been created but not paid (the user scans the code but not paid)
            resultMap.put("code", ZFBCode);
            resultMap.put("data", "non-payment");
        } else if (ZFBCode.equals("10000") && (trade_status.equals("TRADE_SUCCESS") || trade_status.equals("TRADE_FINISHED"))) {
            //Judge whether ZFBCode is equal to "10000" and trade_status is equal to TRADE_SUCCESS or trade_status is equal to TRADE_FINISHED
            //The order has been paid (after the code scanning is completed and the payment is successful)
            resultMap.put("code", ZFBCode);
            resultMap.put("data", "yes-payment");
        } else {
            resultMap.put("code", ZFBCode);
            resultMap.put("data", sub_msg);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return resultMap;
}

2.2 HTML timing call

Copy the following code to alipaqrcodepayment HTML page

The method needs to be called after the creation of two-dimensional code. This method will regularly query the transaction status, and then write the following code according to your business requirements, such as jumping to the page...

//Timed task
var trade;
//Whether the record notifies the page that "the user has scanned the code"
var findNumber=true
/**
 * Query transaction status
 */
function findZFB_trade(){
    trade = setInterval(function(){
        console.log("Every 3 seconds");
        $.ajax({
            url: basePath +'/AlipayFaceToFaceController/findZFB_tradeAction.action',
            method: 'post',
            async: false,  //Asynchronous request (truefalse is synchronous request by default, and true is asynchronous request)
            data: {
                "outTradeNo": outTradeNo
            },
            dataType: 'JSON',
            success: function (res) {
                if (res.code=='10000' && res.data=='non-payment'){
                    //The order has been created but not paid (the user scans the code but not paid)
                    if (findNumber){
                        console.log("The user has scanned the code but has not paid");
                        findNumber=false;
                    }
                }else if (res.code=='10000' && res.data=='yes-payment'){
                    //Block timing
                    window.clearInterval(trade);
                    alert("The order has been paid, thank you for your support...");
                }
            }
        })
    },3000);
}

2.4 final effect drawing

3. Alipay asynchronous notification

Note: for the sake of system security, all business logic processing needs to be processed in asynchronous callback and cannot be processed in query transaction status.

Asynchronous notification function: it is said at the top of the article that querying the transaction status does not do any business logic processing. Next, we need to rely on this method for business logic code processing. The following ZFBcallback Alipay will automatically call the user after the success of the scan code. It will transmit some parameters to tell the server that the order payment is successful and then the system needs to make some listed businesses, such as modifying the order status of the user, etc.

3.1 intranet penetration

Since we need to accept Alipay to callback, our computer needs to be accessed by the external network, so our computer needs to make internal network penetration so that the external network can access our interface.

The specific operation methods can be Baidu

3.2 setting callback interface address

Add the delegated code to the zfbpriorder method in the AlipayFaceToFace class, and fill in your project address with the parameter in setNotifyUrl(), such as: https://test.domainName.com/project/AlipayFaceToFaceController/ZFBcallback.action What I write below is zfbfacetofacemodel Getnotifyurl() is from zfbinfo The address obtained from the properties file must be accessible from the Internet and accept the POST request (GET is not allowed).

 	/** Asynchronous notification address, starting with http or HTTPS, the asynchronous address of post can be used to receive the payment result returned by Alipay. If the notification is not received, it can be confirmed by referring to the document. 			 https://opensupport.alipay.com/support/helpcenter/193/201602475759  **/
    request.setNotifyUrl(zfbFaceToFaceModel.getNotifyUrl());

3.3 write ZFBcallback callback function

Copy the following methods to the alipayfacetofaccecontroller class

It is important to note that in this method, you must have an asynchronous signature. In brief, you need to verify whether the interface is called by Alipay. It is mainly for safety, so as to prevent the criminals from calling your method to forge data, so this method needs to be checked when calling.

//Asynchronous check sign: remember that alipaypublickey is Alipay's public key, please go to open.. alipay. Com corresponding application.
boolean flag = AlipaySignature.rsaCheckV1(params, alipay_public_key, "utf-8","RSA2");

Note: Alipay will automatically call the following method after Alipay has successfully paid the user again. (if you set up callback interface address, see the code above), you need to return to "success" after the completion of the call. Alipay, if you do not return to Alipay, will call the method regularly. So you need to complete a series of business operations after receiving this method, and then you need to return the "success" string. And pay attention to whether the interceptor is intercepted (if you are intercepted by your login interceptor, Alipay will not be able to access this method).

/**
 * The callback function is paid (when the user pays successfully, Alipay automatically calls the method).
 * This interface needs to be accessed by the external network and must be a POST request, and if the interceptor is intercepted, if it is intercepted by your login interceptor, Alipay will not be able to access the method.
 * @param request
 * @param response
 */
@RequestMapping("/ZFBcallback")
public void ZFBcallback(HttpServletRequest request, HttpServletResponse response) throws IOException {
    try {
        CommonUtils commonUtils=new CommonUtils();
        //Alipay public key
        String alipay_public_key=commonUtils.getZFBinfoValue("alipay_public_key");
        PrintWriter out;
        out = response.getWriter();
        //Get feedback from Alipay POST
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        //Loop traverses the parameters of Alipay request to store in params.
        for (Iterator 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);
        }
        //Asynchronous check sign: remember that alipaypublickey is Alipay's public key, please go to open.. alipay. Com corresponding application.
        boolean flag = AlipaySignature.rsaCheckV1(params, alipay_public_key, "utf-8","RSA2");
        if (flag){
            //Description is the interface that Alipay calls.
            if (params.get("trade_status").equals("TRADE_SUCCESS") || params.get("trade_status").equals("TRADE_FINISHED")) {
                System.out.println("After receiving the callback result, the user has completed the payment");
                /***
                 * Write your business logic code here
                 */
                out.write("success");
            }
        }else {
           	//Signature verification failed. The interface was called by others
            out.write("Alipay asynchronous callback check failed, please note");
        }
        out.flush();
        out.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

3.4 final effect drawing

This shows that the user has paid successfully, and then he can do the corresponding business logic processing according to his business needs

Keywords: Java Dubbo Back-end

Added by ScottCFR on Sat, 25 Dec 2021 11:22:02 +0200