Skip to content
Last updated

Authenticating your application

Before you can make any requests to the Adfin API, you must generate an access token to authenticate your requests. Adfin uses OAuth 2.0 for secure authentication and authorisation.

Prerequsites

Your Adfin Integration Manager will share encrypted app credentials containing your client_id and client_secret.

OAuth 2.0 flows supported

  • Client credentials flow (for platform-to-platform communication)
  • Authorization code flow (for biller authorisation on behalf of your platform)

Authentication in Adfin

Authentication You must supply your client_id and client_secret either in the HTTP Basic Auth header or as form parameters. If you include them in both places, they must match exactly.

How to use Header authentication:

Base64 Authentication

The authorization header string is Basic Base64Encode(client_id:client_secret).

For example, for client ID xyz123clientid and client secret secret987654321, you’d first Base64-encode the string:

xyz123clientid:secret987654321
→ eHl6MTIzY2xpZW50aWQ6c2VjcmV0OTg3NjU0MzIx

Then your header becomes:

Authorization: Basic eHl6MTIzY2xpZW50aWQ6c2VjcmV0OTg3NjU0MzIx

Request example:

curl -X POST "https://api.staging.adfin.com/api/oauth2/token" \
-H "Authorization: Basic $(echo -n 'YOUR_ID:YOUR_SECRET' | base64)" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'grant_type=client_credentials'

Client credentials flow (Platform Token)

This flow is used when platforms need to access Adfin resources directly.

curl -X POST "https://api.staging.adfin.com/api/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'grant_type=client_credentials&client_id={your_client_id}&client_secret={your_client_secret}'

Body:

  • The body contains the grant_type (set to client_credentials)
  • Replace {your_client_id} and {your_client_secret} with your credentials.

If successful, Adfin will respond with an access token:

{
  "access_token": "your_access_token",
  "token_type": "Bearer",
  "expires_in": 3600
}

Generate Authorization code

This flow allows your platform to request an access token after receiving an authorization code from a biller's login session.

The user will be prompted to login to their account.

Image description

Step 1: Redirect biller to Adfin's authorisation page

Use the hosts for the environment your credentials belong to. The biller login runs on the Adfin Console; every other call goes to the API.

StepStagingProduction
Biller login and consenthttps://staging.adfin.com/auth/loginhttps://console.adfin.com/auth/login
Token and refreshhttps://api.staging.adfin.com/api/oauth2/tokenhttps://api.adfin.com/api/oauth2/token
Revokehttps://api.staging.adfin.com/api/oauth2/revokehttps://api.adfin.com/api/oauth2/revoke
API callshttps://api.staging.adfin.com/apihttps://api.adfin.com/api

Redirect the biller to Adfin's authorisation page by constructing your unique authorisation url:

Staging:

https://staging.adfin.com/auth/login?&client_id={your_client_id}&scope=invoices%20customers&redirect_uri={your_redirect_uri}&state={random_state_value}

Production:

https://console.adfin.com/auth/login?&client_id={your_client_id}&scope=invoices%20customers&redirect_uri={your_redirect_uri}&state={random_state_value}
Login address

Use exactly the login addresses above. Adfin's login page builds its return address from whichever address it is opened on, so opening it anywhere else, such as app.adfin.com, ends in a "Callback URL mismatch" error even when your redirect_uri is correct. If your redirect_uri itself is not registered, the biller sees "Invalid redirect URI." when they approve access.

Properties required for oAuth redirect:

URI PropertyDescription
client_idThe client_id of your platform as provisioned by Adfin
redirect_uriThis is where users will be sent after granting permission to Adfin
scopeUse the scopes invoices and customers
stateRequired. A random value you generate and check on the callback. Without it, a biller who is already signed in to Adfin goes to their dashboard instead of the consent screen

Step 2: Handle the callback

After the biller logs in and approves the authorisation, they will be redirected back to the redirect_uri configured in Step 1. Adfin will append a code in the query string, like:

https://your-platform.com/callback?code=[your_authorization_code]&state=random_state_value

Step 3: Exchange the authorization code for tokens

Once you have the authorization code, use this cURL request to exchange it for access and refresh tokens:


Use the same authentication patterns as described at the top of the article: header auth, form parameter authentication.

curl -X POST "https://api.staging.adfin.com/api/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'grant_type=authorization_code&client_id={your_client_id}&client_secret={your_client_secret}&code={authorization_code}&redirect_uri={your_redirect_uri}'
Request dataDescription
grant_typeSet to authorization_code in this step
client_idThe credentials of your Adfin app
client_secretThe credentials of your Adfin app
codeThe authorization code from step 2
redirect_uriMust be the same URI used in the initial request.
Response dataDescription
access_tokenThe unique access token (biller access token)
refresh_tokenRefresh token for the billers account
expires_inHow long the access token is valid for
token_typeWill return bearer token (eg. Biller access token)

You can now use the access_token to make authorised requests on behalf of the biller (e.g Create customers on behalf of the biller).


Managing Refresh Tokens

Use the refresh token to request a new access token when the current access token expires. This is critical for maintaining session continuity without requiring the biller to log in again. Below is the process and an example cURL command to guide you.

oAuth with Refresh token

Our integration uses OAuth2 with refresh token rotation, which requires that:

  • Each newly issued refresh token must be used going forward.
  • Old refresh tokens should be discarded immediately.
  • Concurrent requests must not reuse or fall back to expired tokens.
  • Presenting a refresh token that has already been used can revoke every refresh token on that connection, and the biller will need to authorise again.

Using refresh tokens

You must use refresh tokens to generate new access tokens and additional refresh tokens.

curl -X POST "https://api.staging.adfin.com/api/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'grant_type=refresh_token&client_id={your_client_id}&client_secret={your_client_secret}&refresh_token={your_refresh_token}'
Request dataDescription
grant_typeSet to refresh_token
client_idYour platform's client_id
client_secretYour platform's client_secret
refresh_tokenThe refresh token you received during the initial token exchange
Response dataDescription
access_tokenThe unique access token (biller access token)
refresh_tokenRefresh token for the billers account
expires_inHow long the access token is valid for
token_typeWill return bearer token (eg. Biller access token)

Token expiry

  • access_token: Expires after 1 hour.
  • refresh_token: Expires if it isn't used for 5 days. Every refresh returns a new refresh token with a fresh 5-day window, so a connection can be kept going for up to 1 year from when the biller authorised it. After 1 year, the biller needs to authorise again.

Error handling

  • 401 Unauthorized (INVALID_REFRESH_TOKEN): The refresh token has expired, has been revoked or is invalid. You will need to prompt the biller to authorise again via the Authorization Code Flow.
  • 400 Bad request: Incorrect request format or missing required parameters.

Best practices for using refresh tokens

  • Token rotation: If the response provides a new refresh token, replace the old one in your system. This helps prevent stale tokens.
  • Scheduled refresh: Refresh each connection at least once a day, even when there is no activity for that biller, so its refresh token is never left unused for 5 days.
  • Token storage: Store refresh tokens securely (e.g., encrypted) to protect against token theft.
  • Graceful expiry handling: Always handle the expiration of access tokens by using the refresh token to avoid biller login disruptions.