Josh
Josh

Reputation: 589

stripe webhooks for rails 4

I have been trying to setup my first webhook with stripe. I found an article that looks like the right way to do it but 2 years old. I am thinking it is outdated.

Here is my controller so far.

class StripewebhooksController < ApplicationController
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here https://manage.stripe.com/account
    Stripe.api_key = "mytestapikey"

    require 'json'

    post '/stripewebhooks' do
      data = JSON.parse request.body.read, :symbolize_names => true
      p data

      puts "Received event with ID: #{data[:id]} Type: #{data[:type]}"

      # Retrieving the event from the Stripe API guarantees its authenticity  
      event = Stripe::Event.retrieve(data[:id])

      # This will send receipts on succesful invoices
      # You could also send emails on all charge.succeeded events
      if event.type == 'invoice.payment_succeeded'
        email_invoice_receipt(event.data.object)
      end
    end
end

Will this work correctly and is this the right way to do it? Here is the stripe documentation.

Upvotes: 3

Views: 2049

Answers (1)

Callmeed
Callmeed

Reputation: 5002

I'm using Stripe Webhooks in production and this doesn't look quite right. You should first define your webhook URL in your routes like this:

# config/routes.rb
MyApp::Application.routes.draw do
    post 'webhook/receive'
end

In this example your webhook url will be at http://yourapp.com/webhook/receive (that's what you give to Stripe). Then you need the appropriate controller and action:

class WebhookController < ApplicationController
  # You need this line or you'll get CSRF/token errors from Rails (because this is a post)
  skip_before_filter :verify_authenticity_token

  def receive
    # I like to save all my webhook events (just in case)
    # and parse them in the background
    # If you want to do that, do this
    event = Event.new({raw_body: request.body.read})
    event.save
    # OR If you'd rather just parse and act 
    # Do something like this
    raw_body = request.body.read
    json = JSON.parse raw_body
    event_type = json['type'] # You most likely need the event type
    customer_id = json['data']['object']['customer'] # Customer ID is the other main bit of info you need

    # Do the rest of your business here

    # Stripe just needs a 200/ok in return
    render nothing: true
  end

end

Another thing to note: every webhook you receive has an ID. It's good practice to save and check against this to make sure you're not acting on the same event more than once.

Upvotes: 5

Related Questions