Home > other >  Keep Encountering 500 Error When Using Stripe Webhooks with Ruby on Rails 7
Keep Encountering 500 Error When Using Stripe Webhooks with Ruby on Rails 7

Time:08-24

I'm developing an application where users can pay a one time fee to submit a screenplay. The current flow looks like this:

  1. User fills out form
  2. Upon submitting form, the user is redirected to Stripe Checkout
  3. Stripe webhook listens for session.checkout.completed, once that happens the is_paid field is updated to TRUE.

Every thing except the webhooks are working fine. I can submit the form, be redirect to stripe, and make a payment. The issue that I'm encountering is that whenever I use Stripe CLI (stripe listen --forward-to localhost:3000/webhooks) and go through the checkout process on my local environment, I receive the following errors in the Stripe CLI tab:

payment_intent.created
[500] POST http://localhost:3000/webhooks
customer.created
[500] POST http://localhost:3000/webhooks
payment_intent.succeeded
[500] POST http://localhost:3000/webhooks
charge.succeeded
[500] POST http://localhost:3000/webhooks
checkout.session.completed
[500] POST http://localhost:3000/webhooks

And the following errors in my Rails Server tab:

Completed 500 Internal Server Error in 0ms (ActiveRecord: 0.0ms | Allocations: 454)

ArgumentError (wrong number of arguments (given 0, expected 1 )):

app/controllers/webhooks_controller.rb:8:in `create'

The above says there's an error on line eight which would be endpoint_secret = Rails.application.credentials.dig[:stripe, :webhook_secret] but I don't see what's wrong with this. I've checked my credentials and they're definitely correct (I've copy and pasted them numerous times, made sure they were test keys, compared them letter by letter etc).

When I use stripe trigger checkout.session.completed I get the same errors.

If anyone has an idea of where I'm going wrong it would be apppreciated!

Here's what my screenplay_controller looks like:

def create
  @screenplay = current_user.screenplays.new(screenplay_params)

  if @screenplay.save
    session = Stripe::Checkout::Session.create({
      line_items: [{
        price: "removed for privacy",
        quantity: 1,
      }],
      mode: "payment",
      metadata: { screenplay_id: @screenplay.id },
      customer_email: current_user.email,
      success_url: root_url,
      cancel_url: root_url,
    })
    redirect_to session.url, allow_other_host: true
  else
    render :new, status: :unprocessable_entity
  end
end 

This is my webhooks_controller:

class WebhooksController < ApplicationController
  skip_before_action :verify_authenticity_token

  def create
    event = nil
    sig_header = request.env["HTTP_STRIPE_SIGNATURE"]
    payload = request.body.read
    endpoint_secret = Rails.application.credentials.dig[:stripe, :webhook_secret]

    begin
      event = Stripe::Webhook.construct_event(
        sig_header, payload, endpoint_secret
      )
    rescue JSON::ParserError => e
      # Invalid payload
      head 400
      return
    rescue Stripe::SignatureVerificationError => e
      # Invalid signature
      head 400
      return
    end

    case event.type
    when "checkout.session.completed"
      session = event.data.object

      screenplay = Screenplay.find_by(id: session.metadata.screenplay_id)
      screenplay.update(is_paid: true)
    end
  end
end

This is what my routes look like:

Rails.application.routes.draw do
  root "static_pages#home"

  devise_for :users
  resources :screenplays
  resources :webhooks, only: [:create]
end

And this is what my Stripe initialiser looks like:

Stripe.api_key = Rails.application.credentials.dig(:stripe, :secret_key)

CodePudding user response:

You need to replace square brackets with normal brackets

a = { b: :c }
a.dig(:b)
# Returns :c

a.dig[:b]
# ArgumentError: wrong number of arguments (given 0, expected 1 )
  • Related