Javascript 使用Node.js时,条带API调用正在生成多个订阅
我正在我的节点应用程序中实现条带api。我遇到的问题是,如果我多次快速单击submit按钮,就会多次调用api,stripe客户会突然有多个订阅和费用 这种情况下,用户拥有一个没有订阅的条带客户帐户,因为他们以前已取消订阅。现在,由于旧计划已被删除,他们希望重新订阅新计划 我的代码逻辑如下:Javascript 使用Node.js时,条带API调用正在生成多个订阅,javascript,node.js,api,asynchronous,stripe-payments,Javascript,Node.js,Api,Asynchronous,Stripe Payments,我正在我的节点应用程序中实现条带api。我遇到的问题是,如果我多次快速单击submit按钮,就会多次调用api,stripe客户会突然有多个订阅和费用 这种情况下,用户拥有一个没有订阅的条带客户帐户,因为他们以前已取消订阅。现在,由于旧计划已被删除,他们希望重新订阅新计划 我的代码逻辑如下: 1. Submit form 2. I retrieve the user from my mongo db 3. I retrieve the customer from stripe using a s
1. Submit form
2. I retrieve the user from my mongo db
3. I retrieve the customer from stripe using a stored customer id (api call)
4. I create a customer subscription (api call)
5. I update the stripe customer object with their credit card (api call)
6. Respond back to user
- 以上所有操作都是使用异步瀑布来完成的,每个后续的异步调用都在一个单独的函数中
- 在第3步和第4步之间,我希望检索客户并检查他或她是否已经订阅,如果用户已经有活动订阅,则防止发生第4步和第5步李>
- 我正在测试这样一个场景:用户多次单击submit按钮,最终要为几个订阅付费。我认为这与node如何一次发送多个请求有关,因为它是异步的,我想检查是否进行了api调用,以检查是否设置了太长的时间,并且node在发送所有请求时没有等待
感谢使用功能强大的速率限制器库
这将限制每个会话(每个用户浏览器)使用功能强大的速率限制器库
这将限制每个会话(每个用户浏览器)一种方法是保留最近交易的缓存(在Redis或类似工具中),通过从关键交易值(例如客户id、日期、时间、金额)派生的散列进行索引
将订阅请求提交到stripe之前,请将当前事务与缓存进行比较。如果点击,您可以显示错误、自动忽略交易或让用户选择是否继续。一种方法是保留最近交易的缓存(在Redis或类似工具中),通过从关键交易值(例如客户id、日期、时间、金额)派生的哈希索引
将订阅请求提交到stripe之前,请将当前事务与缓存进行比较。如果点击,您可以显示错误,自动忽略事务,或者让用户选择是否继续。在第一次单击时立即使用javascript禁用前端中的按钮。在第一次单击时立即使用javascript禁用前端中的按钮。Stripe具有内置功能,可帮助您防止出现这种情况 您需要生成一个唯一的字符串,并将其与条带请求一起发送
将它以隐藏的形式放入HTML中,即CORS令牌,然后读取它并将其放入条带调用中,可以防止双击/重试。条带内置了帮助您防止这种情况的功能 您需要生成一个唯一的字符串,并将其与条带请求一起发送
将它以隐藏的形式放入HTML中,一个la your CORS令牌,然后读取它并将其放入Stripe调用将防止双击/重试。我尝试了一下,它似乎可以阻止每个用户,而不仅仅是那个用户。我的应用程序是无状态的,因此没有任何会话。我使用JSON Web令牌进行身份验证以防止会话的需要。啊,我很抱歉。每个用户的限制器将类似于密钥为req.connection.remoteAddress的情况。我尝试了一下,它似乎可以阻止每个用户,而不仅仅是那个用户。我的应用程序是无状态的,因此没有任何会话。我使用JSON Web令牌进行身份验证以防止会话的需要。啊,我很抱歉。每用户限制器类似于密钥为req.connection.remoteAddress的情况
var RateLimiter = require('limiter').RateLimiter;
// Allow 1 requests per minute
var limiterPayments = new RateLimiter(1, 'minute');
exports.payWithStripe = function(req,res){
limiterPayments.removeTokens(1,function(err,remainingRequests){
if (err){
return res.sendStatus(429);
} else {
// continue with stripe payment
}
}