wlzboy
6 天以前 7de1396e315896dbc72a9d54e44f77434ea90f18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
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();
    }
}