提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 一、开发前准备?
- 二、使用步骤
- 1、引入库
- 2、配置在 application.yml 里面进行配置:
- 3、alipay的java配置:AplipayConfig.java
- 4、支付接口
- 4、回调接口
一、开发前准备?
easy支付官方文档:https://opendocs.alipay.com/open/009ys9
通用版文档:https://opendocs.alipay.com/open/02np94
支付宝沙箱的配置:
注册支付宝开发者账户,进入开发者控制台
沙箱快捷入口:
https://open.alipay.com/develop/sandbox/app
沙箱的界面:
二、使用步骤
1、引入库
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-easysdk</artifactId>
<version>2.2.2</version>
</dependency>
2、配置在 application.yml 里面进行配置:
#阿里沙箱支付配置
alipay:
#签名算法
signType:
#应用ID
appId:
#应用私钥
appPrivateKey:
#支付宝公钥
publicKey:
#回调地址
notifyUrl:
3、alipay的java配置:AplipayConfig.java
/**
* @author :Mr.ZJW
* @date :Created 2023/9/20 17:40
* @description:alipay沙箱环境配置
*/
@Slf4j
@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AlipayConfig {
/**
* appId
*/
private String appId;
/**
* 私钥
*/
private String appPrivateKey;
/**
* 公钥
*/
private String publicKey;
/**
* 回调地址
*/
private String notifyUrl;
/**
* 支付宝配置初始化,公钥模式
*/
@PostConstruct
public void init() {
Config config = new Config();
//#基础配置
config.protocol = "https"; //协议
config.gatewayHost = "openapi.alipaydev.com"; //支付宝网关
config.signType = "RSA2"; //签名方式
//#业务配置
config.appId = this.appId; //应用id
config.merchantPrivateKey = this.appPrivateKey; 应用私钥
config.alipayPublicKey = this.publicKey; //支付宝公钥
config.notifyUrl = this.notifyUrl; //回调地址
Factory.setOptions(config);
log.info("支付宝配置初始化完成");
}
}
4、支付接口
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.google.common.collect.Maps;
import com.jowell.common.exception.base.BaseException;
import com.jowell.common.response.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* @author :Mr.ZJW
* @date :Created 2023/9/20 17:53
* @description:支付controller
*/
@Slf4j
@RequestMapping("/alipay")
@Controller
@ResponseBody
public class TestAlipayController {
/**
* 支付接口
*
* @param subject 名称
* @param outTradeNo 订单号
* @param totalAmount 金额
* @return /
*/
@GetMapping("/pay")
public String pay(String subject, String outTradeNo, String totalAmount) {
AlipayTradePagePayResponse response;
try {
response = Factory.Payment.Page().pay(subject, outTradeNo, totalAmount, "");
} catch (Exception e) {
log.error("支付宝付款调用失败,原因:" + e.getMessage());
throw new BaseException("网络异常,请刷新后重试");
}
return response.getBody();
}
接口测试:
访问URL进行测试,测试的url格式:http://localhost:10000/alipay/pay?subject=支付测试&outTradeNo=D239211000000&totalAmount=1
效果:
进行用买家账号密码登录:
输入支付密码进行支付:
支付成功:
4、回调接口
回调接口要有一个外网域名,这里可以使用花生壳以及我分享过的一遍文章:
文章链接:https://blog.csdn.net/javaeEEse/article/details/117983797?spm=1001.2014.3001.5502
把这个域名复制到配置文件里的回调地址上。
回调完整代码:
/**
* 支付宝回调
*/
@PostMapping("/notify")
public Result<String> notify(HttpServletRequest request) {
log.info("支付宝回调成功");
//校验是否成功
if ("TRADE_SUCCESS".equals(request.getParameter("trade_status"))) {
//#解析回调数据
Map<String, String> params = Maps.newHashMap();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
params.put(name, request.getParameter(name));
}
//订单号
String tradeNo = params.get("out_trade_no");
//支付金额
String gmtPayment = params.get("gmt_payment");
//支付宝交易凭证号
String alipayTradeNo = params.get("trade_no");
//#支付宝验签,防止不法分子伪造请求
try {
Boolean flag = Factory.Payment.Common().verifyNotify(params);
if (Boolean.TRUE.equals(flag)) {
log.info("交易名称: " + params.get("subject"));
log.info("交易状态: " + params.get("trade_status"));
log.info("支付宝交易凭证号: " + params.get("trade_no"));
log.info("商户订单号: " + params.get("out_trade_no"));
log.info("交易金额: " + params.get("total_amount"));
log.info("买家在支付宝唯一id: " + params.get("buyer_id"));
log.info("买家付款时间: " + params.get("gmt_payment"));
log.info("买家付款金额: " + params.get("buyer_pay_amount"));
} else {
log.error("异步通知验签失败");
return Result.error("fail");
}
} catch (Exception e) {
log.error("异步发生异常{}", e.getMessage());
return Result.error("fail");
}
//#进行一些业务逻辑,如更新订单等操作
}
return Result.success();
}