Skip to content

PayPal Integration ​

Bridge Payments provides seamless integration with PayPal, supporting both PayPal accounts and card payments (including Venmo).

Overview ​

PayPal integration supports:

  • ✅ PayPal Checkout - Pay with PayPal account
  • ✅ Card Payments - Credit/debit cards via PayPal
  • ✅ Venmo - Pay with Venmo (US only)
  • ✅ Subscriptions - Recurring billing
  • ✅ Guest Checkout - No PayPal account required
  • ✅ Multi-Currency - 25+ currencies supported
  • ✅ Webhooks - Real-time event notifications

Configuration ​

1. Get PayPal API Credentials ​

  1. Sign up at developer.paypal.com
  2. Create a REST API app
  3. Copy your Client ID and Secret

2. Configure Bridge Payments ​

In your Bridge Payments instance (Pubflow dashboard):

bash
# PayPal API Credentials
PAYPAL_CLIENT_ID=your_client_id
PAYPAL_CLIENT_SECRET=your_client_secret

# Environment (sandbox or live)
PAYPAL_MODE=sandbox # or "live" for production

# Webhook ID (optional, for webhook verification)
PAYPAL_WEBHOOK_ID=your_webhook_id

3. Configure Webhooks ​

Set up webhook endpoint in PayPal dashboard:

Webhook URL:

https://your-instance.pubflow.com/bridge-payment/webhooks/paypal

Events to Subscribe:

  • PAYMENT.CAPTURE.COMPLETED
  • PAYMENT.CAPTURE.DENIED
  • PAYMENT.CAPTURE.REFUNDED
  • BILLING.SUBSCRIPTION.CREATED
  • BILLING.SUBSCRIPTION.UPDATED
  • BILLING.SUBSCRIPTION.CANCELLED
  • BILLING.SUBSCRIPTION.PAYMENT.FAILED

Payment Flows ​

PayPal Checkout ​

Step 1: Create Payment Intent ​

bash
curl -X POST "https://your-instance.pubflow.com/bridge-payment/payments/intents" \
  -H "Content-Type: application/json" \
  -H "X-Session-ID: session_abc123" \
  -d '{
    "total_cents": 2000,
    "currency": "USD",
    "provider_id": "paypal",
    "concept": "Premium Plan",
    "return_url": "https://yourapp.com/success",
    "cancel_url": "https://yourapp.com/cancel"
  }'

Response:

json
{
  "id": "pay_123",
  "provider_payment_id": "PAYPAL-ORDER-ID",
  "status": "requires_confirmation",
  "total_cents": 2000,
  "currency": "USD",
  "approval_url": "https://www.paypal.com/checkoutnow?token=..."
}

Step 2: Redirect to PayPal ​

javascript
// Redirect user to PayPal
window.location.href = approvalUrl;

Step 3: Capture Payment (After Return) ​

bash
curl -X POST "https://your-instance.pubflow.com/bridge-payment/payments/intents/pay_123/confirm" \
  -H "Content-Type: application/json" \
  -H "X-Session-ID: session_abc123"

Card Payment via PayPal ​

bash
curl -X POST "https://your-instance.pubflow.com/bridge-payment/payments/intents" \
  -H "Content-Type: application/json" \
  -H "X-Session-ID: session_abc123" \
  -d '{
    "total_cents": 2000,
    "currency": "USD",
    "provider_id": "paypal",
    "payment_source": "card",
    "card_number": "4111111111111111",
    "card_exp_month": "12",
    "card_exp_year": "2025",
    "card_cvc": "123",
    "concept": "Product Purchase"
  }'

Subscription ​

bash
curl -X POST "https://your-instance.pubflow.com/bridge-payment/subscriptions" \
  -H "Content-Type: application/json" \
  -H "X-Session-ID: session_abc123" \
  -d '{
    "customer_id": "cust_123",
    "provider_id": "paypal",
    "total_cents": 2000,
    "currency": "USD",
    "billing_interval": "monthly",
    "concept": "Premium Monthly Plan",
    "return_url": "https://yourapp.com/success"
  }'

