具有多个支付提供商的商店计费模式设计
Schema design for store billing with multiple payment providers
我在做什么
我正在使用 TelegrafJS
+ MongoDB
编写一个 Telegram
机器人;该机器人允许用户使用三种计费方式订阅私人频道:
- 贝宝
- 条纹
- 手动(当用户没有任何信用卡时,我手动生成私人频道的访问码,当用户输入访问码时,创建订阅)。
这里的主要问题是客户参考,事实上,当我使用 PayPal
或 Stripe
生成订阅时,customer_id
是不同的,因为它们是不同的支付提供商,所以我有以下情况:
P. Provider | Customer Id | Subscription Id
PayPal 1ac a
Stripe 2ac b
实际上我创建了以下模型来存储客户和订阅:
客户模型
let CustomerSchema = new Schema({
telegram_id: Number,
email: {
type: String
},
hasTrial: {
type: Boolean,
default: true
},
subscriptions: [SubscriptionSchema],
created_at: {
type: Date,
default: Date.now,
required: true
}
});
如你所见,有字段telegram_id
,这是使用用户的telegram.chat.id
赋值的,允许我在私人频道(用户付费的资源)中管理用户访问)。
还有 hasTrial
字段,它允许我创建一次手动订阅,此订阅未链接到任何支付提供商,但以与其他订阅相同的方式存储:
订阅模式
let SubscriptionSchema = new Schema({
_id: String,
period_start: {
type: Date,
required: true
},
period_end: {
type: Date,
required: true
},
status: {
type: String,
required: true
},
plan_id: {
type: String,
required: true
}
});
主要问题是:如何跟踪属于不同支付提供商的订阅 a
和 b
(如此不同 customer_id
)?
我的想法
我想在 Customer Model
中创建两个附加字段:
stripe_id: String
paypal_id: String
但老实说,我不喜欢这个解决方案。我需要以某种方式存储两个支付提供商的客户 ID,因为订阅状态通过 webhooks
更改,例如:
- Stripe 发送
subscription.cancelled
挂钩到链接到 2ac
客户的 b
订阅
- 我的应用程序将订阅
status
设置为 canceled
并且还将具有 telegram_id: 5
的用户从频道中踢出
使用当前的数据库设计,我无法知道订阅链接到哪个用户..
你能给我一些建议吗?
我不明白这是怎么回事。任何 RDBMS 都能够在同一列中存储不同格式的 PayPal 和 Stripe subscription_ids
,并使用简单的 SELECT 查询对 customer_id
进行相同的查找。
如有必要,PayPal(也许还有 Stripe)会让您在订阅状态更新中使用 'CUSTOM' 之类的字段来传递和接收 customer_id,但我不建议这取决于以任何方式使用此功能(除了可能作为备份——将 CUSTOM 字段设置为写入时,即新的订阅设置,但不要在您的业务逻辑中读取它)。
支付提供商不是数据库,他们的数据存储能力不应超出有效支付处理所必需的范围。正如我在回答的第一部分中提到的,您应该自己存储和检索 ID。
我在做什么
我正在使用 TelegrafJS
+ MongoDB
编写一个 Telegram
机器人;该机器人允许用户使用三种计费方式订阅私人频道:
- 贝宝
- 条纹
- 手动(当用户没有任何信用卡时,我手动生成私人频道的访问码,当用户输入访问码时,创建订阅)。
这里的主要问题是客户参考,事实上,当我使用 PayPal
或 Stripe
生成订阅时,customer_id
是不同的,因为它们是不同的支付提供商,所以我有以下情况:
P. Provider | Customer Id | Subscription Id
PayPal 1ac a
Stripe 2ac b
实际上我创建了以下模型来存储客户和订阅:
客户模型
let CustomerSchema = new Schema({
telegram_id: Number,
email: {
type: String
},
hasTrial: {
type: Boolean,
default: true
},
subscriptions: [SubscriptionSchema],
created_at: {
type: Date,
default: Date.now,
required: true
}
});
如你所见,有字段telegram_id
,这是使用用户的telegram.chat.id
赋值的,允许我在私人频道(用户付费的资源)中管理用户访问)。
还有 hasTrial
字段,它允许我创建一次手动订阅,此订阅未链接到任何支付提供商,但以与其他订阅相同的方式存储:
订阅模式
let SubscriptionSchema = new Schema({
_id: String,
period_start: {
type: Date,
required: true
},
period_end: {
type: Date,
required: true
},
status: {
type: String,
required: true
},
plan_id: {
type: String,
required: true
}
});
主要问题是:如何跟踪属于不同支付提供商的订阅 a
和 b
(如此不同 customer_id
)?
我的想法
我想在 Customer Model
中创建两个附加字段:
stripe_id: String
paypal_id: String
但老实说,我不喜欢这个解决方案。我需要以某种方式存储两个支付提供商的客户 ID,因为订阅状态通过 webhooks
更改,例如:
- Stripe 发送
subscription.cancelled
挂钩到链接到2ac
客户的b
订阅 - 我的应用程序将订阅
status
设置为canceled
并且还将具有telegram_id: 5
的用户从频道中踢出
使用当前的数据库设计,我无法知道订阅链接到哪个用户..
你能给我一些建议吗?
我不明白这是怎么回事。任何 RDBMS 都能够在同一列中存储不同格式的 PayPal 和 Stripe subscription_ids
,并使用简单的 SELECT 查询对 customer_id
进行相同的查找。
如有必要,PayPal(也许还有 Stripe)会让您在订阅状态更新中使用 'CUSTOM' 之类的字段来传递和接收 customer_id,但我不建议这取决于以任何方式使用此功能(除了可能作为备份——将 CUSTOM 字段设置为写入时,即新的订阅设置,但不要在您的业务逻辑中读取它)。
支付提供商不是数据库,他们的数据存储能力不应超出有效支付处理所必需的范围。正如我在回答的第一部分中提到的,您应该自己存储和检索 ID。