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