Frontend Integration ​

React with PayPal SDK ​

jsx
import { PayPalScriptProvider, PayPalButtons } from '@paypal/react-paypal-js';

function PayPalCheckout({ amount }) {
  const [paymentIntentId, setPaymentIntentId] = useState('');

  const createOrder = async () => {
    // Create payment intent
    const response = await fetch('/bridge-payment/payments/intents', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Session-ID': sessionId
      },
      body: JSON.stringify({
        total_cents: amount,
        currency: 'USD',
        provider_id: 'paypal'
      })
    });

    const data = await response.json();
    setPaymentIntentId(data.id);
    return data.provider_payment_id; // PayPal Order ID
  };

  const onApprove = async (data) => {
    // Confirm payment
    await fetch(`/bridge-payment/payments/intents/${paymentIntentId}/confirm`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Session-ID': sessionId
      }
    });

    alert('Payment successful!');
  };

  return (
    <PayPalScriptProvider options={{ 'client-id': 'your_client_id' }}>
      <PayPalButtons
        createOrder={createOrder}
        onApprove={onApprove}
        onError={(err) => console.error('PayPal error:', err)}
      />
    </PayPalScriptProvider>
  );
}

React Native ​

jsx
import { WebView } from 'react-native-webview';

function PayPalPayment({ amount }) {
  const [approvalUrl, setApprovalUrl] = useState('');
  const [paymentIntentId, setPaymentIntentId] = useState('');

  useEffect(() => {
    // Create payment intent
    fetch('https://your-instance.pubflow.com/bridge-payment/payments/intents', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Session-ID': sessionId
      },
      body: JSON.stringify({
        total_cents: amount,
        currency: 'USD',
        provider_id: 'paypal',
        return_url: 'yourapp://payment/success',
        cancel_url: 'yourapp://payment/cancel'
      })
    })
      .then(res => res.json())
      .then(data => {
        setApprovalUrl(data.approval_url);
        setPaymentIntentId(data.id);
      });
  }, [amount]);

  const handleNavigationStateChange = async (navState) => {
    if (navState.url.includes('payment/success')) {
      // Confirm payment
      await fetch(
        `https://your-instance.pubflow.com/bridge-payment/payments/intents/${paymentIntentId}/confirm`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-Session-ID': sessionId
          }
        }
      );

      Alert.alert('Success', 'Payment completed!');
    }
  };

  return (
    <WebView
      source={{ uri: approvalUrl }}
      onNavigationStateChange={handleNavigationStateChange}
    />
  );
}

Features ​

Venmo Support ​

Enable Venmo for US customers:

bash
curl -X POST "/bridge-payment/payments/intents" \
  -d '{
    "total_cents": 2000,
    "currency": "USD",
    "provider_id": "paypal",
    "payment_source": "venmo",
    "return_url": "https://yourapp.com/success"
  }'

Multi-Currency ​

PayPal supports 25+ currencies:

bash
curl -X POST "/bridge-payment/payments/intents" \
  -d '{
    "total_cents": 2000,
    "currency": "EUR",  # or GBP, CAD, AUD, etc.
    "provider_id": "paypal"
  }'

Testing ​

Sandbox Accounts ​

Use PayPal Sandbox for testing:

  1. Create sandbox accounts at developer.paypal.com
  2. Use sandbox credentials in Bridge Payments:
bash
PAYPAL_MODE=sandbox
PAYPAL_CLIENT_ID=sandbox_client_id
PAYPAL_CLIENT_SECRET=sandbox_client_secret

Test Cards ​

Card NumberTypeResult
4111111111111111VisaSuccess
5555555555554444MastercardSuccess
378282246310005AmexSuccess

Expiration: Any future date
CVV: Any 3 digits (4 for Amex)

Best Practices ​

  1. Use Webhooks - Handle async events reliably
  2. Set Return URLs - Provide success/cancel URLs
  3. Test in Sandbox - Use sandbox mode for development
  4. Handle Errors - Gracefully handle payment failures
  5. Monitor Dashboard - Track payments and disputes

Next Steps ​