Authentication

Authentication

Overview

The SDK uses JWT token-based authentication to keep your API credentials secure. Instead of exposing your Client ID and Secret in browser code, tokens are generated server-side by your backend.


Why Token-Based Authentication?Security Benefits:

  • API credentials (Client ID/Secret) never leave your server

  • Tokens are scoped to specific customers and invoices

  • Tokens have limited lifetime, reducing exposure risk

  • Token refresh is handled automatically by the SDK***

Authentication Flow

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│  Your           │     │  Your           │     │  Alternative    │
│  Backend        │     │  Frontend       │     │  API            │
└────────┬────────┘     └────────┬────────┘     └────────┬────────┘
         │                       │                       │
         │  1. POST /v1/checkout-auth/init              │
         │  (with OAuth2 client credentials)            │
         │──────────────────────────────────────────────>│
         │                       │                       │
         │  2. Returns JWT token                        │
         │<──────────────────────────────────────────────│
         │                       │                       │
         │  3. Pass token to frontend                   │
         │──────────────────────>│                       │
         │                       │                       │
         │                       │  4. SDK uses token    │
         │                       │  for all API calls    │
         │                       │──────────────────────>│
         │                       │                       │
         │                       │  5. Token expires     │
         │                       │  onAccessTokenExpired │
         │                       │  callback triggered   │
         │                       │<─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│
         │                       │                       │
         │  6. Frontend requests │                       │
         │  new token            │                       │
         │<──────────────────────│                       │
         │                       │                       │
         │  7. New token returned│                       │
         │──────────────────────>│                       │
         │                       │                       │
         │                       │  8. SDK continues     │
         │                       │  with new token       │
         │                       │──────────────────────>│

Backend Implementation

Step 1: Get OAuth Token

First, exchange your Client ID and Secret for an OAuth access token:

Response:

Step 2: Generate Checkout Token

Use the OAuth token to generate a checkout token for a specific customer and invoice:

Response:

Complete Backend Example```typescript

import express from 'express';

const router = express.Router();

const CLIENT_ID = process.env.ALTERNATIVE_CLIENT_ID; const CLIENT_SECRET = process.env.ALTERNATIVE_CLIENT_SECRET; const API_BASE = 'https://public-api.alternativepayments.io';

// Cache OAuth token let oauthToken: { token: string; expiresAt: number } | null = null;

async function getOAuthToken(): Promise { // Return cached token if valid if (oauthToken && oauthToken.expiresAt > Date.now() + 60000) { return oauthToken.token; }

const response = await fetch(${API_BASE}/oauth/token, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': Basic ${Buffer.from(${CLIENT_ID}:${CLIENT_SECRET}).toString('base64')}, }, body: 'grant_type=client_credentials', });

const data = await response.json(); oauthToken = { token: data.access_token, expiresAt: Date.now() + data.expires_in * 1000, };

return data.access_token; }

router.post('/api/checkout-token', async (req, res) => { try { const { customerId, invoiceId } = req.body;

} catch (error) { console.error('Failed to generate checkout token:', error); res.status(500).json({ error: 'Failed to generate token' }); } });

export default router; </div><div data-gb-custom-block data-tag="tab" data-title='Python (FastAPI)'>python from fastapi import FastAPI, HTTPException from pydantic import BaseModel import httpx import os import base64 import time

app = FastAPI()

CLIENT_ID = os.environ["ALTERNATIVE_CLIENT_ID"] CLIENT_SECRET = os.environ["ALTERNATIVE_CLIENT_SECRET"] API_BASE = "https://public-api.alternativepayments.io"

Token cache

oauth_token = {"token": None, "expires_at": 0}

async def get_oauth_token() -> str: global oauth_token

class TokenRequest(BaseModel): customer_id: str invoice_id: str

@app.post("/api/checkout-token") async def generate_checkout_token(request: TokenRequest): try: access_token = await get_oauth_token()

Handle Token Expiration

Provide an onAccessTokenExpired callback to automatically refresh tokens:


Security Best Practices

  1. Never expose credentials in frontend code - Always generate tokens on your backend

  2. Use HTTPS - Ensure all communication is encrypted

  3. Validate on your backend - Verify the customer/invoice belongs to the authenticated user

  4. Set appropriate token lifetimes - Shorter lifetimes reduce exposure risk

  5. Implement the refresh callback - Provide a smooth experience when tokens expire


Token Contents

The checkout token is a JWT that contains:

Claim
Description

partner_id

Your partner identifier

client_id

Your API client ID

customer_id

The customer this token is scoped to

invoice_id

The invoice this token is scoped to

exp

Token expiration timestamp

Last updated

Was this helpful?