How to Integrate Alipay’s New Transfer API with Spring Boot (v4.10.97)
This guide walks you through upgrading to Alipay’s new transfer interface alipay.fund.trans.uni.transfer, updating the SDK to version 4.10.97, configuring certificates, adding Maven dependencies, creating configuration beans, and implementing utility classes for secure fund transfers in a Spring Boot application.
Alipay has launched a new transfer interface alipay.fund.trans.uni.transfer (higher security and more features) and deprecated the old interface alipay.fund.trans.toaccount.transfer. The new API uses certificate verification, so the SDK must be upgraded to the latest version (4.10.97 at the time of writing).
1. Place the three certificates downloaded from the Alipay Open Platform under resources
2. Write the Alipay configuration file alipay.properties
alipay.appId=your_app_id
alipay.serverUrl=https://openapi.alipay.com/gateway.do
alipay.privateKey=your_private_key
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
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.10.97.ALL</version>
</dependency>4. Create the 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. Write the configuration class to create an 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();
// Set gateway, app id, private key, format, charset, sign type
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)) {
// Production or pre‑release environment – use certificate content
certAlipayRequest.setCertContent(getCertContentByPath(aliPayBean.getAppCertPath()));
certAlipayRequest.setAlipayPublicCertContent(getCertContentByPath(aliPayBean.getAlipayCertPath()));
certAlipayRequest.setRootCertContent(getCertContentByPath(aliPayBean.getAlipayRootCertPath()));
certAlipayRequest.setProxyHost(proxyHost);
certAlipayRequest.setProxyPort(proxyPort);
} else {
// Local development – use absolute paths
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. Write the payment utility class
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;
/** Transaction query */
public boolean isTradeQuery(AlipayTradeQueryModel model) throws AlipayApiException {
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
request.setBizModel(model);
AlipayTradeQueryResponse response = alipayClient.certificateExecute(request);
return response.isSuccess();
}
/** App payment */
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();
}
/** Transfer using the new API */
public AlipayFundTransUniTransferResponse doTransferNew(TransferParams transferParams) throws Exception {
String title = (transferParams.getRemark() != null && !transferParams.getRemark().isBlank())
? 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(transferParams.getPayeeRealName() != null && !transferParams.getPayeeRealName().isBlank()
? transferParams.getPayeeRealName() : "");
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, error: {}", e.toString());
log.info("Alipay response: {}", JSONObject.toJSONString(response));
}
log.info("doTransfer response: {}", JSONObject.toJSONString(response));
return response;
}
}Tips – classes used for the transfer operation:
@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;
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
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.
