I'm developing an application where users can pay a one time fee to submit a screenplay. The current flow looks like this:
- User fills out form
- Upon submitting form, the user is redirected to Stripe Checkout
- 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 )