多种支付方式之间安全选择的设计方法

问题描述 投票:0回答:1

我们需要动态支持多种支付方式(信用卡、PayPal、Google Pay 等...)。
我们可以更改用于实现某种支付方式的网关。
例如:
今天可以使用 Stripe SDK 实现 PayPal 付款方式,明天可以使用 PayPal SDK 实现。

这让我想到了策略模式,我可以通过任何网关 sdk 来实现每种支付方式。
示例::

class PayPalModel : IPaymentModel

class PayPalGateway(val someSdk: SDK) : IPaymentService<PayPalModel> {
     override suspend fun authorizeFunds(model: PayPalModel) {
        // someSdk can be: stripe sdk, paypal sdk, ...
     }
}

然后简单地注入服务,并调用“authorizeFunds”:

val gateways =
        listOf(
            CreditGateway(),
            PayPalGateway()
        )
 val api = PaymentAPI(gateways)
 api.authorizeFunds(PayPalModel(...)

然后“api”将首先在内部找到正确的服务:

private suspend fun findService(model: IPaymentModel): IPaymentService<IPaymentModel>? {
    for (service in paymentServices) {
        if (service.appliesTo(model)) {
            return service as IPaymentService<IPaymentModel>
        }
    }
    return null
}

但是,对于我们支持的所有付款方式,在下订单时,客户端仅向服务器发送两个字段:

  1. 选择的付款方式类型
  2. 他们从 Stripe/Square/.. SDK 收到的身份验证 ID/令牌

因此,在这种情况下,各种支付模型(PayPalModel、CreditModel,..)似乎是多余的,因为它们始终包含相同的数据。

但是,如果我们忽略或概括此模型,我们将失去所有类型的网关实现之间的类型安全区别。
例如,想象一下:

class PayPalGateway : IPaymentService { // omiting the model
    override suspend fun authorizeFunds(model: PaymentRequest) {
      /// stripe sdk, paypal sdk, ...
    }
}
class CreditGateway : IPaymentService<PaymentRequest> { // generalizing the model
    override suspend fun authorizeFunds(model: PaymentRequest) {
      /// stripe sdk, paypal sdk, ...
    }
}

因此,除了类命名之外,没有真正的方法可以“安全地”区分服务以便使用正确的服务。 上面的“findService”功能将被破坏/无用。 确保当客户端向我发送方法类型+令牌/id时,我选择正确的支付服务,明智的选择是什么?

kotlin design-patterns strategy-pattern
1个回答
0
投票

enum class PaymentType { PAY_PAL, CREDIT, ... } interface IPaymentModel { val type: PaymentType }

我想,该客户向您提供了有关他们的付款方式/服务的信息。这样,您只需检查该值并选择正确的网关即可。

when(model.type) { PAY_PAL -> // return the PayPal service class }

在我看来,这种方法比迭代可用服务更稳健。

© www.soinside.com 2019 - 2024. All rights reserved.