【发布时间】:2014-03-22 02:08:48
【问题描述】:
我想要两件事:
a) 我希望只有在 API 调用成功时才能在数据库中保存记录
b) 我只想在 db 记录保存成功的情况下执行 API 调用
目标是使本地(数据库中)存储的数据与 Stripe 上的数据保持一致。
@payment = Payment.new(...)
begin
Payment.transaction do
@payment.save!
stripe_customer = Stripe::Customer.retrieve(manager.customer_id)
charge = Stripe::Charge.create(
amount: @plan.amount_in_cents,
currency: 'usd',
customer: stripe_customer.id
)
end
# https://stripe.com/docs/api#errors
rescue Stripe::CardError, Stripe::InvalidRequestError, Stripe::APIError => error
@payment.errors.add :base, 'There was a problem processing your credit card. Please try again.'
render :new
rescue => error
render :new
else
redirect_to dashboard_root_path, notice: 'Thank you. Your payment is being processed.'
end
上面的下面会起作用,因为如果记录(第 5 行)没有保存,其余的代码就不会执行。
但是如果我需要在 API 调用后保存 @payment 对象怎么办,因为我需要为 @payment 对象分配 API 结果中的值。举个例子:
@payment = Payment.new(...)
begin
Payment.transaction do
stripe_customer = Stripe::Customer.retrieve(manager.customer_id)
charge = Stripe::Charge.create(
amount: @plan.amount_in_cents,
currency: 'usd',
customer: stripe_customer.id
)
@payment.payment_id = charge[:id]
@payment.activated_at = Time.now.utc
@payment.save!
end
# https://stripe.com/docs/api#errors
rescue Stripe::CardError, Stripe::InvalidRequestError, Stripe::APIError => error
@payment.errors.add :base, 'There was a problem processing your credit card. Please try again.'
render :new
rescue => error
render :new
else
redirect_to dashboard_root_path, notice: 'Thank you. Your payment is being processed.'
end
您注意到@payment.save! 发生在 API 调用之后。这可能是一个问题,因为 API 调用在数据库尝试保存记录之前运行。这可能意味着 API 调用成功,但数据库提交失败。
对这个场景有什么想法/建议吗?
【问题讨论】:
标签: ruby-on-rails ruby ruby-on-rails-4 transactions stripe-payments