Skip to content

Authentication

The Maytes merchant API uses OAuth 2.0 client credentials. Your server exchanges its client_id and client_secret for a short-lived access token, then sends that token as a Bearer credential on every request.

All calls are server-to-server. Never put your client_secret in browser or mobile code.

Environments

Maytes has two environments. Each has its own base URL and its own credentials (from the merchant portal). The production base URL — used by every example on this site — is:

https://api.maytes.co

Build against the sandbox first — an isolated environment where no real money moves — then switch your base URL and credentials to production to go live. The API shape is identical across both; only the host and credentials change. The sandbox base URL and test cards are in Sandbox environment.

Get your credentials

Your client_id and client_secret come from the Maytes merchant portal — a separate pair for each environment; use each pair against its matching base URL. Store them server-side (environment variables or a secret manager) — see Security.

In the portal, API credentials shows your client_id at any time. The client_secret is displayed only once — when your account is provisioned, and each time you rotate it — so store it when you see it.

The page is visible only to your merchant admin portal users; ask Maytes to grant admin access if your team needs it.

Rotating your client secret

Rotate from the portal's API credentials page if you've lost the secret or suspect it leaked. Rotation is immediate and has no grace window: the old secret stops working the moment you rotate, so deploy the new value to your servers right away. Access tokens you already hold keep working until they expire, which gives you a short buffer before the next token fetch needs the new secret.

Request an access token

bash
curl -s https://api.maytes.co/oauth/token \
  -H 'content-type: application/json' \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET"
  }'

The response contains an access_token. Send it on every merchant API call:

http
Authorization: Bearer <access_token>

Token lifetime, caching, and refresh

  • Access tokens are short-lived. Cache the token and reuse it across requests.
  • Don't compute expiry yourself. When a token expires, the API returns 401; fetch a new token and retry the request once.
  • This reactive "use until 401, then refresh and retry" pattern is exactly what the official backend SDKs implement for you — with one token cache shared across calls and safe concurrent refresh.

Use the SDK instead

If you use a backend SDK, you never touch /oauth/token directly. Construct the client once with your credentials and make calls — token fetch, caching, and 401-refresh are handled internally:

ts
import { createMaytesApiClient } from '@maytes/api-client';

const maytes = createMaytesApiClient({
  endpoint: 'https://api.maytes.co',
  clientId: process.env.MAYTES_CLIENT_ID!,
  clientSecret: process.env.MAYTES_CLIENT_SECRET!,
});

Auth errors

HTTPMeaning
401Missing, invalid, or expired access token — fetch a new token and retry.
403Your merchant account is disabled or not permitted for this operation.

See the full error reference.