【问题标题】:Stripe - create / retrieve customer in one callStripe - 一键创建/检索客户
【发布时间】:2018-12-11 04:15:45
【问题描述】:

如果用户不存在,我们是否可以使用条带 API 调用来创建用户并检索新用户?

说我们这样做:

export const createCustomer = function (email: string) {
  return stripe.customers.create({email});
};

即使拥有该电子邮件的用户已经存在,它也会始终创建一个新的客户 ID。 是否有一种方法可以仅在用户电子邮件不存在于条带中时才创建用户?

我只是想避免竞争条件在同一时间范围内可能发生多个stripe.customers.create({email}) 调用。例如,我们检查 customer.id 是否存在,如果不存在,两个不同的服务器请求可能会尝试创建新客户。

这是比赛条件:

const email = 'foo@example.com';

Promise.all([
  stripe.customers.retrieve(email).then(function(user){
   if(!user){
     return stripe.customers.create(email);
   }
  },
 stripe.customers.retrieve(email).then(function(user){
   if(!user){
     return stripe.customers.create(email);
   }
 }
])

显然,竞争条件更可能发生在两个不同的进程或两个不同的服务器请求中,而不是同一个服务器请求,但你明白了。

【问题讨论】:

标签: stripe-payments stripe.js


【解决方案1】:

如果您的用例是您不想使用相同的电子邮件创建客户两次。

您可以使用条带幂等请求的概念。我用它来避免同一订单的重复收费。

您可以使用客户电子邮件作为幂等键。 Stripe 会在最后处理这个问题。具有相同幂等键的两个请求不会被处理两次。

此外,如果您想在某个时间范围内限制它,请使用客户电子邮件和该时间范围创建一个幂等密钥。它会起作用的。

API 支持幂等性,可以安全地重试请求,而无需 不小心执行了两次相同的操作。例如,如果一个 由于网络连接错误,创建费用的请求失败, 您可以使用相同的幂等密钥重试请求以保证 只创建一次充电。

您可以阅读有关此here 的更多信息。我希望这会有所帮助

【讨论】:

  • 这将适用于同一个例程,但这不适用于发出相同请求的不同进程,甚至同一进程中的两个不同例程发出相同类型的请求。
  • 幂等密钥仅在 24 小时内有效,因此这只会阻止您在 24 小时内使用相同的电子邮件创建客户。 :stripe.com/docs/api/#idempotent_requestskeys expire after 24 hours.
  • 这不适用于无法轻松共享幂等密钥的两个不同服务器请求,或者无法轻松共享同一幂等密钥的两个不同进程。幂等键仅在您在同一进程的同一例程中重试请求时才有用。
  • 生成幂等密钥就在您的手中。您可以通过两个进程生成相同的方式生成它。
【解决方案2】:

不,Stripe 中没有内置的方法可以做到这一点。 Stripe 不要求客户的电子邮件地址是唯一的,因此您必须自己验证它。您可以在自己的数据库中跟踪您的用户并避免重复,或者您可以使用 Stripe API 检查给定电子邮件是否已经存在客户:

let email = "test@example.com";
let existingCustomers = await stripe.customers.list({email : email});
if(existingCustomers.data.length){
    // don't create customer
}else{
    let customer = await stripe.customers.create({
        email : email
    });
}

【讨论】:

【解决方案3】:

正如 karllekko 的评论所提到的,幂等键在这里不起作用,因为它们只能持续 24 小时。

email 不是 Stripe 中的唯一字段;如果您想在您的应用程序中实现它,您需要在您的应用程序中处理它 - 即,您需要存储 [ email -> Customer ID ]s 并在那里进行查找以确定您是否应该创建。

假设您的应用程序中有一个 user 对象,那么无论如何,这个逻辑最好放在那里,因为您也希望将其作为其中的一部分 - 在这种情况下,每个 user 只会有一个 Stripe 客户,所以这将在其他地方解决。

【讨论】:

  • 赞成,但应用程序级锁定不是这里的答案,从 Stripe 的角度来看,它必须在数据库级别是原子的。我更新了 OP 以明确竞争条件。
【解决方案4】:

确实可以通过根据存储的db验证stripe的客户数据检索结果来解决。

之后再调用另一个API创建。

但是为了简单起见,我同意@user7898461 并保证retrieveOrCreate customer api :)

【讨论】:

    猜你喜欢
    • 2023-01-18
    • 2014-11-12
    • 2014-03-08
    • 2019-03-28
    • 2016-11-20
    • 1970-01-01
    • 2022-10-19
    • 2015-02-14
    • 2015-12-26
    相关资源
    最近更新 更多