Skip to content

Authentication API ​

Bridge Payments supports multiple authentication methods for both authenticated users and guest checkout flows.

Authentication Methods ​

1. Session-Based Authentication (Authenticated Users) ​

For users with active sessions in your Flowless backend.

bash
curl -X GET "https://your-instance.pubflow.com/bridge-payment/payments" \
  -H "X-Session-ID: 1dc72119bc5eb3a74bfda3d73da59a5f71b1086a" \
  -H "Content-Type: application/json"

JavaScript Example:

javascript
const response = await fetch('/bridge-payment/payments', {
  headers: {
    'X-Session-ID': sessionId,
    'Content-Type': 'application/json'
  }
});

Method B: Authorization Bearer Header ​

bash
curl -X GET "https://your-instance.pubflow.com/bridge-payment/payments" \
  -H "Authorization: Bearer 1dc72119bc5eb3a74bfda3d73da59a5f71b1086a" \
  -H "Content-Type": application/json"

JavaScript Example:

javascript
const response = await fetch('/bridge-payment/payments', {
  headers: {
    'Authorization': `Bearer ${sessionId}`,
    'Content-Type': 'application/json'
  }
});

Method C: Query Parameter ​

bash
curl -X GET "https://your-instance.pubflow.com/bridge-payment/payments?session_id=1dc72119bc5eb3a74bfda3d73da59a5f71b1086a"

JavaScript Example:

javascript
const response = await fetch(`/bridge-payment/payments?session_id=${sessionId}`);

When to Use Query Parameters

Query parameters are useful for:

  • Simple GET requests from browsers
  • URL-based authentication for webhooks
  • Testing and debugging scenarios
  • Applications with limited header control

2. Guest Token Authentication ​

For guest users who completed a checkout and need to access their data later.

How Guest Tokens Work ​

  1. Guest Checkout: User completes payment with guest_data (email, name)
  2. Token Generation: Your Flowless backend generates a token linked to the guest's email
  3. Token Usage: Guest uses token to access their payments, payment methods, etc.
  4. Token Validation: Bridge Payments validates the token with Flowless and retrieves the guest's email

The recommended way to authenticate guest users is using the X-Guest-Token header:

bash
# List guest's payments
curl -X GET "https://your-instance.pubflow.com/bridge-payment/payments" \
  -H "X-Guest-Token: guest_token_abc123"

# Create a new address (POST request)
curl -X POST "https://your-instance.pubflow.com/bridge-payment/addresses" \
  -H "X-Guest-Token: guest_token_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "address_type": "billing",
    "name": "Guest User",
    "line1": "123 Main St",
    "city": "New York",
    "postal_code": "10001",
    "country": "US"
  }'

# Update payment method (PUT request)
curl -X PUT "https://your-instance.pubflow.com/bridge-payment/payment-methods/pm_123" \
  -H "X-Guest-Token: guest_token_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "alias": "My Visa Card",
    "is_default": true
  }'

# Delete payment method (DELETE request)
curl -X DELETE "https://your-instance.pubflow.com/bridge-payment/payment-methods/pm_123" \
  -H "X-Guest-Token: guest_token_abc123"

JavaScript Example:

javascript
// List all payments for this guest
const paymentsResponse = await fetch('/bridge-payment/payments', {
  headers: {
    'X-Guest-Token': guestToken
  }
});
const payments = await paymentsResponse.json();

// Create a new address (POST request)
const addressResponse = await fetch('/bridge-payment/addresses', {
  method: 'POST',
  headers: {
    'X-Guest-Token': guestToken,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    address_type: 'billing',
    name: 'Guest User',
    line1: '123 Main St',
    city: 'New York',
    postal_code: '10001',
    country: 'US'
  })
});

// Update payment method (PUT request)
const updateResponse = await fetch(`/bridge-payment/payment-methods/${methodId}`, {
  method: 'PUT',
  headers: {
    'X-Guest-Token': guestToken,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    alias: 'My Visa Card',
    is_default: true
  })
});

React Native Example:

typescript
// Store token after guest checkout
import AsyncStorage from '@react-native-async-storage/async-storage';

// After successful guest payment
await AsyncStorage.setItem('guest_payment_token', guestToken);

// Later, retrieve guest's data
const token = await AsyncStorage.getItem('guest_payment_token');
const response = await fetch(`${BRIDGE_URL}/bridge-payment/payments`, {
  headers: {
    'X-Guest-Token': token
  }
});
const { data } = await response.json();

