Stripe Integration ​
Bridge Payments provides seamless integration with Stripe, the world's leading payment processing platform.
Overview ​
Stripe integration supports:
- ✅ Payment Intents - One-time payments with 3D Secure support
- ✅ Payment Methods - Tokenized card storage (PCI compliant)
- ✅ Subscriptions - Recurring billing with trials
- ✅ Payment Elements - Modern, customizable payment UI
- ✅ Webhooks - Real-time event notifications
- ✅ 3D Secure - Strong Customer Authentication (SCA)
- ✅ Apple Pay & Google Pay - Digital wallet support
- ✅ Multi-Currency - 135+ currencies supported
Configuration ​
1. Get Stripe API Keys ​
- Sign up at stripe.com
- Navigate to Developers → API Keys
- Copy your Publishable Key and Secret Key
2. Configure Bridge Payments ​
In your Bridge Payments instance (Pubflow dashboard):
bash
# Stripe API Keys
STRIPE_SECRET_KEY=sk_test_... # or sk_live_... for production
STRIPE_PUBLISHABLE_KEY=pk_test_... # or pk_live_... for production
# Webhook Secret (optional, for webhook verification)
STRIPE_WEBHOOK_SECRET=whsec_...3. Configure Webhooks ​
Set up webhook endpoint in Stripe dashboard:
Webhook URL:
https://your-instance.pubflow.com/bridge-payment/webhooks/stripeEvents to Subscribe:
payment_intent.succeededpayment_intent.failedpayment_intent.canceledpayment_method.attachedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedinvoice.payment_succeededinvoice.payment_failed
Payment Flows ​
One-Time Payment ​
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": "stripe",
"concept": "Premium Plan"
}'Response:
json
{
"id": "pay_123",
"client_secret": "pi_123_secret_abc",
"status": "requires_confirmation",
"total_cents": 2000,
"currency": "USD"
}Step 2: Confirm Payment (Frontend) ​
javascript
import { loadStripe } from '@stripe/stripe-js';
const stripe = await loadStripe('pk_test_...');
const { error, paymentIntent } = await stripe.confirmCardPayment(
clientSecret,
{
payment_method: {
card: cardElement,
billing_details: {
name: 'John Doe',
email: 'john@example.com'
}
}
}
);
if (error) {
console.error('Payment failed:', error.message);
} else if (paymentIntent.status === 'succeeded') {
console.log('Payment successful!');
}Step 3: Sync Status (Backend) ​
bash
curl -X POST "https://your-instance.pubflow.com/bridge-payment/payments/intents/pay_123/sync" \
-H "X-Session-ID: session_abc123"Payment with Saved Method ​
Step 1: Create Payment Method ​
bash
curl -X POST "https://your-instance.pubflow.com/bridge-payment/payment-methods" \
-H "Content-Type: application/json" \
-H "X-Session-ID: session_abc123" \
-d '{
"provider_id": "stripe",
"provider_payment_method_token": "pm_1234567890",
"alias": "My Visa Card"
}'Step 2: Create Payment with Method ​
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": "stripe",
"payment_method_id": "pm_123",
"concept": "Monthly Subscription"
}'Step 3: Confirm Payment ​
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" \
-d '{
"payment_method_id": "pm_123"
}'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",
"payment_method_id": "pm_123",
"provider_id": "stripe",
"total_cents": 2000,
"currency": "USD",
"billing_interval": "monthly",
"trial_days": 14,
"concept": "Premium Monthly Plan"
}'Frontend Integration ​
React with Stripe Elements ​
jsx
import { useState, useEffect } from 'react';
import { loadStripe } from '@stripe/stripe-js';
import {
Elements,
PaymentElement,
useStripe,
useElements
} from '@stripe/react-stripe-js';
const stripePromise = loadStripe('pk_test_...');
function CheckoutForm({ paymentIntentId }) {
const stripe = useStripe();
const elements = useElements();
const [error, setError] = useState(null);
const [processing, setProcessing] = useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
if (!stripe || !elements) return;
setProcessing(true);
const { error, paymentIntent } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: `${window.location.origin}/success`
},
redirect: 'if_required'
});
if (error) {
setError(error.message);
setProcessing(false);
} else if (paymentIntent.status === 'succeeded') {
// Sync with backend
await fetch(`/bridge-payment/payments/intents/${paymentIntentId}/sync`, {
method: 'POST',
headers: {
'X-Session-ID': sessionId
}
});
// Redirect to success page
window.location.href = '/success';
}
};
return (
<form onSubmit={handleSubmit}>
<PaymentElement />
{error && <div className="error">{error}</div>}
<button disabled={!stripe || processing}>
{processing ? 'Processing...' : 'Pay Now'}
</button>
</form>
);
}
function PaymentPage({ amount }) {
const [clientSecret, setClientSecret] = useState('');
const [paymentIntentId, setPaymentIntentId] = useState('');
useEffect(() => {
// Create payment intent
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: 'stripe'
})
})
.then(res => res.json())
.then(data => {
setClientSecret(data.client_secret);
setPaymentIntentId(data.id);
});
}, [amount]);
return (
<div>
{clientSecret && (
<Elements stripe={stripePromise} options={{ clientSecret }}>
<CheckoutForm paymentIntentId={paymentIntentId} />
</Elements>
)}
</div>
);
}
export default PaymentPage;React Native with Stripe ​
jsx
import { useStripe } from '@stripe/stripe-react-native';
function PaymentScreen() {
const { confirmPayment } = useStripe();
const [loading, setLoading] = useState(false);
const handlePayment = async () => {
setLoading(true);
// Create payment intent
const response = await 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: 2000,
currency: 'USD',
provider_id': 'stripe'
})
}
);
const { client_secret, id } = await response.json();
// Confirm payment
const { error, paymentIntent } = await confirmPayment(client_secret, {
paymentMethodType: 'Card'
});
if (error) {
Alert.alert('Error', error.message);
} else if (paymentIntent.status === 'Succeeded') {
// Sync with backend
await fetch(
`https://your-instance.pubflow.com/bridge-payment/payments/intents/${id}/sync`,
{
method: 'POST',
headers: { 'X-Session-ID': sessionId }
}
);
Alert.alert('Success', 'Payment completed!');
}
setLoading(false);
};
return (
<View>
<Button
title={loading ? 'Processing...' : 'Pay $20.00'}
onPress={handlePayment}
disabled={loading}
/>
</View>
);
}Features ​
3D Secure (SCA) ​
Stripe automatically handles 3D Secure authentication:
javascript
const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret);
if (error) {
// Handle error
} else if (paymentIntent.status === 'requires_action') {
// Stripe will automatically show 3D Secure modal
const { error: actionError } = await stripe.handleCardAction(clientSecret);
if (!actionError) {
// Authentication successful
}
}Apple Pay & Google Pay ​
Enable digital wallets in Payment Element:
javascript
const elements = stripe.elements({
clientSecret,
appearance: { theme: 'stripe' }
});
const paymentElement = elements.create('payment', {
wallets: {
applePay: 'auto',
googlePay: 'auto'
}
});Multi-Currency ​
Stripe supports 135+ currencies:
bash
curl -X POST "/bridge-payment/payments/intents" \
-d '{
"total_cents": 2000,
"currency": "EUR", # or GBP, JPY, CAD, etc.
"provider_id": "stripe"
}'Testing ​
Test Cards ​
| Card Number | Description |
|---|---|
4242424242424242 | Successful payment |
4000002500003155 | Requires 3D Secure |
4000000000009995 | Declined (insufficient funds) |
4000000000000002 | Declined (generic) |
Expiration: Any future date (e.g., 12/25)
CVC: Any 3 digits (e.g., 123)
Test Mode ​
Use test API keys for development:
bash
STRIPE_SECRET_KEY=sk_test_...
STRIPE_PUBLISHABLE_KEY=pk_test_...Best Practices ​
- Use Payment Elements - Modern, customizable UI
- Enable Webhooks - Handle async events reliably
- Verify Signatures - Validate webhook authenticity
- Handle 3D Secure - Support SCA requirements
- Test Thoroughly - Use test cards before going live
- Monitor Dashboard - Track payments and disputes
Next Steps ​
- Payments API - Complete API reference
- Payment Methods API - Manage saved cards
- Subscriptions API - Recurring billing
- Webhooks API - Event handling