Paycose Docs
Setup

Authentication

How to authenticate to the PaymentGateway API — secret keys, OAuth bearer tokens, test/live mode, and required headers.

PaymentGateway supports three ways to authenticate, depending on what you're building. All of them are sent in the Authorization header.

MethodUse caseprivilege
Secret key (HTTP Basic)Server-to-server integrationsmachine
OAuth 2.0 bearer tokenDashboard / user-facing appsuser / superuser
One-time sessionHosted checkout & anonymous pay—

Secret key (server-to-server)

Examples below use $WALLET for the API base — {base_url}/api/v1/{app}/platform/wallet (e.g. http://localhost:5002/api/v1/app1/platform/wallet). See Quick guide.

Send your secret key as the username in HTTP Basic auth, with an empty password:

curl "$WALLET/charges" \
  -u "${SECRET_KEY}:"

Equivalently, build the header yourself:

const auth = "Basic " + btoa(`${SECRET_KEY}:`);
// Authorization: Basic c2tfdGVzdF8uLi46

Keep secret keys server-side only — never ship them in browser or mobile code. For client-side payment collection, use the publishable key and the checkout SDK (see the public-key model).

OAuth 2.0 bearer token (user apps)

User-facing apps (the dashboard and admin panels) authenticate end users through Ory — Kratos for identity/login and Hydra as the OAuth 2.0 server — then call the API with the resulting access token:

curl "$WALLET/oauth/me" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

The high-level flow is: redirect to Hydra's /oauth2/auth → user logs in via Kratos → Hydra returns an authorization code to your callback → exchange the code at POST /oauth/token for an access + refresh token.

Token lifetimes

TokenLifetime
Access token12 hours
Refresh token30 days
Authorization code10 minutes

Refresh before the access token expires (e.g. every 11 hours) via POST /oauth/token/refresh. Refresh tokens may be rotated on each use — always store the newly returned refresh token.

One-time session (checkout)

Hosted checkout and anonymous "pay" links use a short-lived one-time session so a buyer can complete a single payment without a full account. The checkout SDK manages this session for you — you do not handle the credential directly. See the Checkout SDK guides for integration details.

Required request headers

HeaderWhenPurpose
AuthorizationAlwaysBasic … (secret key) or Bearer … (access token)
X-Test-ModeOptionaltrue for sandbox, omit/false for live — see below
X-CountrySome endpointsTwo-letter country code (e.g. TH) for multi-country apps
Content-TypePOST / PATCHapplication/json

Test vs live mode

Test and live data are stored in separate database schemas (wallet_test / wallet_live), so test activity can never touch live money. Select the schema per request with the X-Test-Mode header:

curl "$WALLET/charges" \
  -u "${SECRET_KEY}:" \
  -H "X-Test-Mode: true"

Every response includes a livemode boolean reflecting the schema the data came from, so you can always verify which environment you hit:

{ "id": "chg_123", "object": "charge", "livemode": false }

Public vs secret keys

PaymentGateway uses a session-driven key model rather than hardcoded client keys: the secret key authenticates server-side calls, while client-side payment collection (hosted checkout or the embeddable SDK) is driven by a checkout session and the publishable key — no secret material in the browser. See the checkout SDK guides for the full integration.

Common authentication errors

These arrive in the standard error envelope:

CodeHTTPMeaning
E1200401Authentication required
E1210401Invalid bearer token
E1211401Invalid or inactive secret key
E1212401Invalid one-time session
E1213401Missing authentication headers
E1300403Insufficient permissions
E1303 / E1304403KYC / KYB verification required

On 401, refresh your token (bearer flow) or re-check your key; on repeated failure, restart the login flow.

On this page