Integrating Alipay’s New Transfer Interface (alipay.fund.trans.uni.transfer) with Spring Boot
This guide explains how to replace the deprecated Alipay transfer API with the new alipay.fund.trans.uni.transfer interface by upgrading the SDK, configuring certificates, adding Maven dependencies, and implementing Spring‑Boot beans, configuration classes, and utility methods for secure fund transfers.
Alipay has launched a new transfer interface alipay.fund.trans.uni.transfer that offers higher security and more features, while the old interface alipay.fund.trans.toaccount.transfer is discontinued. To use the new API, the SDK must be upgraded to the latest version (4.10.97 at the time of writing).
The integration steps are as follows:
1. Place the three certificates downloaded from the Alipay Open Platform under the resources directory.
2. Create the Alipay configuration file alipay.properties :
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.crt3. Add the Maven dependency for the Alipay SDK:
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.10.97.ALL</version>
</dependency>4. Inject the configuration into an AliPayBean component:
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;
}5. Create a configuration class to build the AlipayClient with certificate verification and optional proxy settings:
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;
}
}6. Implement a utility class AliPayUtils that provides methods for trade queries, app payments, and the new transfer operation:
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 aliPayRequest = new AlipayTradeAppPayRequest();
model.setProductCode("QUICK_MSECURITY_PAY");
aliPayRequest.setNotifyUrl(notifyUrl);
aliPayRequest.setBizModel(model);
AlipayTradeAppPayResponse aliResponse = alipayClient.sdkExecute(aliPayRequest);
return aliResponse.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 used in the utility (e.g., TransferParams , BizContentForUniTransfer , and Participant ) are also provided in the source and should be added to the project unchanged.
After completing these steps, the application can securely invoke the new Alipay transfer API, benefiting from certificate‑based verification and the enhanced capabilities of the updated interface.
Architect's Guide
Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.