Java SpringBoot
支付宝去年推出了新的转账接口alipay.fund.trans.uni.transfer(升级后安全性更高,功能更加强大) ,老转账接口alipay.fund.trans.toaccount.transfer将不再维护,新老接口的一个区别就是新接口采用的证书验签方式。使用新接口要将sdk版本升级到最新版本,博主升级时最新版本是4.10.97。接下来看集成步骤:

1、将支付宝开放平台里下载的3个证书放在resources下面

Spring Boot 接入支付宝支付的 SDK 方法 - 图1

2、写支付宝支付的配置文件

alipay.properties:

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

3、引入pom依赖

  1. <dependency>
  2. <groupId>com.alipay.sdk</groupId>
  3. <artifactId>alipay-sdk-java</artifactId>
  4. <version>4.10.97.ALL</version>
  5. </dependency>

4、将配置信息注入AliPayBean

  1. import lombok.Data;
  2. import org.springframework.boot.context.properties.ConfigurationProperties;
  3. import org.springframework.context.annotation.PropertySource;
  4. import org.springframework.stereotype.Component;
  5. @Component
  6. @PropertySource("classpath:/production/alipay.properties")
  7. @ConfigurationProperties(prefix = "alipay")
  8. @Data
  9. public class AliPayBean {
  10. private String appId;
  11. private String privateKey;
  12. private String publicKey;
  13. private String serverUrl;
  14. private String domain;
  15. private String format;
  16. private String charset;
  17. private String signType;
  18. private String appCertPath;
  19. private String alipayCertPath;
  20. private String alipayRootCertPath;
  21. }

5、写配置类

  1. import com.alipay.api.AlipayClient;
  2. import com.alipay.api.CertAlipayRequest;
  3. import com.alipay.api.DefaultAlipayClient;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.beans.factory.annotation.Value;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. import org.springframework.util.FileCopyUtils;
  9. import java.io.InputStream;
  10. @Configuration
  11. public class AliConfig {
  12. @Value("${custom.http.proxyHost}")
  13. private String proxyHost;
  14. @Value("${custom.http.proxyPort}")
  15. private int proxyPort;
  16. @Value("${spring.profiles.active}")
  17. private String activeEnv;
  18. @Autowired
  19. private AliPayBean aliPayBean;
  20. @Bean(name = {"alipayClient"})
  21. public AlipayClient alipayClientService() throws Exception{
  22. CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
  23. //设置网关地址
  24. certAlipayRequest.setServerUrl(aliPayBean.getServerUrl());
  25. //设置应用Id
  26. certAlipayRequest.setAppId(aliPayBean.getAppId());
  27. //设置应用私钥
  28. certAlipayRequest.setPrivateKey(aliPayBean.getPrivateKey());
  29. //设置请求格式,固定值json
  30. certAlipayRequest.setFormat(aliPayBean.getFormat());
  31. //设置字符集
  32. certAlipayRequest.setCharset(aliPayBean.getCharset());
  33. //设置签名类型
  34. certAlipayRequest.setSignType(aliPayBean.getSignType());
  35. //如果是生产环境或者预演环境,则使用代理模式
  36. if ("prod".equals(activeEnv) || "stage".equals(activeEnv) || "test".equals(activeEnv)) {
  37. //设置应用公钥证书路径
  38. certAlipayRequest.setCertContent(getCertContentByPath(aliPayBean.getAppCertPath()));
  39. //设置支付宝公钥证书路径
  40. certAlipayRequest.setAlipayPublicCertContent(getCertContentByPath(aliPayBean.getAlipayCertPath()));
  41. //设置支付宝根证书路径
  42. certAlipayRequest.setRootCertContent(getCertContentByPath(aliPayBean.getAlipayRootCertPath()));
  43. certAlipayRequest.setProxyHost(proxyHost);
  44. certAlipayRequest.setProxyPort(proxyPort);
  45. }else {
  46. //local
  47. String serverPath = this.getClass().getResource("/").getPath();
  48. //设置应用公钥证书路径
  49. certAlipayRequest.setCertPath(serverPath+aliPayBean.getAppCertPath());
  50. //设置支付宝公钥证书路径
  51. certAlipayRequest.setAlipayPublicCertPath(serverPath+aliPayBean.getAlipayCertPath());
  52. //设置支付宝根证书路径
  53. certAlipayRequest.setRootCertPath(serverPath+aliPayBean.getAlipayRootCertPath());
  54. }
  55. return new DefaultAlipayClient(certAlipayRequest);
  56. }
  57. public String getCertContentByPath(String name){
  58. InputStream inputStream = null;
  59. String content = null;
  60. try{
  61. inputStream = this.getClass().getClassLoader().getResourceAsStream(name);
  62. content = new String(FileCopyUtils.copyToByteArray(inputStream));
  63. }catch (Exception e){
  64. e.printStackTrace();
  65. }
  66. return content;
  67. }
  68. }

