需要在条带检出和Webhook插入导轨6后将产品数量更新为零

问题描述 投票:1回答:1

我正在为艺术家搭建一个出售艺术品的网站。它使用条纹结帐进行付款。我已经设置了结帐和Webhook,一旦Webhook命中并且结帐会话完成,我需要将产品的数量更新为0。

这里是结帐控制器(认为是产品)

class CheckoutController < ApplicationController

  def create
    piece = Piece.find(params[:id])

    if piece.nil?
      redirect_to root_path
      return
    end 

    @session = Stripe::Checkout::Session.create(
      payment_method_types: [:card],
      line_items: [{
        name: piece.name,
        description: piece.description,
        amount: (piece.price*100).to_i,
        currency: 'usd',
        quantity: 1
      }],
      shipping_address_collection: {
        allowed_countries: ['US', 'CA'],
      },
      success_url: checkout_success_url,
      cancel_url: checkout_cancel_url
      )

    respond_to do |format|
      format.js
    end

  end 

  def success   

  end

  def cancel

  end


end

这里是webhook事件控制器

class WebhookEventsController < ApplicationController
  # ignore CSRF
  skip_before_action :verify_authenticity_token

  def create

    if !valid_signatures?
      render json: { message: "Invalid sigs"}, status: 400
      return
    end

    # idempotent
    if !WebhookEvent.find_by(source: params[:source], external_id: external_id).nil?
      render json: { message: "Already Processed #{ external_id }"}
      return
    end

    event = WebhookEvent.create(webhook_params)
    ProcessEventsJob.perform_later(event.id)    
    render json: params

  end

  def valid_signatures?
    if params[:source] == 'stripe'
      begin
        wh_secret = Rails.application.credentials.dig(:stripe, :wh)
        Stripe::Webhook.construct_event(
          request.body.read,
          request.env["HTTP_STRIPE_SIGNATURE" ],
          wh_secret
        )
      rescue Stripe::SignatureVerificationError => e
        return false
      end
    end
    true
  end

  def external_id
    return params[:id] if params[:source] == 'stripe'

    SecureRandom.hex
  end

  def webhook_params
    {
      source: params[:source],
      data: params.except(:source, :action, :controller).permit!,
      external_id: external_id
    }
  end
end

这里是条带处理程序,我认为更新单件数量的代码应该在其中

module Events
  class StripeHandler
    def self.process(event)
      stripe_event = Stripe::Event.construct_from(event.data)

      case stripe_event.type
      when 'checkout.session.completed'
        checkout_session = stripe_event.data.object
        # now can do #{ checkout_session.customer }.. or some attribute of checkout_session object
        puts "*** Do things here i.e. logic for emails/inventory management"

      end
    end
  end
end

所有这些,因此我基本上可以禁用艺术品上的购买按钮。

ruby-on-rails stripe-payments
1个回答
0
投票

这里有几点注意事项:

  1. [您可能想将client_reference_id设置为片段的ID,这使协调更容易:https://stripe.com/docs/api/checkout/sessions/create#create_checkout_session-client_reference_id

  2. 您需要在完成的会话中检查line_items或使用client_reference_id查找客户在会话完成后购买的商品。

到目前为止,您的控制器逻辑看起来正确。在Piece上需要一个quantity字段。我假设您在CheckoutSession创建中通过了{client_reference_id: piece.id}。在这种假设下,您的Webhook处理逻辑如下所示:

module Events
  class StripeHandler
    def self.process(event)
      stripe_event = Stripe::Event.construct_from(event.data)

      case stripe_event.type

      when 'checkout.session.completed'
        Piece.transaction do
          piece = Piece.find(id: checkout.client_reference_id)
          raise Exception.new("item already purchased!") if piece.quantity == 0
          piece.quantity = 0
          piece.save!
        end
      end
    end
  end
end

这实现了一个简单的“第一人称赢钱”的情况,因此,首先通过Checkout支付给定作品的第一人付款,然后将其checkout.session.completed Webhook发送到您的应用程序并首先进行处理的人将获得该作品。如果两个人同时付款,那么只有一个人可以得到该件,因此您可能想要执行一些操作,例如自动退款给客户并向他们发送电子邮件。

[我使用database transaction更新了商品,因此,如果两个客户以某种方式确切地同时付款,我们将不会不小心将both客户给予该商品。

© www.soinside.com 2019 - 2024. All rights reserved.