springboot接入支付宝api(网页或单独支付二维码)
更多内容可以参考支付宝开放平台:支付宝开放平台 (alipay.com)
支付宝沙箱:沙箱环境 - 支付宝文档中心 (alipay.com)
一、申请沙箱账号
开发环境可以先用沙箱账号做测试(正式环境跟沙箱环境只有APPID不同),在程序开发完后可以做替换,建议使用老沙箱,新版沙箱很多功能暂未上线
登录支付宝开放平台 -> 控制台(最下面)-> 沙箱 - 申请沙箱账号
二、配置yml参数
在springboot的yml或者properties文件中配置账号参数
lipay:
#APPID
appId:
#沙箱应用-->应用信息-->开发信息-->接口加签方式-->系统默认密钥-->公钥模式-->查看-->应用私钥
appPrivateKey:
#沙箱应用-->应用信息-->开发信息-->接口加签方式-->系统默认密钥-->公钥模式-->查看-->支付宝公钥
alipayPublicKey:
#回调地址
notifyUrl:
#网关地址
serverUrl: https://openapi.alipaydev.com/gateway.do
#数据格式,推荐:json
format: JSON
#编码格式 推荐:utf-8
charset: UTF-8
#签名方式,签名算法,推荐:RSA2
signType: RSA2
在沙箱中的沙箱应用中查看各项参数
支付宝的网关地址是请求发到支付宝服务器的地址,沙箱环境是比正式环境地址多个 dev
沙箱网关地址: 支付宝 - 网上支付 安全快速!
正式环境地址: https://openapi.alipay.com/gateway.do
回调地址是用户支付后支付宝返回的详细内容,可以用订单号查询支付金额校验,必须要可以访问,本地开发的可以用花生壳进行映射,服务器则填写服务器中的地址
三、将配置信息注入bean
注入spring容器用bean获取参数,降低耦合性
@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AlipayConfig {
/**
* APPID
*/
private String appId;
/**
* 应用私钥
*/
private String appPrivateKey;
/**
* 阿里公钥
*/
private String alipayPublicKey;
/**
* 阿里调用我们的地址【内网穿透】
*/
private String notifyUrl;
/**
* 网关地址
*/
private String serverUrl;
/**
* 数据格式
*/
private String format;
/**
* 编码格式
*/
private String charset;
/**
* 签名方式,签名算法
*/
private String signType;
}
四、添加支付依赖
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.34.47.ALL</version>
</dependency>
五、编写支付实体类跟回调实体
//与阿里交互的对象
@Data
public class AliPay {
private String traceNo;//我们的订单号
private Double totalAmount;//总金额
private String subject;//标题
private String alipayTraceNo;//阿里的流水号
private String[] queryOptions;//指定需要返回的参数
}
//支付宝的回调实体类
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class AliReturnPay implements Serializable {
private static final long serialVersionUID = 8683949075381016639L;
// 开发者的app_id
private String app_id;
// 商户订单号
private String out_trade_no;
// 签名
private String sign;
// 交易状态
private String trade_status;
// 支付宝交易号
private String trade_no;
// 交易的金额
private String total_amount;
}
六、编写控制层controller
使用网页支付
@Resource
private AlipayConfig alipayConfig;
/**
* 请求支付宝
*/
@GetMapping("/pay")
public void pay(AliPay aliPay, HttpServletResponse response){
try {
//1.创建client,通过阿里SDK提供的client,负责调用支付宝的API
AlipayClient alipayClient = new DefaultAlipayClient(
alipayConfig.getServerUrl(),
alipayConfig.getAppId(),
alipayConfig.getAppPrivateKey(),
alipayConfig.getFormat(),
alipayConfig.getCharset(),
alipayConfig.getAlipayPublicKey(),
alipayConfig.getSignType()
);
//2.创建request,并设置request参数
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setNotifyUrl(alipayConfig.getNotifyUrl());//设置异步地址
request.setReturnUrl("http://****:9000/alipay/hello");//设置支付成功后的跳转地址
JSONObject jsonObject = new JSONObject();
jsonObject.put("out_trade_no",aliPay.getTraceNo());// 商户订单号
jsonObject.put("total_amount",aliPay.getTotalAmount());// 商品价格
jsonObject.put("subject",aliPay.getSubject());// 商品标题
jsonObject.put("product_code", "FAST_INSTANT_TRADE_PAY");
request.setBizContent(jsonObject.toString());
//执行请求,拿到响应的结果,返回给浏览器
String form = "";
form = alipayClient.pageExecute(request).getBody();
//设置响应结果,将返回的内容写出到浏览器
response.setContentType("text/html;charset=" + alipayConfig.getCharset());
response.getWriter().write(form);//直接将完整的表单html输出到页面
response.getWriter().flush();
response.getWriter().close();
}catch (Exception e){
e.printStackTrace();
}
}
可以设置支付成功的地址进行跳转 setReturnUrl
测试: http://127.0.0.1:9000/alipay/pay?subject=aaa&traceNo=41231241243&totalAmount=99
结果:
各项参数及其含义见支付宝官网: 付款码支付接口 - 支付宝文档中心 (alipay.com)
二维码支付
@PostMapping("/sandboxPay")
public String sandboxPay(AliPay aliPay){
try {
//1.创建client,通过阿里SDK提供的client,负责调用支付宝的API
AlipayClient alipayClient = new DefaultAlipayClient(
alipayConfig.getServerUrl(),
alipayConfig.getAppId(),
alipayConfig.getAppPrivateKey(),
alipayConfig.getFormat(),
alipayConfig.getCharset(),
alipayConfig.getAlipayPublicKey(),
alipayConfig.getSignType()
);
AlipayTradePrecreateRequest alipayRequest = new AlipayTradePrecreateRequest();
alipayRequest.setNotifyUrl(alipayConfig.getNotifyUrl());
JSONObject jsonObject = new JSONObject();
jsonObject.put("out_trade_no",aliPay.getTraceNo());// 商户订单号
jsonObject.put("total_amount",aliPay.getTotalAmount());// 商品价格
jsonObject.put("subject",aliPay.getSubject());// 商品标题
jsonObject.put("store_id","天衡");//组织或公司名
// jsonObject.put("timeout_express","5m");// 订单有效时间
alipayRequest.setBizContent(jsonObject.toString());
AlipayTradePrecreateResponse response = alipayClient.execute(alipayRequest);
System.out.println("创建订单结果:"+response.getBody());
System.out.println("订单编号是"+response.getOutTradeNo());
String qrCode = response.getQrCode();
// AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
return qrCode;
}catch (Exception e){
return null;
}
返回的是支付的地址,可以在在前端用二维码生成工具将链接转成二维码
支付成功的回调
@PostMapping("/call")
public void call(HttpServletRequest request, HttpServletResponse response, AliReturnPay aliReturnPay){
response.setContentType("type=text/html;charset=UTF-8");
System.out.println("当前订单编号:"+aliReturnPay.getOut_trade_no()+"当前订单的状态"+aliReturnPay.getTrade_status());
}
可以判断状态之后进行数据库的订单操作
查询支付宝订单
//查询订单
@PostMapping("/order")
public String selectArder(AliPay aliPay){
try {
//1.创建client,通过阿里SDK提供的client,负责调用支付宝的API
AlipayClient alipayClient = new DefaultAlipayClient(
alipayConfig.getServerUrl(),
alipayConfig.getAppId(),
alipayConfig.getAppPrivateKey(),
alipayConfig.getFormat(),
alipayConfig.getCharset(),
alipayConfig.getAlipayPublicKey(),
alipayConfig.getSignType()
);
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
JSONObject jsonObject = new JSONObject();
jsonObject.put("out_trade_no",aliPay.getTraceNo());// 商户订单号
jsonObject.put("trade_no",aliPay.getTotalAmount());//支付宝订单编号
jsonObject.put("query_options",aliPay.getQueryOptions());//指定需要返回那些信息
request.setBizContent(jsonObject.toString());
AlipayTradeQueryResponse response = alipayClient.execute(request);
if(response.isSuccess()){
System.out.println("调用成功");
System.out.println(response.getBody());
}else {
System.out.println("调用失败");
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
正式环境需要把yml文件中的网关地址改成- serverUrl: https://openapi.alipay.com/gateway.do
并把APPID填写成商家账号的,在应用中设置应用私钥
更多详细设置见官网:付款码支付接口 - 支付宝文档中心 (alipay.com)