Reputation: 135
I am using ngrok to test stripe webhooks on my rails 5.2 application, and there is no http request when a payment is completed on stripe. (the payment is successful though).
I set up the webhook like this:
mount StripeEvent::Engine, at: '/stripe-webhooks'
StripeEvent.configure do |events|
events.subscribe 'checkout.session.completed', StripeCheckoutSessionService.new
end
class StripeCheckoutSessionService
def call(event)
order = Order.find_by(checkout_session_id: event.data.object.id)
order.update(state: 'paid')
end
end
What I see in my terminal when I process a payment, from ngrok:
Session Status online
Session Expires 7 hours, 45 minutes
Version 2.3.35
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://a2544196cf1f.ngrok.io -> http://localhost:3000
Forwarding https://a2544196cf1f.ngrok.io -> http://localhost:3000
Connections ttl opn rt1 rt5 p50 p90
10 0 0.00 0.00 20.80 61.31
HTTP Requests
-------------
GET /orders/2/messages/new 200 OK
GET /orders/2/payments/new 200 OK
POST /orders/2 302 Found
GET /assets/font-awesome/fa-regular-400-6a8c8e9e1e7f692c21af1956de163f3d026778e6449fe93a09a671847ca1ae65.woff2 200 OK
GET /orders/2 200 OK
GET /assets/font-awesome/fa-solid-900-7f4d3fd0a705dbf8403298aad91d5de6972e6b5d536068eba8b24954a5a0a8c7.woff2 200 OK
GET / 200 OK
POST /users/sign_in 302 Found
GET /users/sign_in 200 OK
I tried to send a webhook test from the stripe dashboard and I get a 400 error :
Cannot render console from 54.187.174.169! Allowed networks: 54.187.205.235, 127.0.0.0/127.255.255.255, ::1
Processing by StripeEvent::WebhookController#event as XML
Parameters: {"created"=>1326853478, "livemode"=>false, "id"=>"evt_00000000000000", "type"=>"checkout.session.completed", "object"=>"event", "request"=>nil, "pending_webhooks"=>1, "api_version"=>nil, "data"=>{"object"=>{"id"=>"cs_00000000000000", "object"=>"checkout.session", "billing_address_collection"=>nil, "cancel_url"=>"https://example.com/cancel", "client_reference_id"=>nil, "customer"=>nil, "customer_email"=>nil, "livemode"=>false, "locale"=>nil, "metadata"=>{}, "mode"=>"payment", "payment_intent"=>"pi_00000000000000", "payment_method_types"=>["card"], "setup_intent"=>nil, "shipping"=>nil, "shipping_address_collection"=>nil, "submit_type"=>nil, "subscription"=>nil, "success_url"=>"https://example.com/success"}}, "webhook"=>{"created"=>1326853478, "livemode"=>false, "id"=>"evt_00000000000000", "type"=>"checkout.session.completed", "object"=>"event", "request"=>nil, "pending_webhooks"=>1, "api_version"=>nil, "data"=>{"object"=>{"id"=>"cs_00000000000000", "object"=>"checkout.session", "billing_address_collection"=>nil, "cancel_url"=>"https://example.com/cancel", "client_reference_id"=>nil, "customer"=>nil, "customer_email"=>nil, "livemode"=>false, "locale"=>nil, "metadata"=>{}, "mode"=>"payment", "payment_intent"=>"pi_00000000000000", "payment_method_types"=>["card"], "setup_intent"=>nil, "shipping"=>nil, "shipping_address_collection"=>nil, "submit_type"=>nil, "subscription"=>nil, "success_url"=>"https://example.com/success"}}}}
No signatures found matching the expected signature for payload
I tried to whitelist the ip in my development.rb file :
config.web_console.whitelisted_ips = '54.187.205.235'
But nothing happened. Any Help?
my orders controller:
class OrdersController < ApplicationController
def show
@order = Order.find(params[:id])
end
def update
order = Order.find(params[:id])
order.update(order_params)
line_items_order = order.order_items.map { |item|{
"name" => item.product.name,
"amount" => item.product.price_cents,
"currency" => 'eur',
"quantity" => item.quantity,
"description" => item.grind
}
}
session = Stripe::Checkout::Session.create(
payment_method_types: ['card'],
shipping_address_collection: {
allowed_countries: ['US', 'CA', 'FR', 'PT', 'ES']
},
line_items: line_items_order,
success_url: new_order_message_url(order),
cancel_url: order_url(order)
)
order.update(checkout_session_id: session.id)
redirect_to new_order_payment_path(order)
end
private
def order_params
params.require(:order).permit(:amount_cents_cents)
end
end
and I configured the stripe.rb file like this :
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
with all the keys in the .env file
I finally got this response from stripe webhook dashboard :
<!doctype html5>
<html>
<head>
<style type="text/css">
strong { font-weight: bold; }
hr { -moz-box-sizing: content-box; box-sizing: content-box; height: 0; }
html { font-family: sans-serif; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; } body { margin: 0; }
a { background-color: transparent; }
a:active, a:hover { outline: 0; }
</style>
<style type="text/css">
body { background-color: #f5f5f5; }
.container { width: 500px; margin: auto; color: #444; padding: 5px; }
a, strong { color: purple; text-decoration: none; }
a:hover { text-decoration: underline; }
h2 { text-align: center; color: #000; }
p { line-height: 20px; }
</style>
</head>
<body>
<div class="container">
<h2>Failed to complete tunnel connection</h2>
<hr />
<p>
The connection to <strong><a href="http://a2544196cf1f.ngrok.io">http://a2544196cf1f.ngrok.io</a></strong>
was successfully tunneled to your ngrok client,
but the client failed to establish a connection to
the local address <strong><a href="http://localhost:3000">localhost:3000</a></strong>.
</p>
<p>
Make sure that a web service is running on
<strong><a href="http://localhost:3000">localhost:3000</a></strong> and that it is a valid address.
</p>
<p>
The error encountered was: <strong style="color: #9E2929">dial tcp [::1]:3000: connect: connection refused</strong>
</p>
</div>
</body>
</html>
I made the test from the ngrok http address, with my local host3000 running. Is that ok?
(when I run the test directly from the localhost 3000, I have a 502 error)
Thanks to @taintedzodiac I saw that my post request is wrong:
"message": "You must pass either `subscription_data` or `line_items` or `mode`.",
"type": "invalid_request_error"
I set the line_items in the Stripe::Checkout::Session.create, how could I pass thesame in the post?
Upvotes: 2
Views: 1263
Reputation:
If you don’t have a dedicated ngrok account, the domain name of the ngrok proxy will change if you terminate and restart ngrok on your local machine. To that end, I’m wondering if what you have works, but you haven’t POSTed the current callback url (ie Stripe has an invalid callback url to send the data to)?
Upvotes: 0