travisf
I’m working through this tutorial trying to get payments working with Stripe.
I’ve implemented a Stripe webhook handler:
defmodule Postbox.StripeHandler do
@behaviour Plug
alias Plug.Conn
def init(config), do: config
def call(%{request_path: "/webhook/payments"} = conn, _params) do
signing_secret = Application.get_env(:stripity_stripe, :webhook_key)
[stripe_signature] = Plug.Conn.get_req_header(conn, "stripe-signature")
with {:ok, body, _} = Plug.Conn.read_body(conn),
{:ok, stripe_event} =
Stripe.Webhook.construct_event(body, stripe_signature, signing_secret) do
Plug.Conn.assign(conn, :stripe_event, stripe_event)
else
err ->
conn
|> Conn.send_resp(:bad_request, err)
|> Conn.halt()
end
end
end
I’ve copied my webhook secret (:webhook_key directly from the signing secret) but I’m still, continuously getting this error from Stripe: ** (MatchError) no match of right hand side value: {:error, "No signatures found matching the expected signature for payload"}.
This is a test account and I’m using Ngrok for the Webhook address.
Initial question aside I’m wondering if I’m just using Stripe.Checkout.Session do I need to even bother with Webhooks? Willl Stripe returning a successful URL be sufficient?
Trending in Questions
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
Hi everyone,
I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding.
I sta...
New
Hello,
I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
Documentation
While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New
Other Trending Topics
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Hi everyone!
The first release candidate for the Expert language server project is now available!
We’ve published a press release detai...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #elixirconf-eu
- #metaprogramming
- #hex










Showing Posts 16 to 7- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
SteveL
Just a quick note about testing the
body_readerthat took me a while to figure out. I had a hard time just getting the custom body reader to run in controller tests until I realized the following:content-typeheader, andMy test ended up looking something like:
Hope that helps someone stop banging their head on the desk as much as I did!
sorentwo
I noticed that the post appears to be deleted earlier this week. Here’s a brief, working example of how to verify stripe webhooks in phoenix.
First, parsed JSON will strip some whitespace and alphabetize keys. To calculate the correct HMAC you need to stash the original unparsed request body. A small
body_readermodule will do it:Configure
Plug.Parsersto use the new body_reader module:Then define a private function to verify the signature in your controller:
That will do it! If you test your webhook controller, which you certainly should, you’ll need to inject a signature as well. The signature below is fake and computed using a test signing key (
whsec_test), a fake timestamp, and:raw_body:wceolin
Was your post deleted? It’s returning 404.
justincjohnson
Never mind. I thought it fixed it but it was intermittent. Back to the drawing board.
justincjohnson
For anyone else who runs into this, the problem for me had to do with this setting in Bandit.
I was able to get around the problem by changing my config to the following.
I haven’t thought deeply about the size to use, but this got around the error I was experiencing.
travisf
I finally got to the bottom of this, I had, occasionally, used an Ngrok tunnel as an endpoint for the webhook but mostly I was using
localhostI didn’t realize that when you ran the Stripe CLI locally it gave you a specificsigning_secretwhen the session started:I was using the signing secret from another endpoint I had setup for Ngrok.
travisf
Thanks! The Tolc tutorail was one of several I worked off of. I’ve gutted everything I’ve done on this and copied from their tutorial directly and this is the result whenever I call the webhook in Stripe:
There seems to be two problems here first is that there is no route for
/webhook/paymentswhich is not specified in the tutorial.The second (related?) problem is with parsing the response, I assume if it was reaching the correct endpoint this wouldn’t be a problem (assuming everything else works correctly)?
Sorry for my slow response, I’ve been moving and this is a side project.
focused
Look at the tutorial for
stripity_stripe: https://tolc.io/blog/stripe-with-elixir-and-phoenixMaybe you don’t need to implement a plug at all because it’s already implemented in the package? Just use the behaviours in your handler
@behaviour Stripe.WebhookHandler.Yes, you need to handle the event after the checkout like I did for setup payment methods:
It’s required to handle all checkout session events. Look at the Stripe API and handle your events according to entity statuses and event types.
In my case I needed to handle the “checkout.session.completed” and then update some payment method fields in the DB to make it active in my system.
Session object API
You should look at the events you need https://docs.stripe.com/api/events/types#event_types-checkout.session.async_payment_failed and handle them as you want, e.g. update a
Paymentschema entity status.I would not rely on synchronous API responses only and strongly advice to handle events in a webhook.
P.S.: some useful docs and recommendations about using webhooks - Receive Stripe events in your webhook endpoint | Stripe Documentation
wojtekmach
This blog post might be helpful: https://dashbit.co/blog/how-we-verify-webhooks.
travisf
I saw that but if you have
plug App.StripeHandlerbeforeplug Plug.Parserswouldn’t that resolve the issue without writing a custom parser?For what it’s worth: the payload from
Plug.Conn.read_body(conn)looks like:Essentially just stringifyed JSON. Should it be raw JSON?