See the steps below:
Step one
Click on Create Account on the portal to register.
Step two
Fill the form.
You should receive a welcome email from FCMBDigital Bank after the form is submitted and you will be required to activate your profile with a link from the email.
Step three
Click on sign in and enter your credentials.
Step four
Click on Products to see the list of products available.
Except otherwise communicated, the Open Banking product should cater for your API needs.
Open Banking product is for FinTechs or super agents who needs access to APIs to enable FCMB customers carry out transactions on their channels or enable the Fintech to have access their own accounts for statement, balance and transactions.
Step five
Our APIs requires subscription before they can be utilized by the clients.
Enter your subscription name and click subscribe.
Step six
Once subscription is completed, you will be routed to the subscription window where you see your list of subscriptions and their status. If the state remains submitted, it means the product is yet to be approved by the bank. To get your subscription key, click show to review the key. Only one key is required but we recommend you have both primary and secondary keys handy as you may use your secondary key while you reset the primary.
Step seven
From the product API list, the client can select any desired API and click "Try it" for a trial.
Step Eight
The client can supply all header parameters and request payload to test the endpoint on the developer’s portal
Definition Of Terms
Please note that ClientID, ProductID, Password and the endpoints would change for production migration and we therefore advise you keep them as parameters in your appsettings or webconfig.
- ProductID: This is an ID that is associated to the API operation you are you are permitted to access. For example, interbank transfer could have product ID 11 while interbank transfer use product ID 7. Each sample payload comes with the product assigned on the test portal. The bank will provide the right product ID to use in production.
- clientID: this is a unique identifier for each API user. the client ID is generated by the bank upon registration of a client in readiness for production migration. A generic test client ID has been provided for integration.
- UTCTimestamp: This is a representation of current time of your request converted in UTC time format yyyy-MM-ddTHH:mm:ss.fff
. Be sure to convert your time to UTC time. Please note that the format required as part of your authentication Hash is slightly different..
- x-correlation-id: This is a unique ID that binds multiple API orchestrations together for traceability. It is not mandatory to be passed by the client but a GUID will be required if provided in your API request.
For clients open to adopting a robust request ID generator with high level of randomized output; we recommend the use of the requestID generator below. Please note that this is not mandatory.
The code snippet below recognizes the use of a 3-character prefix by the client to further ensure your request ID are differentiated from any other user adopting such.
- RequestID: This is a unique ID for all request sent to our API. 16 digit alphanumeric ID is recommended as the requestID. We recommend each client have at least 3 character prefix for their requestID though this is not mandatory.
- Our response object format
Our response object will always include Code which contains a two-character response code and Description which gives the meaning of the code. The response code for successful request is ‘00’ while other codes are considered a failure.
NOTE: Any InterBank transaction with response code 01 should be taken as Pending settlement and customer fund should not be returned until settlement position is known T+1
Requery status will not make a difference in this case.
In some cases, a response data is also included to give additional information about the response.
Where Data is provided in the response, the object in the data section is usually to qualify the information about the transaction. For cases of requery APIs, the response code ‘00’ indicating success is only a response to the API call but the data provides the status of the enquiry made.
Http Response code for successful transactions is 200 but some responses could come with 400 or 500 depending on what response is received from server side.
E.g a transaction that resulted in system malfunction could have response code 96 and description as System malfunction but with http code 500.
.{
"code": "string",
"description": "string"
}
Or
{
"data":
{
},
"description": "string",
"code": "99"
}
using System;
using System.Text;
using System.Linq;
public class Program
{
public static void Main()
{
Program p = new Program();
//choose 3 characters prefix
string Prefix = "NIX";
Console.WriteLine("RequestID: " + p.GenerateRequestID(Prefix));
}
private string GenerateRequestID(string Prefix)
{
StringBuilder builder = new StringBuilder();
Enumerable
.Range(65, 26)
.Select(e => ((char)e).ToString())
.Concat(Enumerable.Range(97, 26).Select(e => ((char)e).ToString()))
.Concat(Enumerable.Range(0, 10).Select(e => e.ToString()))
.OrderBy(e => Guid.NewGuid())
.Take(13)
.ToList().ForEach(e => builder.Append(e));
return Prefix + builder.ToString();
}
}
Sample C# snippet for header token generation is shown below.
https://dotnetfiddle.net/l7fZVl
using System;
public class Program
{
public static void Main()
{
Program p = new Program();
var utcdate =DateTime.UtcNow;
var ClientID = "250"; // you may use personal ClientID created from our self onboarding link
var Password = "Re0R%0Fd"; // You may use the password dispatched through email during self onboarding.
Console.WriteLine("Client_ID: "+ ClientID);
Console.WriteLine("x-token: " + p.GetXTokenHeader(utcdate,ClientID, Password));
//UTCTimestamp in Header
Console.WriteLine("UTCTimestamp: "+ utcdate.ToString("yyyy-MM-ddTHH:mm:ss.fff"));
}
private string GetXTokenHeader(DateTime utcdate, string ClientID, string Password)
{
//UTCTimestamp in Sha512 Hash
var date = utcdate.ToString("yyyy-MM-ddHHmmss");
var data = date+ ClientID + Password;
return SHA512(data);
}
private string SHA512(string input)
{
var bytes = System.Text.Encoding.UTF8.GetBytes(input);
using (var hash = System.Security.Cryptography.SHA512.Create())
{
var hashedInputBytes = hash.ComputeHash(bytes);
// Convert to text
// StringBuilder Capacity is 128, because 512 bits / 8 bits in byte * 2 symbols for byte
var hashedInputStringBuilder = new System.Text.StringBuilder(128);
foreach (var b in hashedInputBytes)
hashedInputStringBuilder.Append(b.ToString("x2"));
return hashedInputStringBuilder.ToString();
}
}
}
Authentication
We apply two mechanisms to authenticate our clients to be able to access our API endpoints.
· Api Subscription Key:
This will be retrieved from our developer's portal after your subscription to a product is approved by the administrator. Please note there may be need to subscribe to more than one product on the portal.
· API header token:
This will be generated by the client’s code for each request using SHA-512 Hash of Request Time (UTC Time), ClientID and secret key (Password issued by bank).
Steps
- (You will need to include two additional header parameters for improved security)
Convert your time to UTC in the format 2021-06-19T12:41:25.876 using DateTime.UtcNow (C#)
utcTimeStamp = DateTime.UtcNow
- The second header parameter is x-token, this will be a combination of your UTC time() n the format "yyyy-MM-ddHHmmss", clientID and secretkey (test user secret and clientID will be provided). The token is generated with SHA512 hash. For example,
Token = GenerateSHA512String($"{utcTimeStamp.ToString("yyyy-MM-ddHHmmss")}{clientId}{Secret Key}";
x-token = Token
Test Parameters
We recommend that all clients create personal test credential to get their clientID and password to be used to form their header parameters discussed above. Please click here to create you test credentials.
This process will generate the client ID instantly with a popup after the process is completed.
you will also receive a mail with encrypted password and a second email with the code to open the encrypted file.
Please note that the code will be dispatched through SMS in production.
For client who prefer to use generic credentials, please use the credential below:
ClientID = "250";
Password = "Re0R%0Fd";
Please do not attempt password change with the above credentials to avoid denying others access to the same test account. A profile will be arranged to test password change when you conclude other API calls.
In production, the default secret key will be sent to the client as an encrypted email attachment and the decryption code through SMS upon registration by the bank.
The client is expected to change the default secret key by calling Reset or change Password operations under secure encryption. This operation will require the header validation above before a new secret key can be generated.
Change Password will require the same header information described above but the body will take a new password as parameter.
Reset password will also require same header parameter but no password is required in the body. This will generate a random password and send it to the same credential registered with the bank through SMS and email.
Common Parameters:
Interbank Transfers:
Inter-bank transfer requires three steps for completion.
1. Get a list of banks to select the destination bank code
2. Do name inquiry using the bank code and account number
3. Do transfer transaction.
4. Do Transaction Requery to reconfirm failed status.
The bank list result will provide BankCode and BankName. The bank code will be used as the destinationInstitutionCode in the name inquiry.
The name inquiry response will contain most of the information required in the transfer transaction e.g channel code, bankverificationnumber, beneficiaryKYCLevel which is same as KYClevel, NameEnquiryRef which is same as the sessionID, beneficiaryAccountName.
NOTE: Any InterBank transaction with response code 01 should be taken as Pending settlement and customer fund should not be returned until settlement position is known T+1
Requery status will not make a difference in this case.
The channel code is used to indicate the source channel from which the transaction is consummated. Below is the list of channel codes.
Sample Java snippet for header generation.
3xn45dgvf - Java - OneCompiler
package com.alerzo.iso;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.Date;
import java.util.TimeZone;
public class CryptoSecurity {
public static void main(String[] args) throws ParseException {
String utcDate=getCurrentUtcDate();
String clientID = "250";
String password = "Re0R%0Fd";
String token = getXTokenHeader(utcDate, clientID, password);
System.out.printf("Client ID: %s\n",clientID);
System.out.printf("Token: %s\n",token);
System.out.printf("UTCTimestamp: %s",getCurrentUtcDate("yyyy-MM-dd'T'HH:mm:ss.SSS"));
}
private static String getXTokenHeader(String utcdate, String ClientID, String Password) {
//UTCTimestamp in Sha512 Hash
String data = utcdate + ClientID + Password;
return SHA512(data);
}
private static String getCurrentUtcDate() throws ParseException {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-ddHHmmss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return simpleDateFormat.format(new Date());
}
private static String getCurrentUtcDate(String format) throws ParseException {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return simpleDateFormat.format(new Date());
}
private static String SHA512(String input) {
String toReturn = null;
try {
MessageDigest digest = MessageDigest.getInstance("SHA-512");
digest.reset();
digest.update(input.getBytes("utf8"));
toReturn = String.format("%0128x", new BigInteger(1, digest.digest()));
} catch (Exception e) {
e.printStackTrace();
}
return toReturn;
}
}
.Currency will usually be NGN where required except otherwise stated.
In business to customer (B2C) Transfer APIs, the debitAccountNo must have been configured against your clientID
In Customer to business (C2B) Transfer APIs, the CreditAccountNo must have been configured against your clientID
isFees where present indicates the information about the status of charges to be taken. True means charges will be present in the Charges section and false means no charge is expected. Please note that this is typically not on most APIs for external use.
Charges where present indicates the information amount to be charged and the corresponding account to be credited for the charge. This is a list of maximum 5 entries. Please note that this is typically not on most APIs for external use.
Amount indicated the transaction amount.
RequestID is your transaction reference which must be unique for all requests. Please refer to the requestID generator snippet above for guidance.
Narration represents the description of the transaction which is what will be found in customer account. This is expected to be a maximum of 40 characters.
DebitMerchantForCharge: this is typically present on only transactions within the bank and not present for interbank transfers.
Where present, it depicts how the charge that accompanies the transaction should be treated.
Intrabank Transfer
Below are some of the Parameters that are common in some of the bank’s transfer API.
Account name inquiry is required for every intrabank transfer payments, but this is not the same endpoint as the name inquiry for Inter-bank.
{
"debitAccountNo": "string",
"creditAccountNo": "string",
"isFees": true,
"charges": [
{
"account": "string",
"fee": 0
}
],
"amount": 0,
"currency": "string",
"narration": "string",
"requestId": "string",
"otp": "string",
"debitMerchantForCharge": true
}
{
"accountNo": "string",
"clientID": "string",
"productID": 0,
"amount": 0,
"requestId": "string"
}
Most Client taking our intrabank transfer products will require our B2C Transfer API which requires that your account is pre-registered to have access to the transfer.
Same account configures will have access to B2C Account summary and B2C Account statement APIs.
B2C Transfer
{
"debitAccountNo": "string",
"creditAccountNo": "string",
"amount": 0,
"productId": 0,
"narration": "string",
"requestId": "string",
"debitMerchantForCharge": true
}
If DebitMerchantForCharge is set to true, it means the client will be credited less the fee amount agreed with the bank. This means the client (Merchant) is taking the charge.
If DebitMerchantForCharge is set to false, it means the client will be credited full amount while the customer will be debited the fee amount agreed with the bank. This means the customer is taking the charge.
OTP where present will represent a six-digit SMS token received by customer to authorize the transaction.
Please note that for every API method that requires OTP for execution, the client must have called an OTP generation API. This is only with exception of card verification request which generates OTP by default.
There are two variants of the OTP generation API depending on the action that follows.
GenerateConsentOTP: This OTP is used by clients that want to get customer consent for access to their information like Account balance, statement or transfer with the payload below
{
"accountNo": "string",
"clientID": "string",
"productID": 0,
"expiryDate": "string",
"requestId": "string"
}
Generate C2B OTP: this OTP is required to authorize a debit transaction from customer account.
My bank and I