Create Virtual Accounts on demands, receive funds from customers via Virtual Account Number and get notification on Virtual Accounts usage.
Dedicated Virtual Accounts (DVAs) is a service that lets you create Nigerian virtual accounts for your customers. These accounts allow your customers to receive payment from their customers.
When you create a Dedicated Virtual Account (DVA) for a customer, all bank transfers to that account will automatically be recorded as transactions from that customer.
Coverage
NGN
Integration steps
You can generate a VA and start receiving money in 3 easy steps:
Prepare payload (payload includes: first name, last name, BVN, and email)
Find your keys on the Klasha Dashboard → Settings → Generate API Keys (here)
Klasha Dashboard, Generate API Keys page
Generate bearer token
Using the Token endpoint on the Postman collection, the token can be obtained from the headers under the header name: token. See the screenshot below for an example:
Encryption Algorithm
You need to encrypt the entire create virtual account payload that was specified on the previous point (here)
In order to encrypt the body correctly, you’d need the encryptionKey (that you can obtain following this guide here). We also provided an example in Java of the encryption algorithm in order to help you.
publicstaticStringencryptCBC(String stringToEncrypt,String encryptionkey) {try {SecureRandom sr =newSecureRandom();byte[] salt =newbyte[8];sr.nextBytes(salt);finalbyte[][] keyAndIV =GenerateKeyAndIV(32,16,1, salt,password.getBytes(StandardCharsets.UTF_8),MessageDigest.getInstance("MD5"));Cipher cipher =Cipher.getInstance("AES/CBC/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE,newSecretKeySpec(keyAndIV[0],"AES"),newIvParameterSpec(keyAndIV[1]));byte[] encryptedData =cipher.doFinal(stringToEncrypt.getBytes(StandardCharsets.UTF_8));byte[] prefixAndSaltAndEncryptedData =newbyte[16+encryptedData.length];// Copy prefix (0-th to 7-th bytes)System.arraycopy("Salted__".getBytes(StandardCharsets.UTF_8),0, prefixAndSaltAndEncryptedData,0,8);// Copy salt (8-th to 15-th bytes)System.arraycopy(salt,0, prefixAndSaltAndEncryptedData,8,8);// Copy encrypted data (16-th byte and onwards)System.arraycopy(encryptedData,0, prefixAndSaltAndEncryptedData,16,encryptedData.length);returnBase64.getEncoder().encodeToString(prefixAndSaltAndEncryptedData); } catch (Exception e) {thrownewRuntimeException(e); }}
public static byte[][] GenerateKeyAndIV(int keyLength, int ivLength, int iterations, byte[] salt, byte[] password, MessageDigest md) {
int digestLength =md.getDigestLength();int requiredLength = (keyLength + ivLength + digestLength -1) / digestLength * digestLength;byte[] generatedData =newbyte[requiredLength];int generatedLength =0;try {md.reset();// Repeat process until sufficient data has been generatedwhile (generatedLength < keyLength + ivLength) {// Digest data (last digest if available, password data, salt if available)if (generatedLength >0)md.update(generatedData, generatedLength - digestLength, digestLength);md.update(password);if (salt !=null)md.update(salt,0,8);md.digest(generatedData, generatedLength, digestLength);// additional roundsfor (int i =1; i < iterations; i++) {md.update(generatedData, generatedLength, digestLength);md.digest(generatedData, generatedLength, digestLength); } generatedLength += digestLength; }// Copy key and IV into separate byte arraysbyte[][] result =newbyte[2][]; result[0] =Arrays.copyOfRange(generatedData,0, keyLength);if (ivLength >0) result[1] =Arrays.copyOfRange(generatedData, keyLength, keyLength + ivLength);return result;} catch (DigestException e) {thrownewRuntimeException(e);} finally {// Clean out temporary dataArrays.fill(generatedData, (byte) 0);}}
Initiate VA creation
create a virtual account
POST
To create a virtual account using the Create virtual account API on the Postman collection, see the section below to get an example of the payload you need to send in order to create a transfer.
Serialise the payload
Encrypted payload
The result of the encryption of the payload that we specified has to be used with the Create virtual account endpoint as shown below:
Request Body
Name
Type
Description
firstName*
String
John
lastName*
String
Doe
bvn*
22222222222
email*
String
test@klasha.com
When a VA creation is initiated, processing could take a few seconds. These are sample responses you will get below:
{"id":218,"walletId":null,"accountNumber":"8574578073","bankName":"WEMA BANK","orderRef":"fOeatZO40PEJzeiPvq8q","txRef":"klasha-virtual-account-banktransfer-Steph and sons-133","flwRef":"URF_G6Ie8ZP9GZ5hAZk8z6fZ","userId":null,"businessId":133,"bankCode":null,"enabled":true,"accountName":"Stephen Ojerinde","email":"test@steph.com","profileHash":"hwKpOI9+kZR/fFy7hLOpcQ==","createdAt":"2023-07-07 00:42:45","updatedAt":"2023-07-07 00:42:45"}
{"message":"There is no identity available for this bvn.","error":"Operation not allowed"}
{"message":"Bvn name mismatch.","error":"Operation not allowed"}
Requery
GET{{url}}/wallet/virtual/v2/account/email
In case of network downtime or failures during VA creation, the virtual account can be re-queried with the user’s email. This can be fetched using the Requery with email API on the Postman collection.
Headers
Name
Type
Description
authorization*
String
{{token}}
Transaction Webhook
When payments are received from your users, we would send a webhook with the details of the transaction to your callback URL.
To know the status of a transaction, you can fetch the transaction using the Transaction Status API on the Postman collection. Make use of the session id received from the bank. See an example below: