The Interswitch Strong Authentication Solution (ISAS commonly known as Safe Token) provides a way for issuers to integrate their existing strong authentication systems and provide their cardholders a consistent 2-factor authentication on all their card transactions.

This documentation defines the interface to be implemented by the bank to enable seamless integration between the issuer and ISAS.

Purchase API process flow

The Architecture

Sample Requests

Safe token APIs are HTTP based RESTful APIs therefore API request and response format are in JSON. We have provided sample request and responses next to each endpoint in this documentation. All you need to do is replace the dummy parameters with yours. Feel free to download our

Postman Collection

BASE URL (Sandbox)

BASE URL (Production)

Response Code

We use the standard HTTP response codes. Where anything starting with 2XX signifies approved, 4XX means client error and 5XX indicates server error. When the response codes start with 4XX or 5XX, an error object will be returned to explain further the reason for this failure.

Issuer Requirements

Service Specification: The issuer's service would implement a combination of the following specifications:

  • SOAP Protocol with WS-Reliable Messaging for reliability.
  • WS-Security for message security and authentication.
  • REST Protocol.
  • HTTPS transport.
  • Text/XML or Text/json message encoding.

Communication: The issuer's service is required to authenticate the calls from ISAS. ISAS will pass along its certificate to identify itself to the issuer service. Any hashing algorithm must be SHA512 format.


Authenticate your API calls by including your access token in the Authorization header of every request you make. Interswitch utilizes OAuth 2 to facilitate authorization and grants access to an application either on behalf of a user or on behalf of the application itself.

Application Authorization

To get an access token, create a project on the Interswitch Developer Console and obtain the Client ID and Secret Key of the project and encode the them using this format client_id:secret_key using base64encode. Copy the encoded value of your Client ID and Secret Key and make a call to the endpoint below with the Authorization header that contains the word Basic followed by a space and the base64-encoded value. Ensure that you use the Content-Type:application/x-www-form-urlencoded header and finally pass the grant_type=client_credentials in the body of the request.




Sample Request

import requests
url = ""
body = {"grant_type":"client_credentials"}
headers = {
    'authorization': "Basic SUtJQTFCNzU5M0M0NDAyQkM1RTAwQzQ2QUM4QjFDMUNDMEI4NUVFQkIwODg6c2VjcmV0",
    'content-type': "application/x-www-form-urlencoded"}
response = requests.request("POST", url, data=body, headers=headers)
Parameters Required Type Description
ClientId Yes String Application key. Navigate to `` for your application key
SecretKey Yes String Application secret. Navigate to `` for your application secret.
grant_type Yes String This must be set to client_credentials

Sample Response (Success)

  "access_token": "{Your access token}",
  "token_type": "bearer",
  "expires_in": 43199,
  "scope": "profile",
  "merchant_code": "MX10003",
  "requestor_id": "123588975884",
  "client_name": "kL79ov",
  "payable_id": "359854",
  "jti": "19800d56-3ac6-44c2-b318-8f2ece419840"

Sample Response (Failure)

  "code": "Unauthorized",
  "description": "Bad credentials",
  "errors": null
Parameters Description
access_token A new access token that is used to authenticate against resources that belong to the app itself.
token_type Always bearer
expires_in The lifetime of the access token, in seconds

Authorization headers should be in the following format: Authorization: Bearer Encoded(clientId:secreteKey)

Card Enrollment

To enroll a card, make a request to this endpoint.



Field Value
Content-Type text/xml
SOAPAction AddCardHolder
Authorization Bearer `accesstoken`
Parameter Format Required
HeaderTerminalId String False
TerminalId Aplhanumeric True
AccountNumber Numeric False
Address1 Alphanumeric False
Address2 Alphanumeric False
BankId Integer True
CardPan String True
City String True
Country String False
CountryCode String False
Email String False
ExpiryDate String No
FailureReason Integer False
Gender String False
IsApprovedAndEnabled Boolean False
IsFailure Boolean false
IsVerveEAccount Boolean False
LastName String False
Othernames String False
PostCode Integer False
PrimaryMobileCountryCode String False
PrimaryMobileNumber String ({CountryExtension}+ {PhoneNo}) True
RegistrationChannel Integer {{Value is 9}} True
SecondaryMobileNumber String ({CountryExtension}+ {PhoneNo}) False
State String False
Title String False

Sample Request

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv=""
   <soapenv:Header />
            <tec1:Email />

Sample Response (Success)

<s:Envelope xmlns:s="">
        <AddCardHolderResponse xmlns="">
            <AddCardHolderResult xmlns:a="" xmlns:i="">
                <ResponseCode xmlns="">90000</ResponseCode>
                <ResponseDescription i:nil="true" xmlns=""/>

Sample Response (Failure)

<s:Envelope xmlns:s="">
        <AddCardHolderResponse xmlns="">
            <AddCardHolderResult xmlns:a="" xmlns:i="">
                <ResponseCode xmlns="">10002</ResponseCode>
                <ResponseDescription xmlns="">Invalid Card PAN: 50618310000000152048, </ResponseDescription>


Code Description
10001 Unknown error
80001 Authentication Failure
81001 Token Has been blocked
81002 Token has been locked
81003 Token has not been activated
82001 User does not exist
82001 User already exists
82003 Token does not exist
83001 Token already associated with another user
83002 Token not associated with specified user
90000 Successful
Code Description
1 Hardware