Rails Stripe webhook 更新钱包余额

时间:2021-06-15 23:02:09

标签: ruby-on-rails ruby stripe-payments webhooks

最近怎么样?我需要一些帮助。

  • 我正在开发一个应用程序,该应用程序允许用户购买可用于预订Traceback (most recent call last): File "C:\Users\smith\eclipse-workspace\Practice\src\DecodeWeb.py", line 9, in <module> weatherTable = soup.select_one("div.Ai(c).D(f).Jc(sb).Fz(13px).Py(0).Px(0)") File "C:\Users\smith\AppData\Local\Programs\Python\Python39\lib\bs4\element.py", line 1834, in select_one value = self.select(selector, namespaces, 1, **kwargs) File "C:\Users\smith\AppData\Local\Programs\Python\Python39\lib\bs4\element.py", line 1869, in select results = soupsieve.select(selector, self, namespaces, limit, **kwargs) File "C:\Users\smith\AppData\Local\Programs\Python\Python39\lib\soupsieve\__init__.py", line 98, in select return compile(select, namespaces, flags, **kwargs).select(tag, limit) File "C:\Users\smith\AppData\Local\Programs\Python\Python39\lib\soupsieve\__init__.py", line 62, in compile return cp._cached_css_compile(pattern, namespaces, custom, flags) File "C:\Users\smith\AppData\Local\Programs\Python\Python39\lib\soupsieve\css_parser.py", line 211, in _cached_css_compile CSSParser(pattern, custom=custom_selectors, flags=flags).process_selectors(), File "C:\Users\smith\AppData\Local\Programs\Python\Python39\lib\soupsieve\css_parser.py", line 1058, in process_selectors return self.parse_selectors(self.selector_iter(self.pattern), index, flags) File "C:\Users\smith\AppData\Local\Programs\Python\Python39\lib\soupsieve\css_parser.py", line 909, in parse_selectors key, m = next(iselector) File "C:\Users\smith\AppData\Local\Programs\Python\Python39\lib\soupsieve\css_parser.py", line 1051, in selector_iter raise SelectorSyntaxError(msg, self.pattern, index) soupsieve.util.SelectorSyntaxError: Invalid character '(' position 6 line 1: div.Ai(c).D(f).Jc(sb).Fz(13px).Py(0).Px(0)
  • 积分
  • credits 存储在用户的 activities 中,并通过多态 wallet(这些 wallet_entries 连接到 {{1} } 表也是如此,当用户预订活动时,积分会被扣除)
  • 我正在使用 Stripe 处理 wallet_entries。当用户想要购买积分时,会创建一个 bookings,它包含 payments id 以及设置为待定的 "state" 属性。
  • 我设法设置了 Stripe Checkout 并配置了一个网络钩子,当付款成功时,该钩子将 order 状态从 pending 更新为 paid
  • 我的目标是在 Stripe 的 Webhook 更新 credit_package 状态时创建一个 order's。所述 wallet_entry 包含诸如 order'swallet_entry 引用等信息,以便使用正确的 number_of_credits
  • 更新用户的 wallet 余额
  • 我尝试在处理条纹事件的控制器中执行此操作,我将其包装在原子事务中以确保只有在 wallet 状态时才将积分添加到 number_of_credits 更新为付费
  • Webhook 正在成功更新 wallet 状态,但如果我添加更多行就会中断,这是我在 Stripe Webhooks 日志中遇到的错误: order's。我的猜测是这个逻辑应该在别处处理。
  • 这是我的文件:

条带初始化器

order's

条纹结帐会话服务

NameError in StripeEvent::WebhookController#event undefined local variable or method current_user  for <StripeCheckoutSessionService:0x000056103da42a38&>;

付款控制器

Rails.configuration.stripe = {
  publishable_key: ENV['STRIPE_PUBLISHABLE_KEY'],
  secret_key:      ENV['STRIPE_SECRET_KEY'],
  signing_secret:  ENV['STRIPE_WEBHOOK_SECRET_KEY']
}

Stripe.api_key = Rails.configuration.stripe[:secret_key]
StripeEvent.signing_secret = Rails.configuration.stripe[:signing_secret]

StripeEvent.configure do |events|
  events.subscribe 'checkout.session.completed', StripeCheckoutSessionService.new
end

订单控制器

class StripeCheckoutSessionService
  def call(event)
    ActiveRecord::Base.transaction do
      order = Order.find_by(checkout_session_id: event.data.object.id)
      order.update(state: 'paid')
      # Extra stuff that breaks code
      wallet = current_user.wallet
      wallet_entry = WalletEntry.create!(type: "Deposit", total_credits: order.credit_package.number_of_credits, wallet: wallet, entryable: order)
      wallet.credit_total += wallet_entry.total_credits
    end
  end
end

路线

class PaymentsController < ApplicationController
  before_action :authenticate_user!
  def new
    @order = Order.where(state: 'pending').find(params[:order_id])
  end
end
  • 对如何进行有什么建议吗?我愿意完全改变这种方法,甚至是支付网关架构。谢谢

1 个答案:

答案 0 :(得分:0)

对于 Stripe webhooks,请求由 Stripe 向您自己的应用程序发出。在此请求的上下文中,没有登录用户,因此 current_user 在执行 wallet = current_user.wallet 的行上不可用。

可能您需要做的是使用不同的东西抓取链接到此订单的用户。我可以想象您的 Order 模型以某种方式与用户相关联,在这种情况下,您可以:

order = Order.find_by(checkout_session_id: event.data.object.id)
order.update(state: 'paid')      
wallet = order.user.wallet