Basic Stripe integration

Change easily integrates with Stripe to add donations to your existing payment flow. This guide will show you how to add donations to most Stripe flows.

To add donations to your Stripe flow, you will need to:

  1. Adjust the payment amount to include a donation
  2. Listen for the payment_intent.succeeded webhook from Stripe
  3. Create the donation with Change

In this guide, we’ll address each of these steps.

1. Adjust the payment amount

To include a donation in your existing payment flow, adjust the payment amount to include the donation.

For example, if you’re using Stripe Checkout, you can add a donation line item to the payment:

# Add a donation to the payment amount
line_items: [
price_data: {
currency: 'usd',
product_data: { name: 'Donation to Make-a-Wish' },
unit_amount: 2000,
quantity: 1,
mode: 'payment',
success_url: ''

You may not be using Stripe Checkout, but the same principle applies to other Stripe products. Adjust the payment amount to include the donation you’d like to make.

2. Listen for the payment_intent.succeeded webhook

When a payment is successful, Stripe sends a payment_intent.succeeded webhook. This works for many Stripe flows including Checkout, Subscriptions, and more. Listen for this webhook to create a donation with Change.

If you’ve never used Stripe webhooks before, visit the Stripe docs to learn how to set up webhooks for your application. If you prefer not to use webhooks, see the alternatives to webhooks section below.

3. Create the donation with Change

When you receive the payment_intent.succeeded webhook, create a donation with Change. Use the Create a donation endpoint from the Change API.

# Using Sinatra. (This code is boilerplate from the Stripe docs)
post '/webhook' do
payload =
event = Stripe::Event.construct_from(
JSON.parse(payload, symbolize_names: true)

# Handle the event
case event.type
when 'payment_intent.succeeded'
# 👇 Make a donation 👇
body: {
amount: 2000, # $20.00
nonprofit_id: 'n_B7e7Xu5RFvYHGLHDCSMQ5Yck',
funds_collected: true,
headers: headers,
basic_auth: { username: 'YOUR_PUBLIC_KEY', password: 'YOUR_SECRET_KEY' }
puts "Unhandled event type: #{event.type}"

status 200

In the example above, a $20 donation is created to the Red Cross when a payment is successful. Change will keep track of the donations that you create. Each month, you’ll receive an invoice from Change for the total amount of donations you’ve created. When you pay the invoice, Change will automatically distribute the donations to the nonprofits you’ve selected.

In the example above, every donation is to the Red Cross, but you can adjust the donation amount, nonprofit, and more. Donate to other nonprofits by changing the nonprofit_id field. You can find nonprofit IDs in the Change dashboard on the nonprofit search page.

If you allow for different donation amounts or nonprofits, you need to keep track of these options in your application. Every payment flow is different, but here are some common approaches:

  • Hardcoded - If you only allow donations to a single nonprofit, you can hardcode the nonprofit ID in your application.
  • User input - If you allow users to choose the nonprofit, you can store the nonprofit ID in the metadata of the payment. When you receive the webhook, you can read the metadata to determine the nonprofit. Many Stripe products support metadata, including Checkout, PaymentIntents, Subscriptions, and more.
  • SKU based - If you associate nonprofits with certain products, you can use the product ID or SKU to determine the nonprofit in your server code. When you receive the webhook, you can look up the product ID or SKU to determine the nonprofit.
  • And more… - Every application is different, and you may think of your own way to integrate that works best for your code. If you’re not sure the best way to proceed, reach out and we’ll be happy to help.

Alternatives to webhooks

If you don’t want to use webhooks, you can create donations in a batch job or other asynchronous process. You can create donations at any time after the payment is successful. Some prefer to create donations in a job at the end of the day by looping over their successful payments from that day.

Made with ❤ in San Francisco | Changelog | Status