# How to integrate an online payment gateway in Bubble

- Tool: Bubble
- Difficulty: Beginner
- Time required: 25-30 min
- Compatibility: All Bubble plans (paid plan recommended for live payments)
- Last updated: March 2026

## TL;DR

Integrate a payment gateway in Bubble by comparing Stripe, PayPal, and other options, then implementing your chosen gateway with the appropriate plugin or API Connector. This tutorial covers the decision framework, Stripe Checkout setup, PayPal integration, and best practices for handling payments securely in a no-code environment.

## Overview: Payment Gateways in Bubble

Every monetized app needs a payment gateway. This tutorial compares the top options for Bubble, walks through setting up the most common (Stripe), and covers payment confirmation, error handling, and security best practices.

## Before you start

- A Bubble account with user authentication
- A payment gateway account (Stripe recommended)
- Basic understanding of Workflows and Plugins

## Step-by-step guide

### 1. Choose your payment gateway

Compare options: Stripe (most popular with Bubble, best plugin support, 2.9% + 30¢), PayPal (wide user base, buyer protection, 2.9% + 30¢), Square (good for in-person + online), Razorpay (popular in India). For most Bubble apps, Stripe is the recommended choice due to its native plugin, Checkout hosted page, and subscription support.

**Expected result:** You have selected the payment gateway that fits your needs.

### 2. Install and configure the Stripe plugin

Go to Plugins → Add plugins → search 'Stripe.' Install the official Stripe plugin. In plugin settings, enter your Stripe Publishable Key (starts with pk_test_ or pk_live_) and Secret Key (starts with sk_test_ or sk_live_). Start with test keys for development.

> Pro tip: Use test mode keys during development. Switch to live keys only when deploying to production. Test card: 4242 4242 4242 4242.

**Expected result:** Stripe plugin configured with API keys.

### 3. Create a Stripe Checkout payment flow

On your payment page, add a 'Pay Now' button. The workflow: Action 1 — Create a Stripe Checkout Session (via API Connector or plugin). Set the price, product description, success URL, and cancel URL. Action 2 — Navigate to the Checkout Session URL. Stripe handles the entire payment page — card input, validation, and processing. The user returns to your success URL after paying.

**Expected result:** Clicking Pay Now redirects to Stripe's hosted payment page.

### 4. Handle payment confirmation with webhooks

Create a backend workflow called 'stripe-webhook.' In your Stripe dashboard, add a webhook endpoint pointing to this workflow's URL. Listen for 'checkout.session.completed' events. When received: find the user by email or customer ID, mark their order as paid, and trigger any fulfillment actions. Always use webhooks instead of relying on the success page redirect.

**Expected result:** Successful payments automatically update order status via webhook.

### 5. Add error handling and payment states

Track payment status with an Order data type: status (Option Set: Pending/Paid/Failed/Refunded). Set to Pending when checkout starts, Paid on webhook confirmation, Failed if the user cancels or payment fails. Display appropriate messages on the success and cancel pages. Add admin tools for viewing payment status and processing refunds.

**Expected result:** Payment states are tracked from initiation through confirmation or failure.

## Complete code example

File: `Workflow summary`

```text
PAYMENT GATEWAY — SETUP SUMMARY
==================================

STRIPE SETUP:
  Plugin: Stripe (official)
  Keys: pk_test_xxx (publishable), sk_test_xxx (secret)
  Test card: 4242 4242 4242 4242, any future exp, any CVC

PAYMENT FLOW:
  1. User clicks Pay Now
  2. Create Stripe Checkout Session → get URL
  3. Redirect to Stripe Checkout
  4. User enters card and pays
  5. Stripe redirects to success/cancel URL
  6. Webhook confirms payment → update order status

WEBHOOK EVENTS:
  checkout.session.completed → mark order as Paid
  payment_intent.payment_failed → mark order as Failed
  charge.refunded → mark order as Refunded

ORDER STATUS:
  Pending → Paid → (optionally) Refunded
  Pending → Failed (user cancelled or payment declined)

SECURITY:
  - Never expose secret key in frontend
  - Always confirm payments via webhook, not redirect
  - Use HTTPS for all payment pages
```

## Common mistakes

- **Using the success redirect page to confirm payment** — Users can navigate directly to the success URL without paying Fix: Always use Stripe webhooks to confirm payments server-side. The success page should check order status before showing confirmation.
- **Exposing the Stripe secret key in frontend actions** — The secret key grants full access to your Stripe account including creating charges and viewing customer data Fix: Use the secret key only in backend workflows and the plugin's server-side settings. Never put it in frontend JavaScript.
- **Not testing with Stripe test mode first** — Real charges cannot be easily reversed and debugging is harder with live payments Fix: Use test mode keys and test card numbers throughout development. Switch to live keys only for production.

## Best practices

- Always use Stripe webhooks to confirm payments, never redirect URLs alone
- Keep secret keys in backend workflows and plugin settings only
- Test thoroughly with Stripe test mode before going live
- Track payment states in your database for order management
- Add admin tools for viewing payments and processing refunds
- Display clear error messages when payments fail
- Implement idempotency to prevent duplicate charges

## Frequently asked questions

### Can I use both Stripe and PayPal?

Yes. Add both options on your checkout page. Some users prefer PayPal for buyer protection, while others prefer direct card payment via Stripe.

### How do I handle subscriptions?

Use Stripe's subscription billing. Create Products and Prices in Stripe, then use Stripe Checkout in 'subscription' mode. Handle subscription webhooks for renewals and cancellations.

### What are Stripe's fees?

2.9% + 30¢ per successful card charge in the US. International cards have additional fees. No monthly fees for standard accounts.

### Can I accept payments on Bubble's Free plan?

The Stripe plugin works on all plans, but you cannot deploy to a custom domain on the Free plan. Test payments work in development on any plan.

### How do I handle refunds?

Use the Stripe API via API Connector or the plugin to create a refund. Update the order status to Refunded and notify the customer.

### Can RapidDev set up payments for my app?

Yes. RapidDev implements complete payment systems including checkout, subscriptions, invoicing, and financial reporting.

---

Source: https://www.rapidevelopers.com/bubble-tutorial/integrate-an-online-payment-gateway-in-bubble
© RapidDev — https://www.rapidevelopers.com/bubble-tutorial/integrate-an-online-payment-gateway-in-bubble
