Integrating Alipay's New Transfer Interface with Spring Boot (Java)

This tutorial explains how to upgrade to Alipay's new transfer API alipay.fund.trans.uni.transfer, update the SDK, configure certificates and properties, and implement Spring Boot components and utility classes for secure backend payment integration.

Top Architect
Top Architect
Top Architect
Integrating Alipay's New Transfer Interface with Spring Boot (Java)

Alipay has released a new transfer interface alipay.fund.trans.uni.transfer that replaces the old alipay.fund.trans.toaccount.transfer and uses certificate‑based verification for higher security.

To use the new interface, upgrade the Alipay SDK to version 4.10.97 (or later) and place the three certificates downloaded from the Alipay Open Platform under the resources directory.

Step 1: Add the certificates ( appCertPublicKey_*.crt, alipayCertPublicKey_RSA2.crt, alipayRootCert.crt) to src/main/resources.

Step 2: Create an alipay.properties file with your app ID, server URL, private key, format, charset, sign type, and the paths to the three certificates.

alipay.appId=你的应用id
alipay.serverUrl=https://openapi.alipay.com/gateway.do
alipay.privateKey=你的应用私钥
alipay.format=json
alipay.charset=UTF-8
alipay.signType=RSA2
alipay.appCertPath=/cert/appCertPublicKey_2021001164652941.crt
alipay.alipayCertPath=/cert/alipayCertPublicKey_RSA2.crt
alipay.alipayRootCertPath=/cert/alipayRootCert.crt

Step 3: Add the Alipay SDK Maven dependency to your pom.xml.

<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.10.97.ALL</version>
</dependency>

Step 4: Define a Spring bean AliPayBean annotated with @Component and @ConfigurationProperties(prefix="alipay") to bind the properties.

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Component
@PropertySource("classpath:/production/alipay.properties")
@ConfigurationProperties(prefix = "alipay")
@Data
public class AliPayBean {
    private String appId;
    private String privateKey;
    private String publicKey;
    private String serverUrl;
    private String domain;
    private String format;
    private String charset;
    private String signType;
    private String appCertPath;
    private String alipayCertPath;
    private String alipayRootCertPath;
}

Step 5: Configure an AliConfig class that creates a AlipayClient using CertAlipayRequest, loads the certificates (either from classpath or via proxy in production), and registers the bean as alipayClient.

import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.FileCopyUtils;

import java.io.InputStream;

@Configuration
public class AliConfig {

    @Value("${custom.http.proxyHost}")
    private String proxyHost;
    @Value("${custom.http.proxyPort}")
    private int proxyPort;
    @Value("${spring.profiles.active}")
    private String activeEnv;

    @Autowired
    private AliPayBean aliPayBean;

    @Bean(name = {"alipayClient"})
    public AlipayClient alipayClientService() throws Exception {
        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        certAlipayRequest.setServerUrl(aliPayBean.getServerUrl());
        certAlipayRequest.setAppId(aliPayBean.getAppId());
        certAlipayRequest.setPrivateKey(aliPayBean.getPrivateKey());
        certAlipayRequest.setFormat(aliPayBean.getFormat());
        certAlipayRequest.setCharset(aliPayBean.getCharset());
        certAlipayRequest.setSignType(aliPayBean.getSignType());
        if ("prod".equals(activeEnv) || "stage".equals(activeEnv) || "test".equals(activeEnv)) {
            certAlipayRequest.setCertContent(getCertContentByPath(aliPayBean.getAppCertPath()));
            certAlipayRequest.setAlipayPublicCertContent(getCertContentByPath(aliPayBean.getAlipayCertPath()));
            certAlipayRequest.setRootCertContent(getCertContentByPath(aliPayBean.getAlipayRootCertPath()));
            certAlipayRequest.setProxyHost(proxyHost);
            certAlipayRequest.setProxyPort(proxyPort);
        } else {
            String serverPath = this.getClass().getResource("/").getPath();
            certAlipayRequest.setCertPath(serverPath + aliPayBean.getAppCertPath());
            certAlipayRequest.setAlipayPublicCertPath(serverPath + aliPayBean.getAlipayCertPath());
            certAlipayRequest.setRootCertPath(serverPath + aliPayBean.getAlipayRootCertPath());
        }
        return new DefaultAlipayClient(certAlipayRequest);
    }

    public String getCertContentByPath(String name) {
        InputStream inputStream = null;
        String content = null;
        try {
            inputStream = this.getClass().getClassLoader().getResourceAsStream(name);
            content = new String(FileCopyUtils.copyToByteArray(inputStream));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return content;
    }
}

Step 6: Implement a utility class AliPayUtils that provides methods for trade queries, app payments, and the new transfer API AlipayFundTransUniTransferRequest. The transfer method builds a BizContentForUniTransfer object, sets the amount, product code, scene, and payee information, and executes the request with certificateExecute.

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class AliPayUtils {
    @Autowired
    @Qualifier("alipayClient")
    private AlipayClient alipayClient;

    public boolean isTradeQuery(AlipayTradeQueryModel model) throws AlipayApiException {
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        request.setBizModel(model);
        AlipayTradeQueryResponse response = alipayClient.certificateExecute(request);
        return response.isSuccess();
    }

    public String startAppPay(AlipayTradeAppPayModel model, String notifyUrl) throws AlipayApiException {
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setNotifyUrl(notifyUrl);
        request.setBizModel(model);
        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
        return response.getBody();
    }

    public AlipayFundTransUniTransferResponse doTransferNew(TransferParams transferParams) throws Exception {
        String title = (StringUtils.isNotBlank(transferParams.getRemark()) ? transferParams.getRemark() : "转账");
        AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
        BizContentForUniTransfer bizContent = new BizContentForUniTransfer();
        bizContent.setOut_biz_no(transferParams.getOutBizNo());
        bizContent.setTrans_amount(MathUtil.changeF2Y(Math.abs(Integer.parseInt(transferParams.getAmount()))));
        bizContent.setProduct_code("TRANS_ACCOUNT_NO_PWD");
        bizContent.setBiz_scene("DIRECT_TRANSFER");
        bizContent.setOrder_title(title);
        Participant participant = new Participant();
        participant.setIdentity(transferParams.getPayeeAccount());
        participant.setIdentity_type(transferParams.getPayeeType());
        participant.setName(StringUtils.isNotBlank(transferParams.getPayeeRealName()) ? transferParams.getPayeeRealName() : StringUtils.EMPTY);
        bizContent.setPayee_info(participant);
        bizContent.setRemark(title);
        request.setBizContent(JSON.toJSONString(bizContent));
        AlipayFundTransUniTransferResponse response = null;
        try {
            response = alipayClient.certificateExecute(request);
        } catch (Exception e) {
            log.info("doTransfer exception,异常信息:{}", e.toString());
            log.info("doTransfer exception,支付宝返回信息:{}", JSONObject.toJSONString(response));
        }
        log.info("doTransfer,AlipayFundTransUniTransferResponse:{}", JSONObject.toJSONString(response));
        return response;
    }
}

Additional data classes ( TransferParams, BizContentForUniTransfer, Participant) model the request parameters and are annotated with Lombok @Data for boilerplate reduction.

@Data
public class TransferParams {
    private Long appId;
    private Long createdBy;
    private String outBizNo;
    private String payeeType;
    private String payeeAccount;
    private String amount;
    private String payerShowName;
    private String payeeRealName;
    private String remark;
    private String orderId;
}
@Data
public class BizContentForUniTransfer {
    private String out_biz_no;
    private BigDecimal trans_amount;
    private String product_code;
    private String biz_scene;
    private String order_title;
    private String original_order_id;
    private String remark;
    private String business_params;
    private Participant payee_info;
}
@Data
public class Participant {
    private String identity;
    private String identity_type;
    private String name;
}

After completing these steps, the application can securely invoke the new Alipay transfer interface, benefiting from certificate verification and the enhanced capabilities of the updated API.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaSDKSpring BootPayment IntegrationAlipay
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.