我正在我的节点应用程序中实现stripe api。我遇到的问题是,如果我多次单击提交按钮非常快,则会多次调用api,并且条带客户突然有多个订阅和收费。
该方案是用户拥有条带客户帐户而没有订阅,因为他们之前已取消订阅。现在,他们希望重新订阅新计划,因为旧计划已被删除。
我的代码逻辑如下:
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
我想要的是什么:
问题:
我如何解决这个问题。
注意:当然我有前端处理这个以防止用户多次提交表单但这不是理想的,并且不希望这是我唯一的防线。
由于
答案 0 :(得分:0)
使用功能强大的限速器库
https://github.com/jhurliman/node-rate-limiter
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
}
}
这会限制每个会话(每个用户浏览器)
答案 1 :(得分:0)
一种方法是保留最近交易的缓存(在Redis或类似情况下),由从关键交易值(例如客户ID,日期,时间,金额)派生的散列索引。
在将订阅请求提交到条带之前,将当前事务与缓存进行比较。如果收到命中,您可以显示错误,自动忽略该交易,或让用户选择是否继续。
答案 2 :(得分:0)
在第一次点击后立即使用 javascript 禁用前端中的按钮。
答案 3 :(得分:0)
Stripe 内置功能可帮助您防止这种情况发生。 https://stripe.com/docs/api/idempotent_requests
您需要生成一个唯一的字符串并将其与条带请求一起发送。
将它以隐藏形式放入 HTML 中,即您的 CORS 令牌,然后将其读出并将其放入 Stripe 调用中将防止双击/重试。