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 getConfiguration() { return configuration; } private Map configuration = null; private ServiceProvider serviceProvider; private String version; private PayChannel payChannel; private Convertor> orderNotifyConvertor = null; /** * 设置订单通知转换器对象。 * @param orderNotifyConvertor * @date 2023-01-16 */ public void setOrderNotifyConvertor(Convertor> orderNotifyConvertor) { this.orderNotifyConvertor = orderNotifyConvertor; } public void setConfiguration(Map 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 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; /** * 平台处理订单支付通知,目前与业务回调区分开。 *
     *     1)需要处理多次通知的情况,否则无法给第三方确认(如:微信)
     *     2)主要是保存平台订单操作。
     * 
* @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 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; }