Skip to content
StraventaDocs
Guides

Authentication

Bearer JWT tokens, scopes, refresh token rotation, and OIDC client setup

Authentication

505pay uses Bearer JWTs issued by the /token endpoint. Tokens are short-lived and rotate on refresh.

Token vs. API key

Use OAuth /token for console / dashboard / OIDC flows where a human or admin app is acting on a user's behalf. Use a long-lived API key (sk_test_… / sk_live_…) for server-to-server merchant integrations like checkout intent creation and refunds. See the API keys guide for the API-key path.

How it works

  1. Your OIDC client presents client_id + client_secret (or user credentials) to /token.
  2. The server returns an access_token (JWT) and a refresh_token.
  3. Include the access token in every API request as Authorization: Bearer <token>.
  4. When the access token expires, use the refresh token to obtain a new pair. Refresh tokens are single-use — each use rotates to a new token.

Token endpoint

POST https://sandbox.505pay.link/token
Content-Type: application/x-www-form-urlencoded

Client credentials grant

Use this grant for server-to-server integrations where no end-user is involved.

curl -X POST https://sandbox.505pay.link/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=$CLIENT_ID" \
  -d "client_secret=$CLIENT_SECRET"
const params = new URLSearchParams({
  grant_type: 'client_credentials',
  client_id: process.env.CLIENT_ID!,
  client_secret: process.env.CLIENT_SECRET!,
});

const res = await fetch('https://sandbox.505pay.link/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: params,
});

const { access_token, refresh_token, expires_in } = await res.json();
import requests

r = requests.post('https://sandbox.505pay.link/token', data={
    'grant_type': 'client_credentials',
    'client_id': CLIENT_ID,
    'client_secret': CLIENT_SECRET,
})
data = r.json()
access_token = data['access_token']
refresh_token = data['refresh_token']
expires_in = data['expires_in']

Password grant

Use this grant when acting on behalf of a specific user.

curl -X POST https://sandbox.505pay.link/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=password" \
  -d "client_id=$CLIENT_ID" \
  -d "client_secret=$CLIENT_SECRET" \
  -d "username=$USER_EMAIL" \
  -d "password=$USER_PASSWORD"

Token response

{
  "access_token": "eyJ...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "def5..."
}
FieldDescription
access_tokenJWT to include in Authorization: Bearer header
token_typeAlways Bearer
expires_inSeconds until the access token expires (configurable per tenant)
refresh_tokenSingle-use token for obtaining a new access token pair

Refreshing tokens

When your access token expires, use the refresh token to obtain a new pair. The old refresh token is immediately invalidated — store the new one.

curl -X POST https://sandbox.505pay.link/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "client_id=$CLIENT_ID" \
  -d "client_secret=$CLIENT_SECRET" \
  -d "refresh_token=$REFRESH_TOKEN"

Refresh tokens are single-use. Using a refresh token more than once (replay attack) immediately invalidates the entire token family, requiring the user to re-authenticate.

Scopes

Scopes control what the access token is permitted to do. Request scopes using the scope parameter in your token request.

-d "scope=payments:read payments:write webhooks:manage"
ScopeDescription
payments:readList and retrieve payment records
payments:writeCreate and update payments
webhooks:manageRegister and manage webhook subscriptions
refunds:writeIssue refunds
reports:readAccess settlement and reconciliation reports
adminFull administrative access (tenant admin only)

OIDC client setup

  1. Log in to dashboard.505pay.link.
  2. Navigate to Settings → API Credentials → New Client.
  3. Choose Confidential (server-side) or Public (mobile / SPA) client type.
  4. Copy CLIENT_ID and CLIENT_SECRET — the secret is shown once at creation.
  5. Store credentials in environment variables, never in source code.

Token lifetime is configurable per tenant. Contact support to adjust the default if your use case requires longer-lived tokens.

Using the token

Pass the access token in the Authorization header on every request:

Authorization: Bearer eyJ...

Tokens older than expires_in seconds return 401 Unauthorized with error code token_expired. Refresh proactively rather than reactively to avoid dropped requests.

Was this page helpful?

On this page