shikeying
2024-01-11 3b67e947e36133e2a40eb2737b15ea375e157ea0
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
package com.walker.pay;
 
import com.walker.infrastructure.ApplicationRuntimeException;
import com.walker.infrastructure.arguments.Variable;
import com.walker.infrastructure.utils.StringUtils;
import com.walker.pay.callback.OrderCallBack;
import com.walker.pay.exception.NotifyException;
import com.walker.pay.exception.OrderException;
import com.walker.pay.response.OrderStatusResponsePay;
import com.walker.pay.support.DefaultOrder;
import com.walker.pay.util.PayDefinitionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.util.Map;
 
public abstract class AbstractPayEngineProvider implements PayEngineProvider{
 
    protected final transient Logger logger = LoggerFactory.getLogger(this.getClass());
 
    public Map<String, Variable> getConfiguration() {
        return configuration;
    }
 
    private Map<String, Variable> configuration = null;
 
    private ServiceProvider serviceProvider;
    private String version;
    private PayChannel payChannel;
 
    private Convertor<NotifyValue<?>> orderNotifyConvertor = null;
 
    /**
     * 设置订单通知转换器对象。
     * @param orderNotifyConvertor
     * @date 2023-01-16
     */
    public void setOrderNotifyConvertor(Convertor<NotifyValue<?>> orderNotifyConvertor) {
        this.orderNotifyConvertor = orderNotifyConvertor;
    }
 
    public void setConfiguration(Map<String, Variable> configuration){
        if(configuration == null || configuration.size() == 0){
            logger.warn("支付引擎配置参数为空,请确认是否不需要参数。provider=" + this.getServiceProvider().getName() + ", version=" + this.getVersion());
        }
        this.configuration = configuration;
    }
 
    @Override
    public ServiceProvider getServiceProvider() {
        return this.serviceProvider;
    }
 
    @Override
    public String getVersion() {
        return this.version;
    }
 
    @Override
    public PayChannel getPayChannel() {
        return this.payChannel;
    }
 
    @Override
    public String getPayDefinitionId(){
        return PayDefinitionUtils.getPayDefinitionId(this.serviceProvider, this.version);
    }
 
    public void setPayChannel(PayChannel payChannel){
        this.payChannel = payChannel;
    }
 
    public void setVersion(String version){
        this.version = version;
    }
 
    public void setServiceProvider(ServiceProvider serviceProvider){
        this.serviceProvider = serviceProvider;
    }
 
    @Override
    public String getProviderPayType(PayType payType) {
        String thirdPayType = this.acquireProviderPayType(this.serviceProvider, payType, this.payChannel);
        if(StringUtils.isEmpty(thirdPayType)){
            logger.warn("用户实现支付类型获取为空: acquireProviderPayType = null, payType = " + payType);
        }
        return thirdPayType;
    }
 
    /**
     * 根据支付配置信息,获取第三方支付系统的"支付类型"字符串。
     * @param serviceProvider
     * @param payType
     * @param payChannel
     * @return
     */
    protected abstract String acquireProviderPayType(ServiceProvider serviceProvider, PayType payType, PayChannel payChannel);
 
    /**
     * 获取(预)订单生成器对象,该对象执行具体的第三方订单调用并返回结果。
     * @param providerPayType 第三方支付的"支付类型",如:微信的native、h5等
     * @param platformOrder 平台订单对象
     * @param configuration 第三方对接配置参数
     * @return
     * @date 2023-01-16
     */
    @Deprecated
    protected abstract OrderGenerator acquireOrderGenerator(String providerPayType, Order platformOrder, Map<String, Variable> configuration);
 
//    /**
//     * 获取(预)订单生成器对象,该对象执行具体的第三方订单调用并返回结果。
//     * @param payContext 支付操作上下文对象
//     * @param platformOrder 平台订单对象
//     * @return
//     * @date 2023-02-17
//     */
//    protected abstract OrderGenerator acquireOrderGenerator(PayContext payContext, Order platformOrder);
 
    /**
     * 成功后,保存订单信息到平台。
     * @param platformOrder
     * @param responsePay
     * @date 2023-01-16
     */
    protected abstract void savePrepareOrder(Order platformOrder, ResponsePay responsePay);
 
