springboot3+vue3支付宝交易案例-结算支付!今天下午整理了一下结算的内容。遇到了很多问题。汇总分享给大家。
第一个问题:支付宝结算后,返回的交易编码,和交易时间,交易状态,都应该使用varchar来存。
第二个问题:它交易支付完成后,会自动返回购物车的页面地址。
package com.example.demo.controller;
import cn.hutool.json.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.example.demo.config.AliPayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.example.demo.bean.Orders;
import com.example.demo.service.IOrdersService;
import com.example.demo.service.impl.OrdersService;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/alipay")
public class AlipayController {
//支付宝沙箱测试网关地址
private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
private static final String FORMAT = "JSON";
private static final String CHARSET = "UTF-8";
private static final String SIGN_TYPE = "RSA2";
@Resource
private IOrdersService ordersService;
@Resource
private AliPayConfig alipayConfig;
/**
* 向支付宝发送支付的接口。
* @param orderNo
* @param httpResponse
* @throws IOException
*/
@GetMapping("/pay")
public void pay(Integer orderNo, HttpServletResponse httpResponse) throws IOException {
//查询订单信息
List ordersList= ordersService.getOneOrdersByOrderNo(orderNo);
Orders order = ordersList.get(0);
if(order == null){
return;
}
//private static final String GATEWAY_URL = "https://openapi.alipaydev.com/gateway.do";
// 1. 创建Client,通用SDK提供的Client,负责调用支付宝的API
AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, alipayConfig.getAppId(),
alipayConfig.getAppPrivateKey(), FORMAT, CHARSET, alipayConfig.getAlipayPublicKey(), SIGN_TYPE);
// 2. 创建 Request并设置Request参数
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); // 发送请求的 Request类
request.setNotifyUrl(alipayConfig.getNotifyUrl());//疑惑之一。
JSONObject bizContent = new JSONObject();
bizContent.set("out_trade_no", orderNo); // 我们自己生成的订单编号
bizContent.set("total_amount", order.getTotal()); // 订单的总金额
bizContent.set("subject", order.getGoodsName()); // 支付的名称
bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY"); // 固定配置
request.setBizContent(bizContent.toString());
request.setReturnUrl("http://127.0.0.1:5173/cart_list");
// 执行请求,拿到响应的结果,返回给浏览器
String form = "";
try {
form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
} catch (AlipayApiException e) {
e.printStackTrace();
}
//官方回传了一个页面,输入账户,密码,完成支付。
httpResponse.setContentType("text/html;charset=" + CHARSET);
httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
httpResponse.getWriter().flush();
httpResponse.getWriter().close();
}
@PostMapping("/notify") // 注意这里必须是POST接口
public void payNotify(HttpServletRequest request) throws Exception {
if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
System.out.println("=========支付宝异步回调========");
Map params = new HashMap<>();
Map requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
params.put(name, request.getParameter(name));
// System.out.println(name + " = " + request.getParameter(name));
}
String tradeNo = params.get("out_trade_no");//订单原始编码
String gmtPayment = params.get("gmt_payment");//支付的时间
String alipayTradeNo = params.get("trade_no");//支付交易的编码
String status = params.get("trade_status");//交易状态
String sign = params.get("sign");
String content = AlipaySignature.getSignCheckContentV1(params);
boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, alipayConfig.getAlipayPublicKey(), "UTF-8"); // 验证签名
// 支付宝验签
if (checkSignature) {
// 验签通过
System.out.println("交易名称: " + params.get("subject"));
System.out.println("交易状态: " + params.get("trade_status"));
System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
System.out.println("商户订单号: " + params.get("out_trade_no"));
System.out.println("交易金额: " + params.get("total_amount"));
System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
System.out.println("买家付款时间: " + params.get("gmt_payment"));
System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
// 更新订单未已支付(更新数据库信息)
//tradeNo, "已支付", gmtPayment, alipayTradeNo
//查询订单信息
Integer orderNo = Integer.valueOf(tradeNo);
List ordersList= ordersService.getOneOrdersByOrderNo(orderNo);
Orders order = ordersList.get(0);
order.setStatus(status);
order.setAlipayNo(alipayTradeNo);
order.setPayTime(gmtPayment);
ordersService.updateOneOrders(order);
}
}
}
}
这里面就是支付宝交易的控制器内容。里面有2个方法。一个是支付的,一个是回调的。
package com.example.demo.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AliPayConfig {
private String appId;
private String appPrivateKey;
private String alipayPublicKey;
private String notifyUrl;
}
这个是一个配置类,读取了我们的配置信息。
alipay.appId=9021000134634591
alipay.appPrivateKey=MIIEugIBADANBgkqhkiG9w0BAQEFAASCBKQwggSgAgEAAoIBAQCvWMRgjeKZdKnT8tT7nh1Yh6RiLhYCablc5a67CojvWRk5NrooIpP39oXkisV7H2nf5J8zfLmS2l2qroDlwAx4Zx3+Woloo6rcLZ42G0QuB8yBZm4doa73/lMurenmucSgCDaS+ap1opEGvlAFZnRi2O0KZy5t9g9WhwzC/D2EWJMSwroclfSTpVxr/on0MLw7l+jTeqcZTul4czXUhnGufWgVjmA7qAd3we7FhAMCqUcWXa3pLCCGIeSaBkqiaoToyql7eqYuwoV2UkT1DeqCN0fW/Zc5h7YpbuGTDfm2SSB/lfQAvHeV5Y+aNIOFJ1G25VKDnAIQgfQgrDYU3Eg1AgMBAAECgf99V/cJDmPtTngYCn41X9Gad1wK0ubo0qquvYEqM12vuwFM5NIt3onnt1H/DTQdz1bftY4YQBBn6bELUbLSiXZgm1XVfOK86kI5ImL2SodyYCDQX2hXxjxNCoBr3eZWCHWF8FkSt2YisRL6vxB0y8hm4KqRxTBranmMYP2+ZJGVCIyimxHAespfG47yPy42fk02DXf9StJpWqOTw5juCfUNDjDbgYLkk6B5gEmH9sj8jeG2OrNOxxjTLRnMgxxsRGV1goRQqAHD7wUAUYu1oFQCAMz3QAQeIv29OvXklRh9AxohridPImQxqzGOm9AnVB0US2GbnXYNBUEdrADn0+ECgYEA4SF+br+uTANdLANvHjP6uzG7UrOef6imUw0Yoepwzbc4pimxkH8p3lQZFpR9i06/7skIu/u7YAOgrcMVFcDQkmprqLDSXeML/YgQzocCqPg4cwYU6EDrMFrjAT7uBRXJFHaRdVNuEpTdtWWQMMdJe/WbNVxQMf2XBe8NM5AO3PkCgYEAx2PCm//PHkeuaEoOi0hcdCmKf67iA3uahyCl3+IzLO7bgEtpldLAlMiNMxNL+HiuxnGMUxmJXb5GkGeSNPjajMGmYY+pOx2h2SiJcMuHtMLjHwBmnEVWbMzWcD5huF//66jMI8NJN8eXZcfNxcjcD/BIEhlP6bi2vnCs1PInQB0CgYAZWR8WMyjZ0CsmcICLYwjhGNlhl23KK+AGS9wxJudqki2jr+AZR+gb61Yjz7ZPAB/mL+Z23AId7mqiBewS1fHl+muCw937yjuoYTCbQGJRShl5Af9KozyX5jPXCRHdqrVIQ41fK3SiTPalnPjeNSIV/fJq0KkK5+WgOmk/HAJAaQKBgBEat7kWKrhYQdfkcnb0UCoO3jix0eWmlsz8uf4Is4cpPl81GOunVqnswmAdSakZATU4zGbci/IkvnzoxZwRtP3aJuG7pzLRCe9NEO1CKHQTO9SO/j5tnEpdEBA06cEdSyD2K/ztZbyJPK2YhEhxQJ+FZ0lWLorIM7UGiW0DEObpAoGAUaWp+93D8VLYKzLlutCrZXmXw7gFfFXkmr5rd0ylFW7OqTtGPbvXwREpByyoKGyXZSIR9gnyYtjw4PQctKrXNvqqPevFEJ1I8EWm+sKsN9E8Sg7j0M9BhRaJ+9B4/OwDv9+G1N6WOjaia88RBx45s8lVb9l6Fjd5wsI2O5p/1Xw=
alipay.alipayPublicKey=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoBuX6xKYpLdexDoGc+jmfGGijjFnsv/0jvPmPydnt+bUgIWF8ghk2v3ddbY2C6toqdk1n367CyIF/swQl2gZFscWg83tvPHOho+fyHJ9ZANzJqQDeEXD2YVfrOGcTJQt0dnX6w5rfZerzsrD685C1OhAIttP5HKff2iplyvx1ZPaHEhghacYjD4ObFREXo6M1+pkKJJBo5mUmPQ6MBwWwkKqtIaQMMUnszO+o7GyVbVd7CttS/VDXwqTNay0pPlWyyBpH9rSl45XClGGHOFgpkN//CVNO7dBtskLOCKDZ++fGIBPKqU5vEkZXoGanlYBOKhrh38gALiR2CaENPdCIwIDAQAB
alipay.notifyUrl=http://8btgff.natappfree.cc/alipay/notify
这个就是配置参数文件内的配置参数信息。
如图,我们都是使用的字符串存储的。否则很容易报错。存不下。
如图,使用沙箱测试账户(用户角色)jiuky可以支付完成了。
这个就是刚刚结算的订单信息。第一个是支付宝回传过来的交易编码。第二个是交易结算时间,第三个是交易结算状态。