Spring Boot 接入支付宝,实战来了!
上一篇:深夜看了张一鸣的微博,让我越想越后怕
支付宝推出了新的转账接口alipay.fund.trans.uni.transfer
(升级后安全性更高,功能更加强大) ,老转账接口alipay.fund.trans.toaccount.transfer
将不再维护,新老接口的一个区别就是新接口采用的证书验签方式。
使用新接口要将sdk版本升级到最新版本,博主升级时最新版本是4.10.97。
接下来看集成步骤。
1.将支付宝开放平台里下载的3个证书放在resources下面
2.写支付宝支付的配置文件
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.crt
3.引入pom依赖
<dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>4.10.97.ALL</version>
</dependency>
4.将配置信息注入AliPayBean
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.写配置类
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;@Autowiredprivate AliPayBean aliPayBean;@Bean(name = {"alipayClient"})public AlipayClient alipayClientService() throws Exception{CertAlipayRequest certAlipayRequest = new CertAlipayRequest();//设置网关地址certAlipayRequest.setServerUrl(aliPayBean.getServerUrl());//设置应用IdcertAlipayRequest.setAppId(aliPayBean.getAppId());//设置应用私钥certAlipayRequest.setPrivateKey(aliPayBean.getPrivateKey());//设置请求格式,固定值jsoncertAlipayRequest.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 {//localString 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.写支付工具类
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;
/*** @description:支付宝工具类* @Date:2020-08-26*/
@Slf4j
@Service
public class AliPayUtils {@Autowired@Qualifier("alipayClient")private AlipayClient alipayClient;/*** 交易查询接口* @param request* @return* @throws Exception*/public boolean isTradeQuery(AlipayTradeQueryModel model) throws AlipayApiException {AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();request.setBizModel(model);AlipayTradeQueryResponse alipayTradeQueryResponse = alipayClient.certificateExecute(request);if(alipayTradeQueryResponse.isSuccess()){return true;} else {return false;}}/*** app支付* @param model* @param notifyUrl* @return* @throws AlipayApiException*/public String startAppPay(AlipayTradeAppPayModel model, String notifyUrl) throws AlipayApiException {AlipayTradeAppPayRequest aliPayRequest = new AlipayTradeAppPayRequest();model.setProductCode("QUICK_MSECURITY_PAY");aliPayRequest.setNotifyUrl(notifyUrl);aliPayRequest.setBizModel(model);// 这里和普通的接口调用不同,使用的是sdkExecuteAlipayTradeAppPayResponse aliResponse = alipayClient.sdkExecute(aliPayRequest);return aliResponse.getBody();}/*** 转账接口** @param transferParams* @return AlipayFundTransToaccountTransferResponse*/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;}
}
Spring Boot 最新教程推荐看这个:
https://github.com/javastacks/spring-boot-best-practice
Tips:转账用到的类
@Data
public class TransferParams {/*** 应用编号*/private Long appId;/*** 创建人id*/private Long createdBy;/*** 转账业务订单号*/private String outBizNo;/*** 收款方识别方式*/private String payeeType;/*** 收款方账号,可以是支付宝userId或者支付宝loginId*/private String payeeAccount;/*** 转账金额,单位分*/private String amount;/*** 付款方名称*/private String payerShowName;/*** 收款方名称*/private String payeeRealName;/*** 备注*/private String remark;/*** 支付宝转账流水号*/private String orderId;
}
import lombok.Data;import java.math.BigDecimal;/*** 支付宝转账参数*/
@Data
public class BizContentForUniTransfer {/*** 业务订单号*/private String out_biz_no;/*** 订单总金额,单位为元,精确到小数点后两位,*/private BigDecimal trans_amount;/*** 业务产品码,* 单笔无密转账到支付宝账户固定为:TRANS_ACCOUNT_NO_PWD;* 单笔无密转账到银行卡固定为:TRANS_BANKCARD_NO_PWD;* 收发现金红包固定为:STD_RED_PACKET;*/private String product_code;/*** 描述特定的业务场景,可传的参数如下:* DIRECT_TRANSFER:单笔无密转账到支付宝/银行卡, B2C现金红包;* PERSONAL_COLLECTION:C2C现金红包-领红包*/private String biz_scene;/*** 转账业务的标题,用于在支付宝用户的账单里显示*/private String order_title;/*** 原支付宝业务单号。C2C现金红包-红包领取时,传红包支付时返回的支付宝单号;* B2C现金红包、单笔无密转账到支付宝/银行卡不需要该参数。*/private String original_order_id;/*** 业务备注*/private String remark;/*** 转账业务请求的扩展参数,支持传入的扩展参数如下:* 1、sub_biz_scene 子业务场景,红包业务必传,取值REDPACKET,C2C现金红包、B2C现金红包均需传入;* 2、withdraw_timeliness为转账到银行卡的预期到账时间,可选(不传入则默认为T1),* 取值T0表示预期T+0到账,取值T1表示预期T+1到账,因到账时效受银行机构处理影响,支付宝无法保证一定是T0或者T1到账;*/private String business_params;/*** 支付收款对象*/private Participant payee_info;
}
@Data
public class Participant {/*** 参与方的唯一标识*/private String identity;/*** 参与方的标识类型,目前支持如下类型:* 1、ALIPAY_USER_ID 支付宝的会员ID* 2、ALIPAY_LOGON_ID:支付宝登录号,支持邮箱和手机号格式*/private String identity_type;/*** 参与方真实姓名,如果非空,将校验收款支付宝账号姓名一致性。* 当identity_type=ALIPAY_LOGON_ID时,本字段必填。*/private String name;
}
原文链接:https://blog.csdn.net/qq_33556185/article/details/110445827
感谢您的阅读,也欢迎您发表关于这篇文章的任何建议,关注我,技术不迷茫!小编到你上高速。
· END ·
最后,关注公众号互联网架构师,在后台回复:2T,可以获取我整理的 Java 系列面试题和答案,非常齐全。
正文结束
推荐阅读 ↓↓↓
1.不认命,从10年流水线工人,到谷歌上班的程序媛,一位湖南妹子的励志故事
2.如何才能成为优秀的架构师?
3.从零开始搭建创业公司后台技术栈
4.程序员一般可以从什么平台接私活?
5.37岁程序员被裁,120天没找到工作,无奈去小公司,结果懵了...
6.IntelliJ IDEA 2019.3 首个最新访问版本发布,新特性抢先看
7.漫画:程序员相亲图鉴,笑屎我了~
8.15张图看懂瞎忙和高效的区别!
一个人学习、工作很迷茫?
点击「阅读原文」加入我们的小圈子!
Spring Boot 接入支付宝,实战来了!相关推荐
- Spring Boot 接入支付宝完整流程实战,网友:看完后秒懂,原来是我想复杂了!...
点击上方蓝色字体,选择"标星公众号" 优质文章,第一时间送达 作者:李秀才 blog.csdn.net/qq_33556185/article/details/110445827 ...
- Spring Boot集成支付宝电脑网站支付功能
Spring Boot集成支付宝电脑网站支付功能 接入准备 登录 创建应用 添加能力 生成私钥与公钥 开发设置 沙箱环境 示例Demo的使用与学习 下载Demo 启动项目 参数配置 执行测试 Spri ...
- Spring Boot 揭秘与实战(二) 数据缓存篇 - EhCache
文章目录 1. EhCache 集成 2. 源代码 本文,讲解 Spring Boot 如何集成 EhCache,实现缓存. 在阅读「Spring Boot 揭秘与实战(二) 数据缓存篇 - 快速入门 ...
- Java Spring Boot 2.0 实战之制作Docker镜像并推送到Docker Hub和阿里云仓库
内容摘要:大规模集群快速部署Java应用,需要制作Docker镜像,本次课程详细介绍如何制作Java程序的Docker镜像文件,深入解析DockerFile核心参数,以及实践演练把我们制作的Docke ...
- Spring Boot Redis Cluster 实战干货
转载自 Spring Boot Redis Cluster 实战干货 添加配置信息 spring.redis:database: 0 # Redis数据库索引(默认为0)#host: 192.168 ...
- 19年8月 字母哥 第三章 spring boot 配置原理实战 用热点公司网不行
第三章 spring boot 配置原理实战 3.1.结合配置加载讲解bean自动装配原理 3.2.详解YAML语法及占位符语法 3.3.获取自定义配置的两种实现方法 3.4.配置文件注入值数据校验 ...
- Spring Boot 高效入门实战
凭借开箱即用,远离繁琐的配置等特性,Spring Boot 已经成为 Java 开发者人人必学必会的开源项目.那么开发者该如何快速上手Spring Boot 呢? 进入Spring Boot世界 Ja ...
- Spring Boot 揭秘与实战(二) 数据缓存篇 - Guava Cache
本文,讲解 Spring Boot 如何集成 Guava Cache,实现缓存. 博客地址:blog.720ui.com/ 在阅读「Spring Boot 揭秘与实战(二) 数据缓存篇 - 快速入门」 ...
- Spring Boot集成支付宝(最新版SDK)—— 手机支付
前言 前些日子写了一篇关于H5网页集成支付宝的文章: Spring Boot集成支付宝(最新版SDK)-- H5/网页支付 当时写了好久,往那一坐就是俩小时,写完直接就发布了,发布之后才感觉少点啥-- ...
- Spring Boot应用监控实战
概述 之前讲过Docker容器的可视化监控,即监控容器的运行情况,包括 CPU使用率.内存占用.网络状况以及磁盘空间等等一系列信息.同样利用SpringBoot作为微服务单元的实例化技术选型时,我们不 ...
最新文章
- R语言协方差分析(analysis of covariance)实战:协方差分析ANCOVA(analysis of covariance)(检查模型假设)、拟合协方差分析ANCOVA模型、事后分析
- jQuery最佳实践
- 移动互联网的特性 互联网+
- 马斯克抱怨 GPT-3 不够 Open,开源语言模型库来了你要不要学?
- 学python需要什么基础-自学Python需要怎样的基础和准备
- 论文笔记_S2D.39_2015-ICCV-条件随机场作为递归神经网络(CRF-RNN)
- Raki的读paper小记:SpanBERT: Improving Pre-training by Representing and Predicting Spans
- 幅频特性、相频特性的概念解释
- HTML链接和锚点学习---第四天
- 芯片设计进阶之路——Reset深入理解
- kodexplorer可道云插件之控制台
- [1106]python bezier(贝塞尔)曲线
- NodeJS与模块系统
- 时尚主题快闪视频相册视频案例制作教程(可转载)
- APM飞控使用动捕等外部定位
- rabbitmq的安装与命令行管理工具rabbitmqadmin的使用
- 佟年计算机科学,亲爱的热爱的:吴白初见佟年眼神有深意,原来他们早就遇见过...
- 战棋游戏中的简单策略方法:基于群表示论的思想
- 字符串排序-C语言实例
- Golang实现微信公众号后台