    @Override
    public ResponsePay generatePrepareOrder(Order platformOrder) throws OrderException{
        if(platformOrder == null){
            throw new IllegalArgumentException("订单不能为空: platformOrder is required!");
        }
//        if(platformOrder.getServiceProvider() == null){
//            throw new IllegalArgumentException("提供商不能为空: serviceProvider is required!");
//        }
//        if(platformOrder.getPayType() == null){
//            throw new IllegalArgumentException("支付类型不能为空: payType is required!");
//        }
        if(StringUtils.isEmpty(platformOrder.getNotifyUrl())){
            throw new IllegalArgumentException("支付回调地址未设置: notifyUrl is required!");
        }
        if(platformOrder.getId() <= 0){
            throw new IllegalArgumentException("订单ID必须设置: id is required!");
        }
        /*if(StringUtils.isEmpty(platformOrder.getVersion())){
            logger.warn("订单未设置支付提供者版本号,系统默认设置为:" + Constants.DEFAULT_VERSION);
            ((DefaultOrder)platformOrder).setVersion(Constants.DEFAULT_VERSION);
        }*/
        // 2023-02-20 由引擎设置支付提供者的版本号,让业务可以选择使用。
        ((DefaultOrder)platformOrder).setVersion(this.getVersion());
 
        String providerPayType = this.acquireProviderPayType(this.serviceProvider, platformOrder.getPayType(), this.payChannel);
        if(StringUtils.isEmpty(providerPayType)){
            throw new IllegalArgumentException("请实现方法 'acquireProviderPayType', payType = " + platformOrder.getPayType());
        }
 
        // 业务生成的订单编号
        String orderId = String.valueOf(platformOrder.getId());
 
        OrderGenerator orderGenerator = this.acquireOrderGenerator(providerPayType, platformOrder, this.configuration);
        if(orderGenerator == null){
//            throw new IllegalArgumentException("获取订单生成器对象为空: acquireOrderGenerator is null!");
            throw new OrderException(orderId, "不支持供应商的订单支付类型:" + providerPayType + ", payType=" + platformOrder.getPayType(), null);
        }
 
        // 2023-02-17 创建支付操作的上下文对象
        PayContext payContext = this.acquirePayContext(providerPayType, platformOrder, this.configuration);
        if(payContext == null){
            logger.error("PayContext创建为空,无法执行操作。platformOrder={}", platformOrder);
            return null;
        }
        AbstractPayContext abstractPayContext = (AbstractPayContext) payContext;
        abstractPayContext.setProviderPayType(providerPayType);
        abstractPayContext.setPayDefinition(this.getPayDefinition());
 
        try {
//            ResponsePay responsePay = orderGenerator.generate(providerPayType, platformOrder, this.configuration);
            ResponsePay responsePay = orderGenerator.generate(payContext, platformOrder);
            if(responsePay == null){
                logger.error("预订单生成为空: responseValue is null! platformOrder={}", platformOrder);
                return null;
            }
//            if(this.isOrderSuccess(responseValue)){
            if(responsePay.getStatus()){
                this.savePrepareOrder(platformOrder, responsePay);
            } else {
                logger.warn("预下单第三方返回失败: " + responsePay.getMessage());
            }
            return responsePay;
 
        } catch (OrderException e) {
            logger.error("订单生成异常:" + e.getMessage() + ", orderId=" + e.getOrderId(), e);
            throw e;
        }
    }
 
