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