Fintech Card Processing

Are you a fintech company looking to issue cards and credentials to your customers? We can help you get started quickly. To do this, you need to connect to our fintech card API processor service. This service assists fintechs in providing card services. To integrate with our Fintech API Card processor service, you'll need to set up specific endpoints and share them with us.

📘

An API endpoint is like a specific web address that your computer can connect to for getting or sending information

In this guide, we'll walk you through the essential setup of endpoints, explain different transaction flows, and outline the authentication process. Understanding these components is crucial for seamless integration, ensuring your system communicates effectively with our services. Let's dive into the details to facilitate a smooth and successful implementation.

Authentication

Both parties agree upon a special private key, which is used to create a unique message authentication code (MAC) for every transaction. This code, based on HMAC with SHA-512, functions like a digital signature ensuring the transaction's authenticity.

Before any transaction is accepted, both parties must check and confirm the validity of this code. If the code doesn't match, the transaction is considered not genuine. The generated MAC represented as a hex string, is included in the requests and responses for verification.

To confirm the correct MAC generation, an online tool like https://www.freeformatter.com/hmac-generator.html can be used, with SHA-512 selected.

import * as crypto from 'crypto';
import { encode } from 'hex-encode';

function generateMac(message: string, privateKey: string): string {
  const hmac = crypto.createHmac('sha512', Buffer.from(privateKey, 'utf-8'));
  hmac.update(message, 'utf-8');
  const macData = hmac.digest();
  return encode(macData);
}

const message: string = 'your_message_here';
const privateKey: string = 'your_private_key_here';
const generatedMac: string = generateMac(message, privateKey);

//console.log('Generated MAC:', generatedMac);
const crypto = require('crypto');
const { encode } = require('hex-encode');

function generateMac(message, privateKey) {
  const hmac = crypto.createHmac('sha512', Buffer.from(privateKey, 'utf-8'));
  hmac.update(message, 'utf-8');
  const macData = hmac.digest();
  return encode(macData);
}

const message = 'your_message_here';
const privateKey = 'your_private_key_here';
const generatedMac = generateMac(message, privateKey);
//console.log('Generated MAC:', generatedMac);

import hashlib
import hmac
import codecs

def generate_mac(message, private_key):
    mac = hmac.new(private_key.encode('utf-8'), message.encode('utf-8'), hashlib.sha512)
    mac_data = mac.digest()
    return codecs.encode(mac_data, 'hex').decode('utf-8')

message = 'your_message_here'
private_key = 'your_private_key_here'
generated_mac = generate_mac(message, private_key)
//print('Generated MAC:', generated_mac)

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Hex;

public class MacGenerator {

    public static String generateMac(String message, String privateKey)
            throws InvalidKeyException, NoSuchAlgorithmException {
        Mac mac = Mac.getInstance("HmacSHA512");
        SecretKeySpec secretKeySpec = new SecretKeySpec(privateKey.getBytes(StandardCharsets.UTF_8), "HmacSHA512");
        mac.init(secretKeySpec);
        byte[] macData = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
        return Hex.encodeHexString(macData);
    }

    public static void main(String[] args) {
        try {
            String message = "your_message_here";
            String privateKey = "your_private_key_here";
            String generatedMac = generateMac(message, privateKey);
            System.out.println("Generated MAC: " + generatedMac);
        } catch (InvalidKeyException | NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
}

Note

  • message here refers to the request from Interswitch
  • privateKey here refers to the private key generated for your integration.

📘

Once you've created the necessary endpoints , we will provide you with a specific endpoint to generate your private key.

Transaction Flow

The transaction process ensures that requests are only considered complete when a response is received. If there's no response, it could be due to various reasons. For certain requests (like debit, inquiry, or placing a lien), if no response is received, a reversal is initiated. Reversal requests for placing a lien are sent as debit lien requests with an amount of 0.

Transaction requests are sent only once; if no response, a reversal is sent. For reversal or debit lien requests with no response, they are repeatedly sent until a valid response is received. As a Fintech you will need to handle multiple reversal/debit lien requests on your end and ensure that only one request is honored.

Transaction Types And Their Expected Endpoints.

The transaction type determines how the transaction should be treated. Currently, we're focusing on five types: DEBIT, ENQUIRY, REVERSALS, PLACE LIEN, and DEBIT LIEN.

You are expected to implement and expose endpoints for these transaction types.

  • Debit: the debit endpoint will be called whenever a debit is to be done on the wallet. This debit can be of any kind, goods & services, withdrawal, etc.
  • Enquiry: the inquiry endpoint will be called whenever an inquiry is to be done on the account. It can be a balance inquiry, name inquiry, etc
  • Reversal: the reversal endpoint is called whenever a debit that has occurred on the wallet needs to be undone.
  • Place lien: the place lien endpoint will be called for the authorization requests of dual messaging. It should place a lien on the wallet for a particular amount.
  • Debit lien: the debit lien endpoint will be called for the completion of the dual messaging. It should debit the lien that has been place.

More Context On Dual Messaging And Lien

📘

In financial transactions, dual messaging refers to a two-step process where a preliminary authorization message is sent to reserve funds (placing a lien), followed by a second message to confirm and complete the transaction (debiting the reserved funds). This method ensures that the required amount is initially set aside before the final approval and deduction from the account, providing a secure and structured approach to financial transactions.

API Endpoint Specification

This part is about figuring out how the different types of transactions should be formatted, what details they need, and what kind of responses to anticipate. We'll organize this based on the transaction types.

Here, we'll outline what requests the fintech should be prepared to get and what responses they should send back. Importantly, for all transaction types, we're looking for the request method to be POST. This means the fintech should be ready to receive requests and send responses using the POST method.

📘

Important Reads

Response Codes

In our system, the response code plays a crucial role in determining the status of a transaction. Every request should generate a response, and the response code is the key identifier of the transaction's status.

The response code for this project is limited to the response codes listed below. If any response code is received and is not within the listed response codes, the transaction response is treated as an invalid transaction response regardless of what the status might have been on the fintech’s or your end.

Similarly, if the response code is invalid for a reversal request, another reversal request will be initiated. This ensures a reliable and consistent handling of transaction statuses.

StatusResponse Code
Successful00
Do not honor05
Error06
Invalid transaction12
Invalid amount13
Unable to locate record12
Function not supported40
Lost card, pick-up41
Account closed45
Not sufficient funds51
Exceeds withdrawal limit61
Exceeds withdrawal frequency65
Not reachable/Issuer or switch inoperative91
Duplicate transaction94

Transaction Reference Number

The transaction reference is a unique string used to identify every transaction. Every transaction, regardless of the transaction type will have a unique transaction reference. A reversal request will, however, have the transaction reference of the original transaction it’s trying to reverse. This original reference number is found only in reversal requests.

The several repeats of the reversal request, will all have a transaction reference which will be the same as the first reversal request. This means that when a reversal request for a particular transaction is sent several times, they will all have the same transaction reference.

Transaction Amount

This is the amount that is sent both in the request and/or in the response. For this project, the transaction amount will always be minor. This means that for every request that will be sent and for every response that will be received, the transaction amount is always expected to be in minor.

e.g. 100 naira in minor should be 10000.