    @Override
    public void notifyOrder(Object notifyData
//            , OrderCallBack callBack
    ) throws NotifyException{
        if(notifyData == null || StringUtils.isEmpty(notifyData.toString())){
            throw new NotifyException(StringUtils.EMPTY_STRING, "订单通知数据为空", null);
        }
        if(this.orderNotifyConvertor == null){
            throw new IllegalArgumentException("请先设置 orderNotifyConvertor 对象.");
        }
 
        try {
            boolean signSuccess = this.verifySign(notifyData);
            if(!signSuccess){
                throw new NotifyException("", "签名验证未通过,source=" + notifyData, null);
            }
        } catch (Exception e) {
            throw new NotifyException("", "验证签名异常:" + e.getMessage(), e);
        }
 
        // 转换接收的数据格式为支付系统定义的抽象数据。
        NotifyValue<?> notifyValue = null;
        try{
            notifyValue = this.orderNotifyConvertor.toGenericObject(notifyData);
        } catch (Exception ex){
            throw new NotifyException(StringUtils.EMPTY_STRING, "notifyValue转换错误:" + ex.getMessage(), ex);
        }
        if(notifyValue == null){
            throw new NotifyException(StringUtils.EMPTY_STRING, "notifyValue 转换为空:" + notifyData, null);
        }
        notifyValue.setSource(notifyData);
        notifyValue.setPayChannel(this.payChannel);
        notifyValue.setServiceProvider(this.serviceProvider);
        notifyValue.setVersion(this.version);
 
        // 1: 处理平台对通知调用, 一定要把异常抛出,为第三方支付确认准备。
        try{
            this.onNotifyOrder(notifyValue);
        } catch (Exception ex){
            if(ex instanceof CallBackException){
                logger.error("订单通知在'业务回调'中执行错误:" + ex.getMessage(), ex);
            }
            throw new NotifyException(notifyValue.getOrderId(), "支付通知'平台调用'异常:" + ex.getMessage(), ex);
        }
        /*if(callBack == null){
            logger.warn("业务未传入'订单通知回调对象',确定是否需要配置!");
            return;
        }
        try {
            callBack.onOrderNotify(notifyValue);
        } catch (CallBackException e) {
            throw new NotifyException(notifyValue.getOrderId(), "支付通知'业务调用'异常:" + e.getMessage(), e);
        }*/
    }
 
    @Override
    public OrderStatusResponsePay searchOrderStatus(Order order){
        OrderStatusQuery orderStatusQuery = this.acquireOrderStatusQuery(order);
        if(orderStatusQuery == null){
            throw new IllegalArgumentException("OrderStatusQuery为空,请实现方法:acquireOrderStatusQuery();");
        }
        try {
            return this.invokeOrderStatus(orderStatusQuery);
        } catch (Exception ex){
            throw new ApplicationRuntimeException("查询订单状态异常, orderId=" + order.getId() + ", msg=" + ex.getMessage(), ex);
        }
    }
 
    /**
     * 验证签名是否合法。
     * @param notifyData
     * @return
     * @throws Exception
     * @date 2023-03-05
     */
    protected abstract boolean verifySign(Object notifyData) throws Exception;
 
    /**
     * 平台处理订单支付通知,目前与业务回调区分开。
     * <pre>
     *     1)需要处理多次通知的情况,否则无法给第三方确认(如:微信)
     *     2)主要是保存平台订单操作。
     * </pre>
     * @param notifyValue
     * @date 2023-01-17
     */
    protected abstract void onNotifyOrder(NotifyValue<?> notifyValue) throws Exception;
 
    /**
     * 生成支付操作上下文对象。
     * @param providerPayType 第三方支付类型
     * @param platformOrder 平台订单
     * @param configuration 参数配置
     * @return
     * @date 2023-02-17
     */
    protected abstract PayContext acquirePayContext(String providerPayType, Order platformOrder, Map<String, Variable> configuration);
 
    /**
     * 获取订单查询条件对象,由子类组装定义。
     * @param order 系统订单号
     * @return
     * @date 2023-02-23
     */
    protected abstract OrderStatusQuery acquireOrderStatusQuery(Order order);
 
    /**
     * 实现具体查询订单状态过程。
     * @param orderStatusQuery
     * @return
     * @date 2023-02-23
     */
    protected abstract OrderStatusResponsePay invokeOrderStatus(OrderStatusQuery orderStatusQuery);
 
    public PayDefinition getPayDefinition() {
        return payDefinition;
    }
 
    @Override
    public void setPayDefinition(PayDefinition payDefinition) {
        this.payDefinition = payDefinition;
    }
 
    /**
     * 返回订单业务操作回调实现,在订单下单以及通知等过程中可实现业务切入机会。
     * @return
     * @date 2023-02-20
     */
    public OrderCallBack getOrderCallback() {
        return orderCallback;
    }
 
    @Override
    public void setOrderCallback(OrderCallBack orderCallback) {
        this.orderCallback = orderCallback;
    }
 
    private OrderCallBack orderCallback;
    private PayDefinition payDefinition;
}