package com.ruoyi.payment.infrastructure.channel.alipay;
|
|
import com.alipay.api.AlipayApiException;
|
import com.alipay.api.AlipayClient;
|
import com.alipay.api.DefaultAlipayClient;
|
import com.alipay.api.request.AlipayTradePrecreateRequest;
|
import com.alipay.api.request.AlipayTradeQueryRequest;
|
import com.alipay.api.request.AlipayTradeCloseRequest;
|
import com.alipay.api.response.AlipayTradePrecreateResponse;
|
import com.alipay.api.response.AlipayTradeQueryResponse;
|
import com.alipay.api.response.AlipayTradeCloseResponse;
|
import com.ruoyi.payment.domain.model.GoodsDetail;
|
import com.ruoyi.payment.domain.model.PaymentOrder;
|
import com.ruoyi.payment.infrastructure.config.AlipayConfig;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Component;
|
|
import javax.annotation.PostConstruct;
|
import java.math.BigDecimal;
|
import java.util.ArrayList;
|
import java.util.List;
|
|
/**
|
* 支付宝当面付客户端
|
*
|
* @author ruoyi
|
*/
|
@Slf4j
|
@Component
|
public class AlipayF2FClient {
|
|
@Autowired
|
private AlipayConfig alipayConfig;
|
|
private AlipayClient alipayClient;
|
|
/**
|
* 初始化支付宝客户端
|
*/
|
@PostConstruct
|
public void init() {
|
alipayClient = new DefaultAlipayClient(
|
alipayConfig.getServerUrl(),
|
alipayConfig.getAppId(),
|
alipayConfig.getPrivateKey(),
|
"json",
|
"UTF-8",
|
alipayConfig.getAlipayPublicKey(),
|
alipayConfig.getSignType()
|
);
|
log.info("支付宝客户端初始化成功");
|
}
|
|
/**
|
* 当面付下单 - 生成二维码
|
*/
|
public String precreate(PaymentOrder order) throws AlipayApiException {
|
log.info("调用支付宝当面付下单接口,订单ID: {}", order.getId());
|
|
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
|
request.setNotifyUrl(alipayConfig.getNotifyUrl());
|
|
// 构造业务参数
|
StringBuilder bizContent = new StringBuilder();
|
bizContent.append("{");
|
bizContent.append("\"out_trade_no\":\"").append(order.getId()).append("\","); // 商户订单号
|
bizContent.append("\"total_amount\":\"").append(formatAmount(order.getAmount())).append("\","); // 订单金额,单位:元
|
bizContent.append("\"subject\":\"").append(order.getSubject()).append("\""); // 订单标题
|
|
// 添加商品明细列表
|
if (order.getGoodsDetails() != null && !order.getGoodsDetails().isEmpty()) {
|
bizContent.append(",\"goods_detail\":[");
|
for (int i = 0; i < order.getGoodsDetails().size(); i++) {
|
if (i > 0) {
|
bizContent.append(",");
|
}
|
bizContent.append("{");
|
bizContent.append("\"goods_id\":\"").append(order.getGoodsDetails().get(i).getGoodsId()).append("\",");
|
bizContent.append("\"goods_name\":\"").append(order.getGoodsDetails().get(i).getGoodsName()).append("\",");
|
bizContent.append("\"quantity\":").append(order.getGoodsDetails().get(i).getQuantity()).append(",");
|
bizContent.append("\"price\":\"").append(formatAmount(order.getGoodsDetails().get(i).getPrice())).append("\"");
|
|
// 添加可选的商品类别和描述
|
if (order.getGoodsDetails().get(i).getGoodsCategory() != null && !order.getGoodsDetails().get(i).getGoodsCategory().isEmpty()) {
|
bizContent.append(",\"goods_category\":\"").append(order.getGoodsDetails().get(i).getGoodsCategory()).append("\"");
|
}
|
|
if (order.getGoodsDetails().get(i).getBody() != null && !order.getGoodsDetails().get(i).getBody().isEmpty()) {
|
bizContent.append(",\"body\":\"").append(order.getGoodsDetails().get(i).getBody()).append("\"");
|
}
|
|
bizContent.append("}");
|
}
|
bizContent.append("]");
|
}
|
|
if (order.getDescription() != null && !order.getDescription().isEmpty()) {
|
bizContent.append(",\"body\":\"").append(order.getDescription()).append("\"");
|
}
|
|
// 设置超时时间
|
bizContent.append(",\"timeout_express\":\"30m\"");
|
|
bizContent.append("}");
|
|
request.setBizContent(bizContent.toString());
|
log.info("支付宝当面付请求参数: {}", bizContent.toString());
|
|
// 调用SDK
|
AlipayTradePrecreateResponse response = alipayClient.execute(request);
|
|
if (!response.isSuccess()) {
|
log.error("支付宝当面付下单失败: {}, {}", response.getSubCode(), response.getSubMsg());
|
throw new AlipayApiException("支付宝当面付下单失败: " + response.getSubMsg());
|
}
|
|
String qrCode = response.getQrCode();
|
if (qrCode == null || qrCode.isEmpty()) {
|
throw new AlipayApiException("支付宝未返回二维码");
|
}
|
|
log.info("支付宝当面付下单成功,qrCode: {}", qrCode);
|
return qrCode;
|
}
|
|
/**
|
* 查询订单
|
*/
|
public AlipayTradeQueryResponse queryOrder(String outTradeNo) throws AlipayApiException {
|
log.info("查询支付宝订单,商户订单号: {}", outTradeNo);
|
|
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
|
request.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\"}");
|
|
AlipayTradeQueryResponse response = alipayClient.execute(request);
|
|
if (!response.isSuccess()) {
|
log.error("查询支付宝订单失败: {}, {}", response.getSubCode(), response.getSubMsg());
|
throw new AlipayApiException("查询订单失败: " + response.getSubMsg());
|
}
|
|
log.info("查询支付宝订单成功,交易状态: {}", response.getTradeStatus());
|
return response;
|
}
|
|
/**
|
* 关闭订单
|
*/
|
public void closeOrder(String outTradeNo) throws AlipayApiException {
|
log.info("关闭支付宝订单,商户订单号: {}", outTradeNo);
|
|
AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
|
request.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\"}");
|
|
AlipayTradeCloseResponse response = alipayClient.execute(request);
|
|
if (!response.isSuccess()) {
|
log.error("关闭支付宝订单失败: {}, {}", response.getSubCode(), response.getSubMsg());
|
throw new AlipayApiException("关闭订单失败: " + response.getSubMsg());
|
}
|
|
log.info("关闭支付宝订单成功");
|
}
|
|
/**
|
* 格式化金额:分转元,保留两位小数
|
*/
|
private String formatAmount(Integer amountInCents) {
|
BigDecimal amount = new BigDecimal(amountInCents).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
|
return amount.toString();
|
}
|
}
|