Metamorphic (Early Access) is using Elixir

:tada: Update 3/26/2022 :partying_face:

It appears the webhooks timing out issue on new subscription sign ups has been resolved!

You should now be able to sign up for 14-day free trial (in Firefox or otherwise) and start using the app. Let me know if you are still having an issue.

From what I had been reading, it seemed that there was some kind of delay causing no responses to be returned on webhooks that I thought would be returning responses.

Attempts

I did a few things to get to where it appears to be working:

  • create Oban workers to send off the calls to stripe for attaching payment method and creating subscriptions
  • [deprecated] Task.Supervisor to call the function that calls into the webhooks supervised genserver (webhooks genserver handles the events and notifying subscribers via PubSub of the events)
  • [deprecated] call the success function to try and immediately return a 200 "ok" response to Stripe
  • drop stripe controller, deprecated items above, and custom body parser in favor of stripity_stripe’s Stripe.WebhookPlug
  • made a MetamorphicWeb.StripeHandler with stripity_stripe’s @behaviour Stripe.WebhookHandler

The challenge for me was that the webhooks would consistently work in development with the Stripe CLI (considering ngrok for future). So, I would first check that things work there and then have to test in production on my own account and go back and forth.

I think this really was the difference-maker for me and I’d recommend anyone to default to this body parser method if using stripity_stripe:

# endpoint.ex

plug Stripe.WebhookPlug,
    at: "/webhooks/stripe",
    handler: MetamorphicWeb.StripeHandler,
    secret: {Application, :get_env, [:stripity_stripe, :webhook_signing_key]}

plug Plug.Parsers,
  ...

So, now the StripeHandler simply broadcasts out to the supervised webhooks_processor.ex GenServer to handle further processing and broadcasting:

# stripe_handler.ex
  ...
  @behaviour Stripe.WebhookHandler

  @impl true
  def handle_event(event) do
    notify_subscribers(event)
  end

  def notify_subscribers(event) do
    Phoenix.PubSub.broadcast(MetamorphicWeb.PubSub, "webhook_received", %{event: event})
  end

  def subscribe_on_webhook_received() do
    Phoenix.PubSub.subscribe(MetamorphicWeb.PubSub, "webhook_received")
  end

Thank you to @stefanchrobot (response to another thread), @andreaseriksson (stripe course), Conner Fritz blog and Simon Rydell’s blog post.

2 Likes