Link Search Menu Expand Document



Authenticating API Calls

API calls can be authenticated by either providing an API key in the “X-Api-Key” header or by providing a user access token in the “Authorization” header.

Example call with API key:

curl -X GET "" \
    -H "X-Api-Key: ${my_api_key}"

Example call with user access token:

curl -X GET "" -H "Authorization: ${my_access_token}"

API Keys

API keys provide enduring access to a single Centrapay account.

See: Creating API Keys.

The Centrapay test merchant API key is available to test creating payment requests: f32c5497297084e5354b47c40d5ccacb109ce483.

User Access Tokens

User access tokens provide time-limited access to all Centrapy accounts for which the user is a member. Access tokens are issued using OIDC code flow via the Centrapay OAuth authorization server and login page at

After successfully negotiating the OIDC code flow your application will have access to three tokens:

Id Token JWT containing user attributes such as id, phone and email.
Access Token JWT granting access to Centrapay APIs. Expires after 1 hour.
Refresh Token Token for OIDC token exchange. Expires after 60 days or when revoked.

A good starting point for learning more about OIDC is Okta’s OAuth OIDC Illustrated Guide.

When initiating a login request, a valid redirect URI must be provided. To obtain a dedicated OAuth client id with your application’s redirect URI(s) whitelisted please contact Centrapay support. Your callback URI can be for a website (such as “”) or mobile app (such as “com.example.yourapp://oidc-callback”).

Your application can use any OIDC client to negotiate the authentication flow but it must support OIDC authorization code flow with PKCE. See the Example Web Browser OIDC Consumer section below for a working example using the “oidc-client” JavaScript library. The Centrapy authorization server configuration can be interrogated via

When handling the OIDC callback, browser based applications should slurp the callback parameters by performing a location.replace() so they are not available in the browser’s location bar or browsing history. If your application needs to talk directly to from a browser then it will also need to be whitelisted for cross-origin requests.


The following table lists the claims which may be be included in a user id token. At minimum, the “sub” claim and one of “phone_number” or “email” will be present.

Name Description
sub Centrapay user id
email email address
phone_number phone number
given_name given name(s)
family_name surname
preferred_username Centrapay user handle
phone_number_verified phone number has been verified (can be used for account recovery)
email_verified email has been verified (can be used for account recovery)


Users and API keys are assigned a role for their associated Centrapay account(s). The permissions granted to the roles are shown in the table below.

Most permissions apply only to resources owned by the associated account. Some permissions, such as payment-requests:pay, apply globally to all resources regardless of the account the resource belongs to. The global permissions are indicated below with a star (✸).

Permission Account Owner Anon Consumer Merchant Terminal
accounts:create    ✅    
accounts:read    ✅    
accounts:update    ✅    
quotas:read    ✅    
api-keys:create    ✅    
api-keys:update    ✅    
api-keys:list    ✅    
merchants:create    ✅    
merchants:read    ✅    
merchants:update    ✅    
merchants:list    ✅    
payment-requests:read ✸ ✅ ✸ ✅
payment-requests:pay ✸ ✅ ✸ ✅  
assets:read    ✅    
assets:spend    ✅    
wallets:transfer    ✅    
wallets:withdraw    ✅    
wallets:deposit    ✅    
wallets:create    ✅    
wallets:read    ✅    
asset-transfers:create    ✅    
asset-transfers:read    ✅    
asset-transfers:claim    ✅    
bank-authorities:create    ✅    
bank-authorities:read    ✅    
quotas:read    ✅    

Example Web Browser OIDC Consumer

This example demonstrates how to integrate a browser based application with the Centrapay OAuth server using the oidc-client-js JavaScript library.

OIDC User Manager Configuration

import Oidc from 'oidc-client';

Oidc.Log.logger = console;

const yourCentrapayOauthClientId = '7mapl0nqonkgl5vfeb3cf86miu';
const yourAppOidcRedirectUri = window.location.origin + '/oidc-callback';
const userPhoneNumber = '+6421234567890';
const userManager = new Oidc.UserManager({
   * Required configs
  authority: '',
  response_type: 'code',
  scope: 'openid',
  client_id: yourCentrapayOauthClientId,
  redirect_uri: yourAppOidcLoginRedirectUri,
  loadUserInfo: false, // "/oauth2/userInfo" call unsupported by Centrapay OAuth server
  post_logout_redirect_uri: yourAppOidcLogoutRedirectUri,
  metadata: {
    end_session_endpoint: ''
   * Recommended configs
  userStore: new Oidc.WebStorageStateStore({ store: window.localStorage }),
  automaticSilentRenew: true,
  monitorSession: false, // Suppress session event double firing
  extraQueryParams: { u: userPhoneNumber }, // Populate Centrapay login form

Minimal OIDC Client Usage

async function login() {
  /* State attribute is stored and retrievable with OIDC callback state param */
  await userManager.signinRedirect({ state: window.location.href });

async function handleOidcCallback() {
  const result = await userManager.signinRedirectCallback().catch((err) => {
    console.log('Something went wrong handling OIDC callback');
  /* Restore previous location stored against state param */
  window.location.replace(result.state || '/');

async function init() {
  let user = null;
  if (window.location.pathname == '/oidc-callback') {
    await handleOidcCallback();
  } else {
    user = await userManager.getUser();
  if (!user) {
    await login();
  return user;


Trigger Token Refresh

Manually trigger a token refresh when expired due to user being offline.

async function refreshUser() {
  const user await userManager.getUser();
  if (user.expired) {
    await userManager.signinSilent();
    await userManager.signinSilentCallback();
    console.log('User refreshed');
  } else {
    console.log('User not refreshed');
  return await userManager.getUser();

  .catch(err => {
    console.log({ msg: 'Something went wrong refreshing user token, login required', err });

Detect OIDC User Refresh

Detect when OIDC user is refreshed via auto silent renew. The new user may have changed with updated claims, for example, if they have added an email address. => {
  console.log({ msg: 'user auto renew completed', user });

OIDC Client Logout

async function logout() {
  /* State attribute is stored and retrievable with OIDC callback state param */
  await userManager.signoutRedirect({ state: window.location.href });

async function handleLogoutOidcCallback() {
  const result = await userManager.signoutRedirectCallback().catch((err) => {
    console.log('Something went wrong handling OIDC callback');
  /* Restore previous location stored against state param */
  window.location.replace(result.state || '/');