6、写支付工具类

  1. import com.alipay.api.AlipayApiException;
  2. import com.alipay.api.AlipayClient;
  3. import com.alipay.api.domain.AlipayTradeAppPayModel;
  4. import com.alipay.api.domain.AlipayTradeQueryModel;
  5. import com.alipay.api.request.AlipayTradeAppPayRequest;
  6. import com.alipay.api.request.AlipayTradeQueryRequest;
  7. import com.alipay.api.response.AlipayTradeAppPayResponse;
  8. import com.alipay.api.response.AlipayTradeQueryResponse;
  9. import lombok.extern.slf4j.Slf4j;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.beans.factory.annotation.Qualifier;
  12. import org.springframework.stereotype.Service;
  13. /**
  14. * @description:支付宝工具类
  15. * @Date:2020-08-26
  16. */
  17. @Slf4j
  18. @Service
  19. public class AliPayUtils {
  20. @Autowired
  21. @Qualifier("alipayClient")
  22. private AlipayClient alipayClient;
  23. /**
  24. * 交易查询接口
  25. * @param request
  26. * @return
  27. * @throws Exception
  28. */
  29. public boolean isTradeQuery(AlipayTradeQueryModel model) throws AlipayApiException {
  30. AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
  31. request.setBizModel(model);
  32. AlipayTradeQueryResponse alipayTradeQueryResponse = alipayClient.certificateExecute(request);
  33. if(alipayTradeQueryResponse.isSuccess()){
  34. return true;
  35. } else {
  36. return false;
  37. }
  38. }
  39. /**
  40. * app支付
  41. * @param model
  42. * @param notifyUrl
  43. * @return
  44. * @throws AlipayApiException
  45. */
  46. public String startAppPay(AlipayTradeAppPayModel model, String notifyUrl) throws AlipayApiException {
  47. AlipayTradeAppPayRequest aliPayRequest = new AlipayTradeAppPayRequest();
  48. model.setProductCode("QUICK_MSECURITY_PAY");
  49. aliPayRequest.setNotifyUrl(notifyUrl);
  50. aliPayRequest.setBizModel(model);
  51. // 这里和普通的接口调用不同,使用的是sdkExecute
  52. AlipayTradeAppPayResponse aliResponse = alipayClient.sdkExecute(aliPayRequest);
  53. return aliResponse.getBody();
  54. }
  55. /**
  56. * 转账接口
  57. *
  58. * @param transferParams
  59. * @return AlipayFundTransToaccountTransferResponse
  60. */
  61. public AlipayFundTransUniTransferResponse doTransferNew(TransferParams transferParams) throws Exception {
  62. String title = (StringUtils.isNotBlank(transferParams.getRemark()) ? transferParams
  63. .getRemark() : "转账");
  64. //转账请求入参
  65. AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
  66. //转账参数
  67. BizContentForUniTransfer bizContent = new BizContentForUniTransfer();
  68. bizContent.setOut_biz_no(transferParams.getOutBizNo());
  69. bizContent.setTrans_amount(MathUtil.changeF2Y(Math.abs(Integer.parseInt(transferParams.getAmount()))));
  70. bizContent.setProduct_code("TRANS_ACCOUNT_NO_PWD");
  71. bizContent.setBiz_scene("DIRECT_TRANSFER");
  72. bizContent.setOrder_title(title);
  73. Participant participant = new Participant();
  74. participant.setIdentity(transferParams.getPayeeAccount());
  75. participant.setIdentity_type(transferParams.getPayeeType());
  76. participant.setName((StringUtils.isNotBlank(transferParams.getPayeeRealName()) ? transferParams
  77. .getPayeeRealName() : StringUtils.EMPTY));
  78. bizContent.setPayee_info(participant);
  79. bizContent.setRemark(title);
  80. request.setBizContent(JSON.toJSONString(bizContent));
  81. //转账请求返回
  82. AlipayFundTransUniTransferResponse response = null;
  83. try {
  84. response = alipayClient.certificateExecute(request);
  85. } catch (Exception e) {
  86. log.info("doTransfer exception,异常信息:{}", e.toString());
  87. log.info("doTransfer exception,支付宝返回信息:{}", JSONObject.toJSONString(response));
  88. }
  89. log.info("doTransfer,AlipayFundTransUniTransferResponse:{}", JSONObject.toJSONString(response));
  90. return response;
  91. }
  92. }

