Alipay sandbox payment test

Table of Contents

1. Development preparation

2. Configure the environment

3. Payment interface

4. Preliminary verification

5. Interface callback

6.Intranet penetration


1. Development preparation

First, use Alipay to scan the QR code to log in to the Alipay development platform.

Login – Alipay

Select Development Tools Sandbox

Enable public key mode, set the gateway address, and copy and paste the Alipay gateway address above.

Alipay – Online payment is safe and fast!

2. Configuration environment

Configure dependencies in pom.xml.

<dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-easysdk</artifactId>
            <version>2.2.0</version>
        </dependency>

Configure in application.yml. Note: There is a space after the colon when configuring.

?
alipay:
  appId:
  appPrivateKey:
  alipayPublicKey:
  notifyUrl:

?

The first three configuration parameters are applied in the console sandbox and configured after notifyUrl.

Then click Document>Webpage &Mobile Application>Development Tools>Development Tools>Development Tool Kit (SDK) Download>Server SDK>Java>Easy Version

Configure initialization parameters, the code can be found in the sample code.

import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.factory.Factory.Payment;
import com.alipay.easysdk.kernel.Config;
import com.alipay.easysdk.kernel.util.ResponseChecker;
import com.alipay.easysdk.payment.facetoface.models.AlipayTradePrecreateResponse;
public class Main {
    public static void main(String[] args) throws Exception {
        // 1. Set parameters (only need to be set once globally)
        Factory.setOptions(getOptions());
        try {
            // 2. Initiate an API call (take creating a QR code for in-person payment and collection as an example)
            AlipayTradePrecreateResponse response = Payment.FaceToFace()
                    .preCreate("Apple iPhone11 128G", "2234567890", "5799.00");
            // 3. Handle response or exception
            if (ResponseChecker.success(response)) {
                System.out.println("Call successful");
            } else {
                System.err.println("Call failed, reason: " + response.msg + ", " + response.subMsg);
            }
        } catch (Exception e) {
            System.err.println("The call encountered an exception, reason: " + e.getMessage());
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    private static Config getOptions() {
        Config config = new Config();
        config.protocol = "https";
        config.gatewayHost = "openapi.alipay.com";
        config.signType = "RSA2";
        config.appId = "<-- Please fill in your AppId, for example: 2019091767145019 -->";
        // To avoid the private key being leaked along with the source code, it is recommended to read the private key string from the file rather than writing it into the source code.
        config.merchantPrivateKey = "<-- Please fill in your application private key, for example: MIIEvQIBADANB ... ... -->";
        //Note: The certificate file path can be set to the path in the file system or the path in CLASS_PATH. It will be loaded from the file system first. If the loading fails, it will continue to try to load from CLASS_PATH.
        config.merchantCertPath = "<-- Please fill in the path of your application public key certificate file, for example: /foo/appCertPublicKey_2019051064521003.crt -->";
        config.alipayCertPath = "<-- Please fill in your Alipay public key certificate file path, for example: /foo/alipayCertPublicKey_RSA2.crt -->";
        config.alipayRootCertPath = "<-- Please fill in the path of your Alipay root certificate file, for example: /foo/alipayRootCert.crt -->";
        //Note: If non-certificate mode is used, there is no need to assign the above three certificate paths. Instead, assign the following Alipay public key string.
        // config.alipayPublicKey = "<-- Please fill in your Alipay public key, for example: MIIBIjANBg... -->";
        //You can set the asynchronous notification receiving service address (optional)
        config.notifyUrl = "<-- Please fill in your payment interface asynchronous notification receiving service address, for example: https://www.test.com/callback -->";
        //AES key can be set, required when calling AES encryption and decryption related interfaces (optional)
        config.encryptKey = "<-- Please fill in your AES key, for example: aa4BtZ4tspm2wnXLb1ThQA== -->";
        return config;
    }
}

3. Payment interface

Official sample code

Factory.Payment.FaceToFace()
    // Call the agent extension method, set app_auth_token, and complete the third-party proxy call
    .agent("ca34ea491e7146cc87d25fca24c4cD11")
    .preCreate("Apple iPhone11 128G", "2234567890", "5799.00");

As shown above, third-party calls require three data, which are, in order, transaction name, Alipay transaction voucher number, and transaction amount.

The voucher number cannot be the same for each transaction.

From the above information, create a payment interface.

Create a new AliPayController.java

import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.example.springboot.controller.dto.AliPay;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.net.URLEncoder;

@RestController
@RequestMapping("/alipay")
public class AliPayController {

 @GetMapping("/pay") // & amp;subject=xxx & amp;traceNo=xxx & amp;totalAmount=xxx
    public String pay(AliPay aliPay) {
        AlipayTradePagePayResponse response;
        try {
            // Initiate an API call (taking creating a QR code for face-to-face payment as an example)
            response = Factory.Payment.Page()
                    .pay(URLEncoder.encode(aliPay.getSubject(), "UTF-8"), aliPay.getTraceNo(), aliPay.getTotalAmount(), "");
        } catch (Exception e) {
            System.err.println("The call encountered an exception, reason: " + e.getMessage());
            throw new RuntimeException(e.getMessage(), e);
        }
        return response.getBody();
    }
}

Create entity class Alipay.java

import lombok.Data;

@Data
public class AliPay {
    //Name of Trade
    private String subject;
    //Alipay transaction voucher number
    private String traceNo;
    //Amount of the transaction
    private String totalAmount;
}

Then add the configuration of ignoring interface alipay to the interceptor.

4. Preliminary verification

URL:http://localhost:8080/alipay/pay?subject=xxx & traceNo=xxx & totalAmount=100

Then you can choose the buyer’s sandbox account and password to log in and pay, or download the sandbox version of Alipay APP to log in with your account and password and scan the QR code to pay.

5.Interface callback

If you want to receive feedback from the Alipay development platform, you need an interface callback.

//Determine whether the Alipay payment transaction is successful. true,false.
request.getParameter("trade_status").equals("TRADE_SUCCESS")

Payment class asynchronous notification signature verification sample code, available on the official platform.

Map<String, String> parameters = new HashMap<>();
parameters.put("charset", "UTF-8");
parameters.put("sign", "GM0CbuqaEivqgb......");
parameters.put("app_id", "2018091261392200");
parameters.put("sign_type", "RSA2");
parameters.put("isv_ticket", "");
parameters.put("timestamp", "2020-03-25 16:27:08");
//... ...put all received parameters into a Map
Factory.Payment.Common().verifyNotify(parameters);

Add the following code to AliPayController.java. Feedback data can be processed there. Provide feedback to the front desk.

 @PostMapping("/notify") // Note that this must be a POST interface
    public String payNotify(HttpServletRequest request) throws Exception {
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                params.put(name, request.getParameter(name));
            }

            String tradeNo = params.get("out_trade_no");
            String gmtPayment = params.get("gmt_payment");
            String alipayTradeNo = params.get("trade_no");
            // Alipay signature verification
            if (Factory.Payment.Common().verifyNotify(params)) {
                //Signature verification passed
                System.out.println("Transaction name: " + params.get("subject"));
                System.out.println("Trade status: " + params.get("trade_status"));
                System.out.println("Alipay transaction voucher number: " + params.get("trade_no"));
                System.out.println("Merchant order number: " + params.get("out_trade_no"));
                System.out.println("Transaction amount: " + params.get("total_amount"));
                System.out.println("The buyer's unique ID in Alipay: " + params.get("buyer_id"));
                System.out.println("Buyer payment time: " + params.get("gmt_payment"));
                System.out.println("Buyer payment amount: " + params.get("buyer_pay_amount"));

            }
        }
        return "******";
    }

6. Intranet penetration

Then because of localhost, the Alipay development platform cannot transmit feedback data.

Intranet penetration is required.

Natapp software address: https://natapp.cn/

Select the required version and download it yourself.

After logging in and registering, purchase a free tunnel, configure your own port number, and purchase it for free.

Click to copy the authtoken number.

Create authtoken startup item.

Then open the downloaded Natapp software folder, create text, add the following code to the authtoken number copied previously, and then change the file suffix to bat.

natapp.exe -authtoken=

Click the start.bat file to start. The following display proves that the startup is successful.

Change the configuration in application.yml:

Then functional testing can be carried out.