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(); } }