Why Use X-Guest-Token Header?

  • ✅ More Secure: Headers are not logged in browser history or server logs
  • ✅ Cleaner URLs: No sensitive tokens in the URL
  • ✅ Works with All HTTP Methods: GET, POST, PUT, DELETE, PATCH
  • ✅ Consistent Pattern: Matches X-Session-ID for authenticated users
  • ✅ Better Developer Experience: Clear separation between authenticated and guest users

Method B: Authorization Token Header ​

bash
curl -X POST "https://your-instance.pubflow.com/bridge-payment/addresses" \
  -H "Authorization: Token guest_token_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "address_type": "billing",
    "name": "Guest User",
    "line1": "123 Main St",
    "city": "New York",
    "postal_code": "10001",
    "country": "US"
  }'

JavaScript Example:

javascript
const response = await fetch('/bridge-payment/addresses', {
  method: 'POST',
  headers: {
    'Authorization': `Token ${guestToken}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    address_type: 'billing',
    name: 'Guest User',
    line1: '123 Main St',
    city: 'New York',
    postal_code: '10001',
    country: 'US'
  })
});

Method C: Query Parameter (Fallback) ✨ IMPROVED ​

Query parameters now work with all HTTP methods (previously only GET):

bash
# GET request
curl -X GET "https://your-instance.pubflow.com/bridge-payment/payments?token=guest_token_abc123"

# POST request (now supported!)
curl -X POST "https://your-instance.pubflow.com/bridge-payment/addresses?token=guest_token_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "address_type": "billing",
    "name": "Guest User",
    "line1": "123 Main St",
    "city": "New York",
    "postal_code": "10001",
    "country": "US"
  }'

# PUT request (now supported!)
curl -X PUT "https://your-instance.pubflow.com/bridge-payment/payment-methods/pm_123?token=guest_token_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "alias": "My Visa Card",
    "is_default": true
  }'

# DELETE request (now supported!)
curl -X DELETE "https://your-instance.pubflow.com/bridge-payment/payment-methods/pm_123?token=guest_token_abc123"

JavaScript Example:

javascript
// GET request
const paymentsResponse = await fetch(
  `/bridge-payment/payments?token=${guestToken}`
);

// POST request (now works!)
const addressResponse = await fetch(
  `/bridge-payment/addresses?token=${guestToken}`,
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      address_type: 'billing',
      name: 'Guest User',
      line1: '123 Main St',
      city: 'New York',
      postal_code: '10001',
      country: 'US'
    })
  }
);

// PUT request (now works!)
const updateResponse = await fetch(
  `/bridge-payment/payment-methods/${methodId}?token=${guestToken}`,
  {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      alias: 'My Visa Card',
      is_default: true
    })
  }
);

Query Parameter Security Considerations

While query parameters now work with all HTTP methods, they are less secure than headers:

  • ⚠️ May be logged in server logs
  • ⚠️ May appear in browser history
  • ⚠️ May be cached by proxies
  • ⚠️ Visible in URLs (can be shared accidentally)

Recommendation: Use X-Guest-Token header whenever possible. Use query parameters only when headers are not available (e.g., simple links, email links, etc.).

What Can Guests Access with Tokens?

With a valid guest token, users can:

Read Operations (GET):

  • ✅ List their payments
  • ✅ View payment details
  • ✅ List their saved payment methods
  • ✅ View payment method details
  • ✅ List their addresses
  • ✅ View address details

Write Operations (POST/PUT/DELETE): ✨ NEW - Now works with all authentication methods

  • ✅ Create new addresses
  • ✅ Update payment method details
  • ✅ Delete payment methods
  • ✅ Update addresses
  • ✅ Delete addresses

Limitations:

  • ❌ Cannot create new payments (use guest_data in request body instead)
  • ❌ Cannot access other users' data (filtered by guest email)
  • ❌ Cannot perform admin operations

Token Validation Flow ​

When a guest token is provided:

  1. Primary Validation: Bridge Payments calls Flowless /auth/token/validate?token=xxx
  2. Extract Email: Gets the guest's email from the validation response
  3. Filter Data: Returns only data where guest_email matches the token's email
  4. Fallback Validation: For PUT/DELETE, if primary validation fails, tries to find email by token in payment history
javascript
// Example: Flowless token validation response
{
  "success": true,
  "user": {
    "id": "guest_user_123",
    "email": "[email protected]",  // ← This email is used to filter data
    "name": "Guest User",
    "userType": "guest",
    "isVerified": true
  },
  "tokenType": "token_login",
  "token_id": "tok_abc123",
  "expires_at": "2025-06-05T03:34:29.000Z"
}

3. Guest Data (No Authentication Required) ​

For creating payments without any authentication (guest checkout).

bash
curl -X POST "https://your-instance.pubflow.com/bridge-payment/payments/intents" \
  -H "Content-Type: application/json" \
  -d '{
    "total_cents": 2000,
    "currency": "USD",
    "provider_id": "stripe",
    "guest_data": {
      "email": "[email protected]",
      "name": "Guest User",
      "phone": "+1234567890"
    }
  }'

JavaScript Example:

javascript
const response = await fetch('/bridge-payment/payments/intents', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    total_cents: 2000,
    currency: 'USD',
    provider_id: 'stripe',
    guest_data: {
      email: '[email protected]',
      name: 'Guest User'
    }
  })
});

Authentication Priority Order ​

When multiple authentication methods are provided, the system checks them in this order:

  1. Authorization Header (Bearer <session> or Token <guest_token>)
  2. X-Session-ID Header (authenticated users)
  3. X-Guest-Token Header (guest users) ✨ NEW
  4. session_id Query Parameter (authenticated users fallback)
  5. token Query Parameter (guest users fallback) ✨ IMPROVED - Now works with all HTTP methods

TIP

Only the first valid authentication method found will be used. Headers are checked before query parameters for better security.

Authentication Method Comparison ​

MethodTypePriorityHTTP MethodsSecurityRecommended
Authorization: BearerSession1All⭐⭐⭐✅ Yes
Authorization: TokenGuest1All⭐⭐⭐✅ Yes
X-Session-IDSession2All⭐⭐⭐✅ Yes (Primary)
X-Guest-TokenGuest3All⭐⭐⭐✅ Yes (Primary)
?session_id=Session4All⭐⭐⚠️ Fallback only
?token=Guest5All⭐⭐⚠️ Fallback only

Session Validation ​

Validate Session ​

Bridge Payments validates sessions against your Flowless backend:

Validation Endpoint (Flowless):

http
POST /auth/bridge/validate
Content-Type: application/json

{
  "sessionId": "1dc72119bc5eb3a74bfda3d73da59a5f71b1086a"
}

Response:

json
{
  "success": true,
  "user": {
    "id": "user_123",
    "email": "[email protected]",
    "name": "John Doe",
    "userType": "user",
    "firstName": "John",
    "lastName": "Doe",
    "isVerified": true
  },
  "session": {
    "id": "1dc72119bc5eb3a74bfda3d73da59a5f71b1086a",
    "userId": "user_123",
    "expiresAt": "2025-07-07T02:55:17.864Z"
  }
}

Validate Guest Token ​

Validation Endpoint (Flowless):

http
GET /auth/token/validate?token=guest_token_abc123

Response:

json
{
  "success": true,
  "user": {
    "id": "guest_user_123",
    "email": "[email protected]",
    "name": "Guest User",
    "userType": "guest",
    "isVerified": true
  },
  "tokenType": "token_login",
  "token_id": "tok_abc123",
  "expires_at": "2025-06-05T03:34:29.000Z"
}

Complete Guest Checkout Flow with Tokens ​

Here's the complete flow for guest checkout with token-based access:

Step 1: Guest Creates Payment (No Auth Required) ​

javascript
// Guest completes checkout without authentication
const response = await fetch('/bridge-payment/payments/intents', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
    // No authentication needed!
  },
  body: JSON.stringify({
    total_cents: 5000,
    currency: 'USD',
    concept: 'Product Purchase',
    provider_id: 'stripe',
    guest_data: {
      email: '[email protected]',  // ← Guest's email
      name: 'John Doe'
    }
  })
});

const { data } = await response.json();
// Payment created with guest_email = '[email protected]'

Step 2: Your Backend Generates Guest Token ​

After successful payment, your Flowless backend generates a token:

javascript
// Your backend (Flowless)
import { generateGuestToken } from './auth';

// Generate token linked to guest email
const guestToken = await generateGuestToken({
  email: '[email protected]',
  name: 'John Doe',
  expiresIn: 3600 // 1 hour
});

// Return token to frontend
return {
  success: true,
  token: guestToken,  // ← Send this to the guest
  message: 'Payment successful! Use this token to view your order.'
};

Step 3: Guest Uses Token to Access Their Data ​

Recommended: Using X-Guest-Token Header

javascript
// Guest can now view their payments
const paymentsResponse = await fetch('/bridge-payment/payments', {
  headers: {
    'X-Guest-Token': guestToken
  }
});
const { data: payments } = await paymentsResponse.json();
// Returns only payments where guest_email = '[email protected]'

// Guest can view their saved payment methods
const methodsResponse = await fetch('/bridge-payment/payment-methods', {
  headers: {
    'X-Guest-Token': guestToken
  }
});
const { data: paymentMethods } = await methodsResponse.json();
// Returns only payment methods where guest_email = '[email protected]'

// Guest can update their payment method (PUT request now works!)
const updateResponse = await fetch(
  `/bridge-payment/payment-methods/${methodId}`,
  {
    method: 'PUT',
    headers: {
      'X-Guest-Token': guestToken,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      alias: 'My Visa Card',
      is_default: true
    })
  }
);

// Guest can create a new address (POST request now works!)
const addressResponse = await fetch('/bridge-payment/addresses', {
  method: 'POST',
  headers: {
    'X-Guest-Token': guestToken,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    address_type: 'shipping',
    name: 'John Doe',
    line1: '456 Oak Ave',
    city: 'Los Angeles',
    postal_code: '90001',
    country: 'US'
  })
});

Alternative: Using Query Parameter (Less Secure)

javascript
// GET request
const paymentsResponse = await fetch(
  `/bridge-payment/payments?token=${guestToken}`
);

// POST request (now works!)
const addressResponse = await fetch(
  `/bridge-payment/addresses?token=${guestToken}`,
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      address_type: 'shipping',
      name: 'John Doe',
      line1: '456 Oak Ave',
      city: 'Los Angeles',
      postal_code: '90001',
      country: 'US'
    })
  }
);

Step 4: Store Token for Later Use ​

React Native - Store token in AsyncStorage

javascript
import AsyncStorage from '@react-native-async-storage/async-storage';

// Store token after successful payment
await AsyncStorage.setItem('guest_payment_token', guestToken);

// Later, retrieve and use with X-Guest-Token header (recommended)
const token = await AsyncStorage.getItem('guest_payment_token');
const response = await fetch(`${BRIDGE_URL}/bridge-payment/payments`, {
  headers: {
    'X-Guest-Token': token
  }
});
const { data } = await response.json();

Web - Store token in localStorage

javascript
// Store token after successful payment
localStorage.setItem('guest_payment_token', guestToken);

// Later, retrieve and use with X-Guest-Token header (recommended)
const token = localStorage.getItem('guest_payment_token');
const response = await fetch('/bridge-payment/payments', {
  headers: {
    'X-Guest-Token': token
  }
});
const { data } = await response.json();

Security Considerations ​

Session-Based Authentication (Authenticated Users) ​

  • ✅ Use X-Session-ID header for best security
  • ✅ Sessions are validated on every request
  • ✅ Sessions can be revoked server-side
  • ✅ Supports full user context (user_id, organization_id, etc.)
  • ✅ Works with all HTTP methods (GET, POST, PUT, DELETE, PATCH)

Guest Token Authentication ​

  • ✅ NEW: Use X-Guest-Token header for best security
  • ✅ Tokens are validated against Flowless on each request
  • ✅ Tokens are filtered by guest_email for security
  • ✅ IMPROVED: Now works with all HTTP methods (POST, PUT, DELETE, PATCH)
  • ⚠️ Tokens are temporary (default: 1 hour, configurable)
  • ⚠️ Tokens are tied to a specific email address
  • ⚠️ Tokens cannot be revoked (until expiration)
  • ⚠️ Tokens provide access to guest's own data only

Authentication Method Security Ranking ​

Most Secure (Recommended):

  1. X-Session-ID header (authenticated users)
  2. X-Guest-Token header (guest users) ✨ NEW
  3. Authorization: Bearer header (authenticated users)
  4. Authorization: Token header (guest users)

Less Secure (Use with Caution): 5. ?session_id= query parameter (authenticated users) 6. ?token= query parameter (guest users)

Why Headers are More Secure:

  • ✅ Not logged in browser history
  • ✅ Not logged in most server access logs
  • ✅ Not cached by proxies
  • ✅ Not visible in URLs (can't be shared accidentally)
  • ✅ Not exposed in referrer headers

When to Use Query Parameters:

  • ⚠️ Simple GET requests from browsers
  • ⚠️ Email links (e.g., "View your order")
  • ⚠️ URL-based authentication for webhooks
  • ⚠️ Testing and debugging scenarios
  • ⚠️ Applications with limited header control

Guest Data (No Authentication) ​

  • ⚠️ Only for creating new payments
  • ⚠️ No access to existing data
  • ⚠️ Cannot list or view previous payments
  • ✅ Simplest checkout flow
  • ✅ No account required

Next Steps ​