#ruby-on-rails #stripe-payments #webhooks
Вопрос:
В моей реализации Stripe пользователь может добавлять новые способы оплаты, подобные этому:
class PaymentMethodsController < ApplicationController
def index
@payment_methods = current_account.payment_methods
end
def new
setup_intent = Stripe::SetupIntent.create({
:payment_method_types => ['card', 'sepa_debit'],
:customer => current_account.stripe_id
})
@client_secret = setup_intent.client_secret
end
def create
flash[:success] = "Payment method created."
redirect_to payment_methods_path
end
end
(Однако точная реализация здесь не имеет большого значения.)
Я также храню копии способов оплаты каждого пользователя в своей базе данных, чтобы иметь возможность показывать их пользователю в index
представлении моего контроллера.
Проблема в том, что теперь я использую веб-крючки Stripe для создания этих записей базы данных, и обычно для того, чтобы эти веб-крючки попали в мое приложение, требуется пара секунд.
Поэтому, когда я перенаправляю своего пользователя в список способов оплаты ( payment_methods_path
) после того, как он создал новый, последний способ оплаты обычно там не отображается, что очень сбивает с толку. Только когда пользователь перезагрузит свою страницу, новая запись станет видимой (потому что к тому времени веб-крючок Stripe завершится успешно).
Есть ли способ задержать действие контроллера Rails до тех пор, пока определенный веб-крючок не завершится успешно, или даже задержать его на фиксированное количество секунд (например, 5)?
Я сталкиваюсь с той же проблемой с моими подписками, которые создаются локально только после успешного запуска webhook. До тех пор мои пользователи все еще находятся в бесплатном плане в течение нескольких секунд, что не является серьезной проблемой, но все еще очень сбивает с толку многих моих пользователей.
Каков наилучший способ решения этой проблемы?
Ответ №1:
Есть ли способ задержать действие контроллера Rails до тех пор, пока определенный веб-крючок не завершится успешно, или даже задержать его на фиксированное количество секунд (например, 5)?
Да, но это плохая идея. Вы можете отложить отправку ответа, просто отправив сервер в спящий режим. Однако это НЕ то, что вы хотите, так как это может привести к тому, что клиент отключит соединение и свяжет поток на вашем веб-сервере.
Классическим решением этой проблемы является опрос или длительный опрос, при котором вы используете JavaScript для отправки повторяющихся запросов XHR на сервер до тех пор, пока не закончится то, чего вы ждете. Длительный опрос устраняет затраты, связанные с настройкой новых подключений, но требует, чтобы сервер разрешал большое количество одновременных подключений.
В настоящее время вы можете использовать WebSockets, который обеспечивает двустороннее соединение. Это имеет встроенную поддержку в рельсах в виде ActionCable. отправленные сервером события также являются альтернативой, но для этого требуется, чтобы вы в большей степени использовали свои собственные.
Ответ №2:
Вы также можете сделать код в своем веб-крючке и в своем обратном URL-адресе идемпотентным; т. Е. любой из них может создать эту вещь. Таким образом, не имеет значения, что произойдет первым, и поскольку у вас есть веб-крючок, это обязательно произойдет в конце концов.