Tips:转账用到的类

  1. @Data
  2. public class TransferParams {
  3. /**
  4. * 应用编号
  5. */
  6. private Long appId;
  7. /**
  8. * 创建人id
  9. */
  10. private Long createdBy;
  11. /**
  12. * 转账业务订单号
  13. */
  14. private String outBizNo;
  15. /**
  16. * 收款方识别方式
  17. */
  18. private String payeeType;
  19. /**
  20. * 收款方账号,可以是支付宝userId或者支付宝loginId
  21. */
  22. private String payeeAccount;
  23. /**
  24. * 转账金额,单位分
  25. */
  26. private String amount;
  27. /**
  28. * 付款方名称
  29. */
  30. private String payerShowName;
  31. /**
  32. * 收款方名称
  33. */
  34. private String payeeRealName;
  35. /**
  36. * 备注
  37. */
  38. private String remark;
  39. /**
  40. * 支付宝转账流水号
  41. */
  42. private String orderId;
  43. }
  44. import lombok.Data;
  45. import java.math.BigDecimal;
  46. /**
  47. * 支付宝转账参数
  48. */
  49. @Data
  50. public class BizContentForUniTransfer {
  51. /**
  52. * 业务订单号
  53. */
  54. private String out_biz_no;
  55. /**
  56. * 订单总金额,单位为元,精确到小数点后两位,
  57. */
  58. private BigDecimal trans_amount;
  59. /**
  60. * 业务产品码,
  61. * 单笔无密转账到支付宝账户固定为:TRANS_ACCOUNT_NO_PWD;
  62. * 单笔无密转账到银行卡固定为:TRANS_BANKCARD_NO_PWD;
  63. * 收发现金红包固定为:STD_RED_PACKET;
  64. */
  65. private String product_code;
  66. /**
  67. * 描述特定的业务场景,可传的参数如下:
  68. * DIRECT_TRANSFER:单笔无密转账到支付宝/银行卡, B2C现金红包;
  69. * PERSONAL_COLLECTION:C2C现金红包-领红包
  70. */
  71. private String biz_scene;
  72. /**
  73. * 转账业务的标题,用于在支付宝用户的账单里显示
  74. */
  75. private String order_title;
  76. /**
  77. * 原支付宝业务单号。C2C现金红包-红包领取时,传红包支付时返回的支付宝单号;
  78. * B2C现金红包、单笔无密转账到支付宝/银行卡不需要该参数。
  79. */
  80. private String original_order_id;
  81. /**
  82. * 业务备注
  83. */
  84. private String remark;
  85. /**
  86. * 转账业务请求的扩展参数,支持传入的扩展参数如下:
  87. * 1、sub_biz_scene 子业务场景,红包业务必传,取值REDPACKET,C2C现金红包、B2C现金红包均需传入;
  88. * 2、withdraw_timeliness为转账到银行卡的预期到账时间,可选(不传入则默认为T1),
  89. * 取值T0表示预期T+0到账,取值T1表示预期T+1到账,因到账时效受银行机构处理影响,支付宝无法保证一定是T0或者T1到账;
  90. */
  91. private String business_params;
  92. /**
  93. * 支付收款对象
  94. */
  95. private Participant payee_info;
  96. }
  97. @Data
  98. public class Participant {
  99. /**
  100. * 参与方的唯一标识
  101. */
  102. private String identity;
  103. /**
  104. * 参与方的标识类型,目前支持如下类型:
  105. * 1、ALIPAY_USER_ID 支付宝的会员ID
  106. * 2、ALIPAY_LOGON_ID:支付宝登录号,支持邮箱和手机号格式
  107. */
  108. private String identity_type;
  109. /**
  110. * 参与方真实姓名,如果非空,将校验收款支付宝账号姓名一致性。
  111. * 当identity_type=ALIPAY_LOGON_ID时,本字段必填。
  112. */
  113. private String name;
  114. }