Authentication
The Sticitt Partner API uses the standard OAuth 2.0 Client Credentials flow. Before you can access any API resources, you must exchange your partner credentials for a secure access token.
Prerequisites
To authenticate, you need a Client ID and Client Secret. These are unique to your organization and environment.
- Test Credentials: Provided during your initial integration kickoff.
- Production Credentials: Issued once your integration is certified for go-live.
If you do not have your Client ID or Secret, please contact us at technology@sticitt.co.za.
1. Host Authentication
To obtain a token, make a POST request to the Authentication URL for your target environment.
- Method:
POST - URL:
<AUTHENTICATION>/connect/token- See Environments for the specific Authentications URLs.
Request Body
The body must be x-www-form-urlencoded and contain the following parameters:
| Parameter | Value | Description |
|---|---|---|
grant_type | client_credentials | Required. Specifies the OAuth flow. |
client_id | <YOUR_CLIENT_ID> | Required. Your unique partner ID. |
client_secret | <YOUR_CLIENT_SECRET> | Required. Your confidential secret key. |
scope | <SCOPES> | Required. The space seperated scopes you are requesting (see below). |
Available Scopes
Your allowed scopes are configured during your partner sign-up. You must request the scopes relevant to the API calls you intend to make.
| Scope | Description | Use Case |
|---|---|---|
partner | Mandatory. Grants base access to the Partner API. | Always required. |
pay-sdk-api | Access to Payment resources. | Payment Integrators & Enterprise. |
terminal-api | Access to Terminal resources. | Integrators using POS/Terminals. |
merchant-api | Access to Merchant resources. | Enterprise Partners only. |
wallet-api | Access to Wallet resources. | Enterprise Partners only. |
If you are a standard Payment Integrator, you typically only need to request:
partner pay-sdk-api
Example Request
Here is how to request a token using curl.
curl --location 'https://iam-test.sticitt.co.za/connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=partner-demo' \
--data-urlencode 'client_secret=YOUR_SECRET_HERE' \
--data-urlencode 'scope=partner pay-sdk-api'
Example Response
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"expires_in": 3600,
"token_type": "Bearer"
}
Using the Token
Once you have the access_token, you must include it in the Authorization header of all API requests to the Sticitt Partner API.
Header Format: Authorization: Bearer <TOKEN>
Example API Call
curl --location 'https://api-test.sticitt.co.za/v3/payments' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIs...' \
--header 'Content-Type: application/json' \
...
2. User Authentication (Enterprise Only)
While Client Credentials allow your server to talk to our API, certain actions—like Claiming a Wallet or Linking an Existing User—require you to act on behalf of a specific Sticitt user.
To do this, you must obtain a User Access Token using the OAuth 2.0 Authorization Code Flow with PKCE.
OAuth 2.0 with PKCE is a global standard. You do not need to implement the cryptographic hashing and redirection logic manually!
We strongly recommend using a battle-tested OpenID Connect (OIDC) client library compatible with your framework (e.g., oidc-client-ts for React/Angular, or standard OIDC middleware for .NET, Node.js, and Python).
The Flow Overview
This is an interactive flow. Your application cannot "get" the token silently; the user must be redirected to Sticitt to log in and grant permission.
- Initiate: Your app generates a security key (PKCE) and redirects the user to Sticitt.
- Consent: The user logs in on the Sticitt Identity Server.
- Callback: Sticitt redirects the user back to your app with a temporary code.
- Exchange: Your server swaps that code for an Access Token.
Step 1: Generate PKCE Codes
Before redirecting the user, create a Code Verifier and Code Challenge to prevent interception attacks.
- Verifier: A random URL-safe string (minimum 43 characters).
- Challenge: A Base64-URL-encoded SHA256 hash of the Verifier.
Step 2: Redirect to Sticitt
Construct a URL and redirect the user's browser (or mobile web view) to our Identity Server connect/authorize endpoint.
- URL:
<AUTHENTICATION>/connect/authorize- See Environments for the specific Authentications URLs.
Query Parameters:
| Parameter | Value | Description |
|---|---|---|
client_id | <YOUR_CLIENT_ID> | Your partner ID. |
redirect_uri | <YOUR_CALLBACK_URL> | Must match the whitelist in your partner settings. |
response_type | code | Standard Auth Code flow. |
scope | openid profile offline_access ... | Request offline_access if you need a Refresh Token. |
code_challenge | <YOUR_CHALLENGE> | The hash generated in Step 1. |
code_challenge_method | S256 | We enforce SHA256. |
Example URL Construction:
https://iam-test.sticitt.co.za/connect/authorize?response_type=code&client_id=acme-host&scope=pay-sdk-api%20partner%20wallet-api%20wallet&redirect_uri=https%3A%2F%2Foauth.pstmn.io%2Fv1%2Fcallback&code_challenge=18lLR6bTfv3BPJqv853ISaYO4piTGHbyQ1a3--rv9ws&code_challenge_method=S256
Step 3: Handle the Callback
If the user logs in successfully, Sticitt will redirect them back to your redirect_uri with a temporary authorization code appended to the URL.
Example Callback:
https://myapp.com/callback?code=83e7-40aa-8cf3...
Do not attempt to exchange this code for a token in your frontend application. You need the client_secret to complete the process, and that must never be stored in the browser/app.
Step 4: Exchange Code for Token
To obtain a token, make a POST request to the Authentication URL for your target environment.
- Method:
POST - URL:
<AUTHENTICATION>/connect/token- See Environments for the specific Authentications URLs.
Request Body
The body must be x-www-form-urlencoded and contain the following parameters:
Body Parameters:
| Key | Value | Description |
|---|---|---|
grant_type | authorization_code | Required. |
client_id | <YOUR_CLIENT_ID> | Required. |
client_secret | <YOUR_CLIENT_SECRET> | Required. |
redirect_uri | <YOUR_CALLBACK_URL> | Must match the one used in Step 2 exactly. |
code | <THE_CODE_FROM_URL> | The code received in the callback. |
code_verifier | <THE_VERIFIER_STEP_1> | The original raw string from Step 1. |
Successful Response:
The response will be a JSON object containing:
access_token: The token used to act as the user.refresh_token: Used to get a new access token when the current one expires.expires_in: Time in seconds until expiration.
You can now use this access_token in the Authorization header to make API calls on behalf of the user, such as linking their wallet to your partner profile.
3. Best Practices
Token Lifecycle & Caching
Access tokens are valid for 1 hour (3600 seconds).
You should not request a new token for every single API call. This adds unnecessary latency and may cause you to hit rate limits.
Recommended Pattern:
- Request a token and store it in memory or a fast cache (like Redis) alongside its expiration time.
- Reuse this token for all subsequent requests.
- Only request a new token when the current one is close to expiring (e.g., < 5 minutes remaining) or if the API returns a
401 Unauthorizederror.
Security
Your credentials grant full access to move money and modify data.
Never expose your client_secret in client-side code (browsers, React/Angular apps, or mobile apps).
All authentication requests must originate from your secure backend server. If you include your secret in frontend code, it can be easily extracted by malicious users.