This content originally appeared on DEV Community and was authored by Harsh patel
Webhooks are a way for an external service to notify your application about events that occur in the service. In other words, it's a way for your application to receive real-time notifications of events happening outside of your application.
In the context of Ruby on Rails, webhooks are commonly used to integrate with third-party services such as Stripe, PayPal, and others. These services use webhooks to send notifications to your application about events such as successful payments, failed payments, new subscribers, and other events.
By using webhooks in your Ruby on Rails application, you can automate processes that would otherwise require manual intervention, such as updating a user's account status or sending notifications to users. This can improve the user experience and streamline your application's workflow.
Webhooks can be implemented using a variety of protocols such as HTTP, HTTPS, and others. In Ruby on Rails, webhooks are typically implemented using controller actions that receive and process webhook requests, and background jobs to perform the actual work of handling the webhook events.
Overall, webhooks provide a powerful way to integrate your Ruby on Rails application with third-party services and automate processes in your application.
Handling webhooks efficiently and with proper error handling in a Ruby on Rails application is important to ensure that your application can handle large volumes of webhook requests and recover from any errors that may occur. In this example, we'll use the popular payment processing service Stripe to demonstrate how to handle webhooks efficiently and with proper error handling in a Ruby on Rails application.
Setup
The first step is to install the Stripe gem and configure it in your Rails application. You can do this by adding the following code to your Gemfile:
gem 'stripe'
Then, run bundle install to install the gem and generate a config/initializers/stripe.rb
file to configure the Stripe API keys:
Rails.configuration.stripe = {
publishable_key: ENV['STRIPE_PUBLISHABLE_KEY'],
secret_key: ENV['STRIPE_SECRET_KEY']
}
Stripe.api_key = Rails.configuration.stripe[:secret_key]
Create a Webhooks Controller
Next, you'll need to create a controller to handle webhook requests. You can create a new WebhooksController
with the following command:
rails generate controller webhooks
In the webhooks_controller.rb
file, define a new method to handle webhook requests:
class WebhooksController < ApplicationController
skip_before_action :verify_authenticity_token
def receive
event = Stripe::Event.construct_from(params.to_unsafe_h)
# Handle the event
begin
case event.type
when 'payment_intent.succeeded'
handle_payment_succeeded(event.data.object)
when 'payment_intent.payment_failed'
handle_payment_failed(event.data.object)
else
raise "Unhandled event type: #{event.type}"
end
rescue StandardError => e
render json: { error: e.message }, status: :unprocessable_entity
end
render json: { message: 'Webhook received successfully' }, status: :ok
end
private
def handle_payment_succeeded(payment_intent)
# Find the user associated with the payment
user = User.find_by(stripe_customer_id: payment_intent.customer)
# Check if the payment covers any outstanding invoices
invoices = user.invoices.unpaid
invoices.each do |invoice|
if invoice.amount_due <= payment_intent.amount_received
invoice.update(status: 'paid', paid_at: Time.now)
payment_intent.amount_received -= invoice.amount_due
end
end
# Create a new payment record
payment = Payment.create(
user: user,
amount: payment_intent.amount_received,
payment_method: payment_intent.payment_method,
payment_intent_id: payment_intent.id,
status: payment_intent.status,
paid_at: payment_intent.created
)
# Send a confirmation email to the user
UserMailer.payment_received(user, payment).deliver_later
rescue => e
Rails.logger.error("Error handling payment failed webhook: #{e}")
end
def handle_payment_failed(payment_intent)
# Find the user associated with the payment
user = User.find_by(stripe_customer_id: payment_intent.customer)
# Handle any unpaid invoices
invoices = user.invoices.unpaid
invoices.each do |invoice|
invoice.update(status: 'failed', failed_at: Time.now)
end
# Create a new payment record
payment = Payment.create(
user: user,
amount: payment_intent.amount_received,
payment_method: payment_intent.payment_method,
payment_intent_id: payment_intent.id,
status: payment_intent.status,
failed_at: payment_intent.created
)
# Send a notification email to the user
UserMailer.payment_failed(user, payment).deliver_later
rescue => e
Rails.logger.error("Error handling payment failed webhook: #{e}")
end
end
we first find the user associated with the payment by looking up their Stripe customer ID. We then check if the payment covers any outstanding invoices by iterating over the user's unpaid invoices and updating their status to "paid" if the payment amount is sufficient.
We then create a new Payment record in our database with information from the payment_intent object, including the user, payment amount, payment method, payment intent ID, and payment status. We also set the paid_at timestamp to the time the payment was created.
Then we find the user associated with the payment by looking up their Stripe customer ID. We then handle any unpaid invoices by iterating over the user's unpaid invoices and updating their status to "failed" with the update method.
We then create a new Payment record in our database with information from the payment_intent object, including the user, payment amount, payment method, payment intent ID, and payment status. We also set the failed_at timestamp to the time the payment was created.
Finally, we send a notification email to the user using a UserMailer object and the deliver_later method to send the email asynchronously.
Configure Webhooks in Stripe
Now that your application is set up to handle webhook requests, you need to configure your Stripe account to send webhook requests to your application. Log in to your Stripe dashboard and navigate to the "Webhooks" tab.
Click the "Add Endpoint" button and enter the URL for your webhook controller action (e.g. https://example.com/webhooks/receive). You can leave the other fields at their default values.
Finally, select the events you want to receive and click the "Add Endpoint" button. Stripe will now send webhook requests to your application whenever the selected events occur.
Testing
To test your webhook handling, you can use the Stripe CLI to simulate events. Install the Stripe CLI and run the following command: stripe trigger payment_intent.succeeded
This will simulate a payment_intent.succeeded event and send a webhook request to your application. Check your application logs to confirm that the webhook was received and handled successfully.
You can also simulate a failed payment by running:
stripe trigger payment_intent.payment_failed
This will simulate a payment_intent.payment_failed event and send a webhook request to your application. Again, check your application logs to confirm that the webhook was received and handled successfully.
If any errors occur during webhook handling, check your logs for error messages and make sure that your error handling code is working correctly.
It's also a good idea to test your webhook handling with a variety of scenarios, including successful and failed payments, network errors, and unexpected events.
And that's it! You now have a robust and efficient webhook handling system in your Ruby on Rails application. With proper error handling and testing, your application can handle large volumes of webhook requests and recover from any errors that may occur.
This content originally appeared on DEV Community and was authored by Harsh patel
Harsh patel | Sciencx (2023-03-19T06:40:31+00:00) Basic Understanding of Webhooks with examples. Retrieved from https://www.scien.cx/2023/03/19/basic-understanding-of-webhooks-with-examples/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.