# How to Integrate PayPal in Bubble

- Tool: Bubble
- Difficulty: Beginner
- Time required: 25-30 min
- Compatibility: All Bubble plans
- Last updated: March 2026

## TL;DR

PayPal integration in Bubble uses an HTML element to embed PayPal's Smart Payment Buttons and the API Connector to handle payment verification. The PayPal button renders in an HTML element, the user completes payment in a PayPal popup, and a JavaScript-to-Bubble bridge passes the transaction details back to a Bubble workflow that creates a payment record. This tutorial covers the full PayPal checkout flow.

## Overview: PayPal Integration in Bubble

This tutorial shows how to accept PayPal payments in your Bubble app using PayPal's Smart Payment Buttons embedded in an HTML element.

## Before you start

- A Bubble app with a checkout or payment flow
- A PayPal Business account with REST API credentials
- API Connector plugin installed
- Toolbox plugin for JavaScript-to-Bubble bridge (optional)

## Step-by-step guide

### 1. Get PayPal API credentials

Log into developer.paypal.com. Navigate to Apps & Credentials. Create a new app or use the default. Copy the Client ID and Secret for both Sandbox (testing) and Live environments. Store the Secret in the API Connector as a private parameter — never expose it client-side. The Client ID is safe for client-side use in the button embed.

**Expected result:** PayPal Client ID and Secret are available for both sandbox and production environments.

### 2. Embed PayPal Smart Payment Buttons

Add an HTML element where you want the PayPal button. Paste the PayPal SDK script and button rendering code. The SDK loads PayPal's button UI. In the createOrder function, specify the purchase amount. In the onApprove function, capture the payment and pass the transaction ID back to Bubble.

```
<div id="paypal-button-container"></div>
<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&currency=USD"></script>
<script>
paypal.Buttons({
  createOrder: function(data, actions) {
    return actions.order.create({
      purchase_units: [{
        amount: { value: '29.99' }
      }]
    });
  },
  onApprove: function(data, actions) {
    return actions.order.capture().then(function(details) {
      // Pass to Bubble via Toolbox or custom state
      console.log('Transaction completed by ' + details.payer.name.given_name);
    });
  }
}).render('#paypal-button-container');
</script>
```

**Expected result:** A PayPal button renders on the page that opens PayPal checkout when clicked.

### 3. Pass payment data back to Bubble workflows

Use the Toolbox plugin's 'JavaScript to Bubble' element to bridge PayPal's JavaScript callback with Bubble workflows. Create a JavascriptToBubble element with a trigger name like 'paypal_complete'. In the onApprove callback, call bubble_fn_paypal_complete(JSON.stringify(details)). Create a workflow on the JavascriptToBubble element that creates a Payment record with transaction_id, payer_email, amount, and status from the parsed JSON.

**Expected result:** Payment completion data flows from PayPal's JavaScript into a Bubble workflow that records the transaction.

### 4. Verify payments server-side via API

For security, verify the payment on the server. Set up an API Connector call to PayPal's order details endpoint (GET https://api-m.paypal.com/v2/checkout/orders/ORDER_ID). Use OAuth authentication with your Client ID and Secret. After creating the Payment record, call this API to verify the amount and status match what the user reported. Only fulfill the order if the server-side verification confirms payment.

> Pro tip: Never trust client-side payment data alone. Always verify with PayPal's API server-side before fulfilling orders.

**Expected result:** Payments are verified server-side through PayPal's API before orders are fulfilled.

### 5. Set up PayPal webhooks for ongoing events

In the PayPal developer dashboard, navigate to Webhooks and add a webhook URL pointing to a Bubble backend API workflow. Subscribe to events like PAYMENT.CAPTURE.COMPLETED and PAYMENT.CAPTURE.REFUNDED. Create the backend workflow to process these events — update payment status, handle refunds, and notify users.

**Expected result:** PayPal sends real-time event notifications to your Bubble backend for payment status changes.

## Complete code example

File: `Workflow summary`

```text
PAYPAL INTEGRATION — WORKFLOW SUMMARY
=======================================

CREDENTIALS:
  Client ID: used in HTML button embed
  Secret: API Connector private parameter
  Sandbox for testing, Live for production

BUTTON EMBED (HTML element):
  PayPal SDK → Smart Payment Buttons
  createOrder: set amount
  onApprove: capture + pass to Bubble

PAYMENT RECORDING:
  JavascriptToBubble → trigger workflow
  Create Payment record:
    transaction_id, amount, payer_email, status

SERVER VERIFICATION:
  API Connector → GET PayPal order details
  Verify amount + status match
  Only fulfill order if verified

WEBHOOKS:
  PayPal dashboard → add webhook URL
  Backend workflow processes events
  Handle: completed, refunded, disputed
```

## Common mistakes

- **Trusting client-side payment data without server verification** — Users can modify JavaScript to report fake payments — client data is not trustworthy Fix: Always verify payments server-side via PayPal's order details API before fulfilling orders
- **Using the PayPal Secret in client-side JavaScript** — The Secret key in client code is visible to all users and can be used to issue refunds or access your account Fix: Keep the Secret only in API Connector private parameters and server-side backend workflows
- **Not testing with PayPal Sandbox before going live** — Untested integrations can charge real money for broken flows or fail on production Fix: Always test the full payment flow with Sandbox credentials and test accounts before switching to Live

## Best practices

- Verify all payments server-side before fulfilling orders
- Use Sandbox credentials for development and testing
- Store PayPal Secret as a private API Connector parameter
- Set up webhooks for real-time payment event processing
- Create Payment records for every transaction as an audit trail
- Handle edge cases: cancelled payments, failed captures, disputes
- Display clear payment status to users after checkout

## Frequently asked questions

### Can I use PayPal alongside Stripe in the same app?

Yes. Many apps offer both options. Display PayPal and Stripe buttons on checkout and let the user choose their preferred payment method.

### Does PayPal charge transaction fees?

Yes. PayPal charges 2.9% + $0.30 per domestic transaction. International transactions have higher fees. Check PayPal's current pricing page for details.

### Can I accept PayPal without a Business account?

No. PayPal's REST API and Smart Payment Buttons require a PayPal Business account. Personal accounts cannot receive payments through API integrations.

### How do I handle PayPal refunds from Bubble?

Use the API Connector to call PayPal's refund endpoint. Pass the capture ID and refund amount. Update the Payment record status to 'refunded' after a successful API response.

### Can RapidDev help integrate payment processing in my Bubble app?

Yes. RapidDev can integrate PayPal, Stripe, and other payment providers with proper verification, webhook handling, and transaction management in Bubble.

---

Source: https://www.rapidevelopers.com/bubble-tutorial/implement-paypal-integration-in-bubble
© RapidDev — https://www.rapidevelopers.com/bubble-tutorial/implement-paypal-integration-in-bubble
