Collection Notification
Overview
The Collection Notification API provides secure access to revenue data, authentication services, and invoice validation functionalities. It allows authorized users to retrieve Revenue Details, Get Payer Id details, and Validate Invoices.
NOTE: Base URL will be provided by ICMA.
Get All Agencies Revenue
Endpoint
Method: GET
URL: BaseUrl/PDMS/api/v1/RevenueDataManagement/get-all-agencies-revenue
Description
Retrieves revenue details of all agencies in the State.
Sample Success Response (200 OK):
{
"succeeded": true,
"message": null,
"errors": null,
"data": [
{
"agencyName": "OFFICE OF THE GOVERNOR",
"agencyCode": "41200",
"revenueName": "Sales of Boarded Vehicles",
"revenueCode": "4040064"
},
{
"agencyName": "BOARD OF INTERNAL REVENUE",
"agencyCode": "41503",
"revenueName": "MCRenewal Commercial STD/VL/RW/HP",
"revenueCode": "BMR458"
},
{
"agencyName": "OFFICE OF THE GOVERNOR",
"agencyCode": "41200",
"revenueName": "Sales of Application Form P.W.B. (Christian Wing)",
"revenueCode": "4040065A"
},
{
"agencyName": "OFFICE OF THE GOVERNOR",
"agencyCode": "41200",
"revenueName": "Sales of report (Christian Wing)",
"revenueCode": "4040065B"
},
{
"agencyName": "STATE JUDICIARY CUSTOMARY COURT OF APPEAL",
"agencyCode": "49100",
"revenueName": "Miscillaneous (Customary Court of Appeal)",
"revenueCode": "4130003"
}
]
}
Get Payer ID Details
Description
This endpoint retrieves detailed information about a specific payer based on the provided payer ID. The Payer ID can be included directly into the URL. See Sample Image
Endpoint
Method: GET
URL: BaseUrl/PDMS/api/v1/RevenueDataManagement/get-payerId-details
Query Parameters
• payerId: string (required) (Example: "O1234567890")
Sample Image to Get Payer ID
Sample Success Response (200 OK):
{
"succeeded": true,
"message": "Payer Details Found For: 4020100206",
"errors": null,
"data": {
"payerName": "ICMA PROFESSIONAL SERVICES",
"utin": "4020100206",
"address": "36. YEMI OLADIRAN STREET OLD BODIJA ",
"email": "peter.doe@icmaservices.com",
"telephoneNumber": null,
"merchantCode": "OYSS",
"lgaName": "Ibadan North",
"payerType": "org",
"staffNumber": null,
"cacNumber": "BN 2315817",
"revenueOfficeName": "Headquarter",
"dateCreated": "0001-01-01T00:00:00",
"payerCategory": "Cooperate Payer",
"jtbTin": null
}
}
Sample2 Success Response (200 OK):
{
"succeeded": true,
"message": "Payer Details Found For: 4060148402",
"errors": null,
"data": {
"payerName": " OGBOROGE OSAS",
"utin": "4060148402",
"address": "SHALOM HOUSE JOYCE B OFF RING ROAD IBADAN ",
"email": "mikedoe@gmail.com",
"telephoneNumber": "08060334342",
"merchantCode": "OYSS",
"lgaName": "Akinyele",
"payerType": "Ind",
"staffNumber": null,
"cacNumber": null,
"revenueOfficeName": "GBAGI SHOPPING COMPLEX",
"dateCreated": "2016-11-11T11:42:22.133",
"payerCategory": "Individual Payer",
"jtbTin": null
}
}
Validate Invoice Number
Endpoint
Method: POST
URL: BaseUrl/PDMS/api/v1/RevenueDataManagement/validate-invoiceNo
Description
This endpoint validates an invoice using the provided payment code.
Sample Request Body (JSON):
{
"invoiceNo": "12233"
}
Single Sample Success Response (200 OK):
{
"succeeded": true,
"message": "Record Found For Invoice or Assessment No. OYPDMS222WWAEB",
"errors": null,
"data": {
"transactionId": "RM3e0cdf4e08f141ca95656d651a9231ba",
"payerName": "MR JOHN DOE ",
"payerId": "4010100026",
"telephone": "08034432038",
"address": "IBADAN ",
"totalAmount": 200,
"amountPaid": 20,
"assessmentBalance": 180,
"paymentCode": "OYPDMS222WWAEB",
"assessmentRefNo": "RM3e0cdf4e08f141ca95656d651a9231ba",
"partPaymentAllow": true,
"narration": "Payment For Direct Assessment",
"revenueCode": "4010001",
"revenueName": "Direct Assessment",
"agencyCode": "41503",
"agencyName": "BOARD OF INTERNAL REVENUE",
"dateAssessed": "2022-06-01T09:35:35.94",
"assessedYear": "2022",
"assessedPeriod": "2021",
"platformCode": "Self",
"invoiceDetailsResponse": []
}
}
Sample Success Response with items (200 OK):
{
"succeeded": true,
"message": "Record Found for Invoice No. : DTPDMS248DDB7B",
"errors": null,
"data": {
"assessmentRefNo": "DTPDMS248DDB7B",
"payerName": "FMC ASABA ELITES MPCS ASABA",
"telephone": "",
"address": "ASABA ",
"totalAmount": "2,500.00",
"assessmentAmount": "2,500.00",
"narration": "Payment For Unclassified Revenue",
"revenueCode": "900",
"revenueName": "Unclassified Revenue",
"agencyCode": "000",
"agencyName": "UNSPECIFIED AGENCY",
"amountPaid": "0.00",
"assessmentBalance": "2,500.00",
"billBalance": 2500.00,
"dateCreated": "2024-05-13T14:00:39",
"isReversed": null,
"reversedby": null,
"dateReversed": null,
"agentUtin": "2020105738",
"taxYear": "2024",
"isExpired": null,
"platformcode": "Self",
"assessedPeriod": "",
"previousYearAssessmentRefNo": "",
"status": "Awaiting Approval",
"invoiceDetailsResponse": [
{
"itemTransactionId": "SS59D84276BF4C446DA852AA933B31AAEE1",
"itemAmount": 2000,
"itemPaymentCode": "DTPDMS248DDB7B1",
"partPaymentAllow": true,
"amountPaid": 0.00,
"narration": "Payment For Withholding Tax (WHT)",
"revenueCode": "401-2(III)",
"revenueName": "Withholding Tax (WHT)",
"agencyCode": "1",
"agencyName": "FEDERAL MINISTRY OF EDUCATION",
"platformCode": "Self",
"isExpired": null
},
{
"itemTransactionId": "SS59D84276BF4C446DA852AA933B31AAEE2",
"itemAmount": 500,
"itemPaymentCode": "DTPDMS248DDB7B2",
"partPaymentAllow": true,
"amountPaid": 0.00,
"narration": "Payment For RoadWorthiness",
"revenueCode": "403-12(v)",
"revenueName": "Road Worthiness",
"agencyCode": "27",
"agencyName": "TRANSPORT",
"platformCode": "Self",
"isExpired": null
}
]
}
}
Validate Payment Restrictions
Description
This endpoint is Compulsory for Providers that have restrictions
Endpoint
Method: POST
URL: BaseUrl/PDMS/api/v1//RevenueDataManagement/validate-payment-restrictions
Sample Request Body:
{
"merchantCode": "OGSS",
"collectionReportValidationCount": 1,
"collectionReportValidationRequests": [
{
"payerId": "4060148402",
"amount": 25000,
"revenueCode": "4130003",
"paymentRefNumber": "TEST|12345|28032025|1120",
"paymentCode": "OYPDMS222WWAEB"
}
]
}
Sample Success Response (200 OK):
{
"succeeded": true,
"message": "Transaction received successfully. Kindly review status details.",
"statusCode": null,
"errors": null,
"data": {
"merchantCode": "OGSS",
"collectionReports": [
{
"paymentRefNumber": "TEST|12345|28032025|1120",
"statusCode": "00",
"statusMessage": "All validations pass proceed to process payment"
}
]
}
}
Sample Response 2:
This is an example of a Validation that indicates that while the transaction was received successfully, it failed validation due to the payer exceeding their monthly individual amount limit.
{
"succeeded": true,
"message": "Transaction received successfully. Kindly review status details.",
"statusCode": null,
"errors": null,
"data": {
"merchantCode": "OGSS",
"collectionReports": [
{
"paymentRefNumber": "TEST|12345|28032025|1120",
"statusCode": "13",
"statusMessage": "Maximum Individual Amount(25000.00) exceeded for this payer id (3710134440) for this month (April 2025)"
}
]
}
}
Encryption Process
-
Private Key Sharing
- The Provider calls a dedicated endpoint (/get-secret-key) to request an AESIV. and AESKey
- A new AESKey and AESIV are generated or retrieved from a previous request.
- The keys remain valid for 3 months unless revoked.
-
Decrypting the AESKey and AESIV
- Use the decrypted key provided by ICMA to decrypt the AESKey and AESIV.
- Store only the encrypted state to prevent exposure.
-
Encrypting Data
- Use AES encryption with the both decrypted AESKey and AESIV before sending the request.
-
Secure Data Transmission
- Send AES-encrypted data securely to ICMA.
- Maximum supported file size: 1 GB.
Retrieve or Renew Secret Key
Endpoint
Method: GET
URL: BaseUrl/PDMS/api/v1/RevenueDataManagement/get-secret-key
Sample of Decrypted Key
Used for decrypting generated encrypted AESKey and encrypted AESIV key:
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCveZgjyTrkaId/7DCPTeiuPSTr4/haT/RdsrRoBMs7S+4fGITCkfj9L07gi8WFAaFnIlT3yYyscLUwOAQtyIgmXUlhmvhqhZhMylpUBTLfSNG45tS/javecWrKAIYXEgQlvdd+yctu0U8nByWhfrazxXwPD0RtB2NL5ZleGj4ivsQxC6YGoBNGQjVa9dXhzmmTIZH67AMD2iYBzCC5+4rNMoWqyaiBeRpmUSK+x97T/blyx6obZQKy6nx/9uasyQ7l2Y9zAGvaIJHusqzdHxvf9zN0PpGPO/qri1nJotRUT079ikx77tNJLa5Qhxyhwaezm9Qi2s2HyOhPsjg83GCZAgMBAAECggEBAKcjI2Waq0yZv8550vr8U097D+rblle3ZmPE7o9RWZ6eQS4/NVz6mvXVlMTOfRGmLu1ERzhJMoOhSwOlp11Qb1ZTbqzYZhtYKmuiJg13cjA5dQEwZJ4bvAPBddz4SMA6udaVD2hFn05rcYAUD6TWRAHRbcwOV7ed3NeS1tVKG7sM86G73DLPadPzuQVU5AjhPEyVR0l3DoR8pphBwGkoemYAasxLTdcYq18Rch30YQa8xh2UvLNy6mjSzIu20D4HDDaRII7ruvJ4txNFLmEy6fzN0S0+MIqeU5K93HL5tsYY4gpV1mw9lAcxxpFwJnC6Ajn1TjfQUeZFsxyMVeoUHq0CgYEA02ulLjEWgLISLDvpoU0RqQb5DptgDCGXQk8fuj5UBXIwMYx9yMVSZGMIiFImQJqp2hC6J8lkwldZwyV1TZ937teqO1IEvFLsGFq076M1auj270pJyiOiQgvYYTPu/CwE6mgD5usz9xPAhs3DIeCV/TazeZ5uO4myZrRcUscXD2cCgYEA1HmhnR9L4cXVLUrWzdiy55+BMNYkxyMcTFc9MpKAddCM1IT2MsV8uoiD51eP6wHpMlVjqrs4Gq2jitEZWF3kp85RWsOfGt0510h5LJBrVDEmkfb3Xh1BJ3EzGGfPolYAmRbGNcmrPxLeHFBlx2GV4zSi/vC226Dr/kHbYB/7D/8CgYAc3oUWsqNE/YvXuHKlkPWJZCdcJEFQRsH1zwIhF2O3vqjwCyQd5zvh81f17WnFxpjM6x3QUwLMOstKB3JmIBFrbs2S/hchdB1DEhfE5T9lEtytPjKnRIhihmWMmF/Y1VXygDOQM6vL4EmY3r33gUhZ5D9LqyOYQ6w1tAkrUH5InwKBgDCUPqc16JuOJ9dbLRGTYhQjG96Wl4IQPQAXUh6l8Ej/jbNpUwD4tjPP0piqJHWO0kp3y3nVpFY1LRcoB6t0jDrxqRgfcdkqi3b1Uv8lZeSx+CeXV6dk+OiTsSL7WTW8hBZ8ZoUVvtmE7tN6bkrPvP1do4a2cph0ioBvfkDUDwrxAoGAdz/1SKsdjTE+SLt1BHbt1j72cww5u5+nxCM5eKDVQ/SQUEUoAt191CJ22pLHcEnE44oXd/C+ZvM2PdAqm9MIT2VJcmpgb5AVmliUspwChJKsWzZ2mxsYQWkYAXiFQLH8qpHQAM3OS4N57W3KVK8Q6xqtzZtjJ2sxoMBUHI+BF9Q=
Parameters
| Name | Type | Location | Description |
|---|---|---|---|
| Renew | boolean | Query | Set true to renew the key, false to retrieve existing key |
Success Response (200 OK)
{
"succeeded": true,
"message": "string",
"statusCode": "string",
"errors": [
"string"
],
"data": {
"clientCode": "string",
"clientName": "string",
"isRevoked": false,
"expiresAt": "2025-03-01T13:23:30.628Z",
"version": "1.0.0",
"encryptedAESKey": "string”,
"encryptedAESIv": "string”,
}
}
400 Bad Request
{
"type": "string",
"title": "string",
"status": 0,
"detail": "string",
"instance": "string"
}
404 Not Found
{
"succeeded": true,
"message": "string",
"statusCode": "string",
"errors": [
"string"
],
"data": {
"clientCode": "string",
"clientName": "string",
"isActive": true,
"expiresAt": "2025-03-01T13:23:30.641Z",
"version": "string",
"encryptedAESKey": "string”,
"encryptedAESIv": "string”,
}
}
500 Internal Server Error
{
"succeeded": true,
"message": "string",
"statusCode": "string",
"errors": [
"string"
]
}
Payment Notification
Overview
The Payment Notification API allows secure sending of payment transaction details by the payment providers. This ensures seamless reconciliation and validation of payments processed through various financial institutions. Data is encrypted using AES encryption for secure transmission.
Endpoint
Method: POST
URL: BaseUrl/PDMS/api/v1/RevenueDataManagement/payment-notification
Request Header
Content-Type: application/json
Authorization: Bearer < token >
Data Encryption
This API uses AES encryption for secure data transmission. Below is a sample object for encryption before sending.
Sample Object to Encrypt for Payment Notification
{
"merchantCode": "OYSS",
"collectionReportCount": 2,
"collectionReports": [
{
"providerCode": "INT",
"channelCode": "INB",
"paymentRefNumber": "ABP|BRH|OYOS|26-02-2025|848866",
"paymentDate": "2025-02-01T17:24:40",
"amountPaid": 100.0,
"payerName": "John Doe",
"payerAddress": "23 Oba Akinjobi Way",
"depositSlipNumber": "55669878",
"telephoneNumber": "8066094193",
"paymentMethodCode": "01",
"paymentValueStatusCode": "00",
"valueStatus": "Cleared",
"receiptNo": "201361381752_2232VO72",
"receiptDate": "2025-02-01T17:24:40",
"valueDate": "2025-02-01T17:24:40",
"revenueCode": "4010002",
"agencyCode": "41503",
"bankCode": "ABP",
"branchCode": "IBADAN 2 (IWO RD)",
"chequeNumber": "N/A",
"chequeBankCode": "N/A",
"chequeBankName": "N/A",
"postedBy": "Cashier One",
"transactionReference": "201361381752",
"assessmentNo": "100080021111062",
"controlNumber": "N/A",
"paymentPeriod": "Jan. 2025",
"payerId": "140849085",
"platformCode": "",
"paymentMethodName": "POS",
"currencyCode": "NGN",
"isReversed": false,
"reversalID": "",
"revenueName": "Direct assessment",
"agencyName": "BOARD OF INTERNAL REVENUE",
"bankName": "ACCESS BANK NIGERIA PLC",
"branchName": "IBADAN 2 (IWO RD)"
},
{
"providerCode": "INT",
"channelCode": "INB",
"paymentRefNumber": "ABP|BRH|OYOS|26-02-2025|848867",
"paymentDate": "2025-02-01T17:24:40",
"amountPaid": 100.0,
"payerName": "John Doe",
"payerAddress": "23 Oba Akinjobi Way",
"depositSlipNumber": "556698788",
"telephoneNumber": "80660941933",
"paymentMethodCode": "01",
"paymentValueStatusCode": "00",
"valueStatus": "Cleared",
"receiptNo": "201361381752_2232VO73",
"receiptDate": "2025-02-01T17:24:40",
"valueDate": "2025-02-01T17:24:40",
"revenueCode": "401000222",
"agencyCode": "4150333",
"bankCode": "ABP",
"branchCode": "IBADAN 2 (IWO RD)",
"chequeNumber": "N/A",
"chequeBankCode": "N/A",
"chequeBankName": "N/A",
"postedBy": "Cashier One",
"transactionReference": "201361381753",
"assessmentNo": "100080021111063",
"controlNumber": "N/A",
"paymentPeriod": "Jan. 2025",
"payerId": "140849085",
"platformCode": "",
"paymentMethodName": "POS",
"currencyCode": "NGN",
"isReversed": false,
"reversalID": "",
"revenueName": "Direct assessment",
"agencyName": "BOARD OF INTERNAL REVENUE",
"bankName": "ACCESS BANK NIGERIA PLC",
"branchName": "IBADAN 2 (IWO RD)"
}
]
}
Request Body for Payment Notification
Responses
The responses provide the status of processed transactions.
200 OK (Batch Communication Response)
{
"succeeded": true,
"message": "Transaction reviewed, see details.",
"statusCode": null,
"errors": [],
"data": {
"merchantCode": "OYSS",
"collectionReports": [ //Transaction Responses
{
"paymentRefNumber": "ABP|BRH|OYOS|26-02-2025|848865",
"statusCode": "200",
"statusMessage": "Success: Notification processed successfully."
},
{
"paymentRefNumber": "ABP|BRH|OYOS|26-02-2025|848866",
"statusCode": "400",
"statusMessage": "Error: Invalid payment details."
}
] // End of Transaction Responses
}
} // End of Batch Communication Response
400 Bad Request (Batch Communication Response)
{
"type": "string",
"title": "string",
"status": 0,
"detail": "string",
"instance": "string"
}
500 Internal Server Error (Batch Communication Response)
{
"succeeded": true,
"message": "string",
"statusCode": "string",
"errors": [
"string"
]
}
Parameters For Payment Notification
| Field # | Field name | Data type | Required | Description |
|---|---|---|---|---|
| 1 | ProviderCode | string | YES | Provider code. This will be supplied by ICMA |
| 2 | ChannelCode | string | YES | The code assigned to the channel of payment. Please see index 2 below |
| 3 | PaymentRefNumber | string | YES | The reference number attached to each payment transaction. |
| 4 | PaymentDate | DateTime | YES | TransactionPpayment Date. |
| 5 | AmountPaid | decimal | YES | The Amount captured |
| 6 | PayerName | string | YES | The name of the payer. |
| 7 | PayerId | string | optional | Supply Null for Payer ID and not system generated ID for the payer. But if the payer pays with TIN, let it be supplied as payer ID |
| 8 | PayerAddress | string | optional | The contact address of the payer. |
| 9 | DepositSlipNumber | string | optional | Deposit Slip Number or Teller Number. Can be set to "N/A" |
| 10 | TelephoneNumber | string | optionl | Phone number of the payer. |
| 11 | PaymentMethodCode | string | YES | The definition is defined in the Key below. Please, see index 1 below. |
| 12 | PaymentMethodName | string | optional | The method of payment. Please, see index 1 below. |
| 13 | PaymentValueStatusCode | string | YES | This is the status code of the payment. Please, see index 3 in the key table below for clarification. |
| 14 | ValueStatus | string | YES | This is the status of the payment. Please, see index 3 in the key table below for clarification. |
| 15 | ValueDate | DateTime | optional | This is payment valid date |
| 16 | ReceiptNo | string | YES | The reciept number generated for the transaction |
| 17 | ReceiptDate | DateTime | optional | The date the reciept was generated |
| 18 | RevenueCode | string | YES | The code of the payment item type |
| 19 | RevenueName | string | YES | The name of the item type |
| 20 | AgencyCode | string | YES | This is the Revenue Head Code |
| 21 | AgencyName | string | YES | This is the Revenue Head Name |
| 22 | BankCode | string | YES | The code of the bank the transaction takes place |
| 23 | BankName | string | YES | The name the bank where the transcation takes place |
| 24 | BranchCode | string | optional | The branch code of the bank where the transcation takes place. |
| 25 | BranchName | string | optional | The branch name of the bank where the transcation takes place. |
| 21 | ChequeNumber | string | optional | Cheque Number i.e. in case you are posting cheque transaction. Can be Set to "N/A" |
| 22 | ChequeBankName | string | optional | Bank Code of the cheque issued i.e. in case you are posting cheque transaction.Can Set to "N/A" |
| 23 | CurrencyCode | string | optional | set to "NGN" |
| 24 | PostedBy | string | YES | The Teller name that post the transaction |
| 25 | TransactionReference | string | optional | This can be alternate to payment transaction reference number |
| 26 | AssessmentNo | string | optional | Assessment Number i.e. if you are paying using assessment number |
| 27 | ReversalID | string | optional | Supply the payment Reference Number of the transaction that you want to reverse, else send NULL or Empty string. |
| 28 | IsReversed | bool | optional | This will be FALSE if the transaction is not a reversed transaction else it will be TRUE |
| 29 | ControlNumber | string | optional | Generated for the transaction with issued receipt number. Can be Set to "N/A" |
| 30 | PaymentPeriod | string | optional | Payment narration for period which the payment covers |
| Index 1 - Payment Method | |
|---|---|
| Name | Code |
| Cash | 01 |
| Own Bank Cheque | 02 |
| Other Bank Cheque | 03 |
| Internal Transfer | 04 |
| Index 2 - Collection Channel Code | |
|---|---|
| Name | Code |
| In Branch | INB |
| POS | POS |
| Web | Web |
| Index 3 - Payment Value | |
|---|---|
| Name | Code |
| Cleared | 00 |
| Pending | 01 |
| Returned | 02 |
Requirements and Limitations
- Ensure all required parameters are included in requests.
- Always validate responses before processing data.
- Receive Token: If the credentials are valid, you will receive an access token.
- Each API key allows a maximum of 1000 requests per hour.
- Exceeding the rate limit will return a 429 Too Many Requests error.
Appendix
Sample of encryption and decryption code in C#
{
public class SampleEncryption
{
public class EncryptDecrypt
{
public string EncryptWithAes(string plainText, byte[] key, byte[] iv)
{
using var aes = Aes.Create();
aes.Key = key;
aes.IV = iv;
var encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using var ms = new MemoryStream();
using var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
using (var sw = new StreamWriter(cs))
{
sw.Write(plainText);
}
var encrypted = ms.ToArray();
return Convert.ToBase64String(encrypted);
}
public string DecryptWithAes(string cipherText, byte[] key, byte[] iv)
{
var buffer = Convert.FromBase64String(cipherText);
using var aes = Aes.Create();
aes.Key = key;
aes.IV = iv;
var decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
using var ms = new MemoryStream(buffer);
using var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
using var sr = new StreamReader(cs);
var decrypted = sr.ReadToEnd();
return decrypted;
}
// RSA decryption to decrypt the EncryptedAESkey & EncryptedAESIv)
public byte[] DecryptWithRsa(byte[] encryptedData, string decryptedKey)
{
try
{
using var rsa = RSA.Create();
rsa.ImportRSAPrivateKey(Convert.FromBase64String(decryptedKey), out _);
return rsa.Decrypt(encryptedData, RSAEncryptionPadding.OaepSHA256);
}
catch (Exception ex)
{
throw new CryptographicException("Decryption failed", ex);
}
}
}
public SampleEncrption(string encryptedAESKey, string encryptedAESIv, string decryptedKey)
{
var encryptDecrypt = new EncryptDecrypt();
var samplePlainText =
"{\"collectionReportCount\":1,\"collectionReports\":[{\"agencyCode\":\"100080021110000\",\"agencyName\":\"BOARD OF INTERNAL REVENUE\",\"amountPaid\":10000.0,\"assessmentNo\":\"0095000051281_100080021111062\",\"bankCode\":\"214\",\"bankName\":\"First City Monument Bank\",\"branchCode\":\"POS\",\"branchName\":\"POS\",\"channelCode\":\"POS\",\"chequeBankCode\":\"N/A\",\"chequeBankName\":\"N/A\",\"chequeNumber\":\"N/A\",\"controlNumber\":\"N/A\",\"currencyCode\":\"string\",\"depositSlipNumber\":\"N/A\",\"icmaReceipt\":\"string\",\"isReversed\":false,\"payerAddress\":\"13, Adeyeye close, off Fashola street, Oando Bus Stop , Sango, Ota\",\"payerName\":\"Adebanjo Oladapo Olaolu\",\"payerUtin\":\"string\",\"paymentDate\":\"2024-10-31T17:24:40\",\"paymentMethodCode\":\"01\",\"paymentMethodName\":\"POS\",\"paymentPeriod\":\"XPCO\",\"paymentRefNumber\":\"0095000051281_6723AF2E14221241\",\"paymentValueStatusCode\":\"00\",\"platformCode\":\"string\",\"postedBy\":\"Adebanjo Oladapo Olaolu\",\"providerCode\":\"XPSL\",\"receiptDate\":\"2024-10-31T17:24:40\",\"receiptNo\":\"201361381752_2232VO72\",\"revenueCode\":\"100080021111062\",\"revenueName\":\"Direct assessment\",\"reversalID\":\"\",\"telephoneNumber\":\"8066094193\",\"transactionReference\":\"201361381752\",\"valueDate\":\"2024-10-31T17:24:40\",\"valueStatus\":\"Cleared\"}],\"merchantCode\":\"OYSS\"}";
Console.WriteLine($"Plain: {samplePlainText}");
// Convert EncryptedAESKey and EncryptedAESIv from base64 strings back to byte arrays
byte[] encryptedAesKeyBytes = Convert.FromBase64String(encryptedAESKey);
byte[] encryptedAesIvBytes = Convert.FromBase64String(encryptedAESIv);
// Decrypt the AESkey using your provided Decrypted key
byte[] aesKey = encryptDecrypt.DecryptWithRsa(encryptedAesKeyBytes, decryptedKey);
// Decrypt the AESIv using your provided Decrypted key
byte[] aesIv = encryptDecrypt.DecryptWithRsa(encryptedAesIvBytes, decryptedKey);
var encryptedText = encryptDecrypt.EncryptWithAes(samplePlainText, aesKey, aesIv);
Console.WriteLine($"Encrypted: {encryptedText}");
var decryptedText = encryptDecrypt.DecryptWithAes(encryptedText, aesKey, aesIv);
Console.WriteLine($"Decrypted: {decryptedText}");
}
}
}
Sample of encryption and decryption code in JAVA
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
public class SampleWithoutFixBreaks {
private static final String RSA_ALGORITHM = "RSA";
private static final String AES_ALGORITHM = "AES";
private static final String AES_TRANSFORMATION = "AES/CBC/PKCS5Padding";
public static void main(String[] args) {
try {
String privateKeyString = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCveZgjyTrkaId/7DCPTeiuPSTr4/haT/RdsrRoBMs7S+4fGITCkfj9L07gi8WFAaFnIlT3yYyscLUwOAQtyIgmXUlhmvhqhZhMylpUBTLfSNG45tS/javecWrKAIYXEgQlvdd+yctu0U8nByWhfrazxXwPD0RtB2NL5ZleGj4ivsQxC6YGoBNGQjVa9dXhzmmTIZH67AMD2iYBzCC5+4rNMoWqyaiBeRpmUSK+x97T/blyx6obZQKy6nx/9uasyQ7l2Y9zAGvaIJHusqzdHxvf9zN0PpGPO/qri1nJotRUT079ikx77tNJLa5Qhxyhwaezm9Qi2s2HyOhPsjg83GCZAgMBAAECggEBAKcjI2Waq0yZv8550vr8U097D+rblle3ZmPE7o9RWZ6eQS4/NVz6mvXVlMTOfRGmLu1ERzhJMoOhSwOlp11Qb1ZTbqzYZhtYKmuiJg13cjA5dQEwZJ4bvAPBddz4SMA6udaVD2hFn05rcYAUD6TWRAHRbcwOV7ed3NeS1tVKG7sM86G73DLPadPzuQVU5AjhPEyVR0l3DoR8pphBwGkoemYAasxLTdcYq18Rch30YQa8xh2UvLNy6mjSzIu20D4HDDaRII7ruvJ4txNFLmEy6fzN0S0+MIqeU5K93HL5tsYY4gpV1mw9lAcxxpFwJnC6Ajn1TjfQUeZFsxyMVeoUHq0CgYEA02ulLjEWgLISLDvpoU0RqQb5DptgDCGXQk8fuj5UBXIwMYx9yMVSZGMIiFImQJqp2hC6J8lkwldZwyV1TZ937teqO1IEvFLsGFq076M1auj270pJyiOiQgvYYTPu/CwE6mgD5usz9xPAhs3DIeCV/TazeZ5uO4myZrRcUscXD2cCgYEA1HmhnR9L4cXVLUrWzdiy55+BMNYkxyMcTFc9MpKAddCM1IT2MsV8uoiD51eP6wHpMlVjqrs4Gq2jitEZWF3kp85RWsOfGt0510h5LJBrVDEmkfb3Xh1BJ3EzGGfPolYAmRbGNcmrPxLeHFBlx2GV4zSi/vC226Dr/kHbYB/7D/8CgYAc3oUWsqNE/YvXuHKlkPWJZCdcJEFQRsH1zwIhF2O3vqjwCyQd5zvh81f17WnFxpjM6x3QUwLMOstKB3JmIBFrbs2S/hchdB1DEhfE5T9lEtytPjKnRIhihmWMmF/Y1VXygDOQM6vL4EmY3r33gUhZ5D9LqyOYQ6w1tAkrUH5InwKBgDCUPqc16JuOJ9dbLRGTYhQjG96Wl4IQPQAXUh6l8Ej/jbNpUwD4tjPP0piqJHWO0kp3y3nVpFY1LRcoB6t0jDrxqRgfcdkqi3b1Uv8lZeSx+CeXV6dk+OiTsSL7WTW8hBZ8ZoUVvtmE7tN6bkrPvP1do4a2cph0ioBvfkDUDwrxAoGAdz/1SKsdjTE+SLt1BHbt1j72cww5u5+nxCM5eKDVQ/SQUEUoAt191CJ22pLHcEnE44oXd/C+ZvM2PdAqm9MIT2VJcmpgb5AVmliUspwChJKsWzZ2mxsYQWkYAXiFQLH8qpHQAM3OS4N57W3KVK8Q6xqtzZtjJ2sxoMBUHI+BF9Q=";
String encryptedKey = "jOsG1BUxOTmcTZLZbLnyObYECnvYyfSnvy3ayTGRP6w8K0l9aKlMAFigw3IPP6sY6P7NrkFAsFJbFIXeYZZ/sGa1ppeblVRfT2U4jv6Ijpij3/JVzI+ejQO4oQRZRNFKbCTSFS9Qi/o1jphFI/Y2TJpQ8D6C7FR/YIjF/h2gUSRQv5IE+dvg+DxpiV9kGunvVXMXGtDbyNaAMY6KbM3zItfhcKPCu/ttpohN6jMcd7rTajAPY7F8hGLP0mva0xwyjEMe9vK86bj4spij2vfzdpv326dZYPV9QxzJX0kppcxXPdwVQI9a4jpvuq+4dPiLTZ++UctKv6sojsbOEZNnzQ==";
String encryptedIv = "mxphyf6oOnVx3IoRyLtNpAjjDK1c6BCEwkdY2FwJiacsO/tpwc4KFGozNN1czwVpsifFueMN79ipY5xB/+bkQZUCEaDROQtlHVrIM2VhiBqJjY8tePtZ5t2qMckAOhDkCCDooF50D4QiliNkwXzTKu6rgIEc++kFfHI5lF/XVP3yR6y+hmfNqEU/haqJCHSKVunXvOpsAsgg9wKDFkKcjkGSSnuhi8yNHYR3DoGzwujQqKjrqrNYKonQyLA1f7lL7eGx85X2SIn3VK7oNvlg6Lf9IguQNt/o4c6e03AMTM8u9rlUCPhFuH2OYdW0d+iF9EGAgipVHTVQrncUEynrnA==";
PrivateKey privateKey = readPrivateKey(privateKeyString);
String keyBase64 = decrypt(Base64.getDecoder().decode(encryptedKey), privateKey);
String ivBase64 = decrypt(Base64.getDecoder().decode(encryptedIv), privateKey);
// Print the key and iv
System.out.println("Key (Base64): " + keyBase64);
System.out.println("IV (Base64): " + ivBase64);
// Message to encrypt
String originalMessage = "{\"merchantCode\":\"OYSS\",\"collectionReportCount\":2,\"collectionReports\":[{\"providerCode\":\"INT\",\"channelCode\":\"INB\",\"paymentRefNumber\":\"ABP|BRH|OYOS|26-02-2025|9488911\",\"paymentDate\":\"2025-02-01T17:24:40\",\"amountPaid\":100.0,\"payerName\":\"John Doe\",\"payerAddress\":\"23 Oba Akinjobi Way\",\"depositSlipNumber\":\"55669891\",\"telephoneNumber\":\"80660941931\",\"paymentMethodCode\":\"01\",\"paymentValueStatusCode\":\"00\",\"valueStatus\":\"Cleared\",\"receiptNo\":\"201361381752_2232VO72\",\"receiptDate\":\"2025-02-01T17:24:40\",\"valueDate\":\"2025-02-01T17:24:40\",\"revenueCode\":\"4010002\",\"agencyCode\":\"41503\",\"bankCode\":\"ABP\",\"branchCode\":\"IBADAN 2 (IWO RD)\",\"chequeNumber\":\"N/A\",\"chequeBankCode\":\"N/A\",\"chequeBankName\":\"N/A\",\"postedBy\":\"Cashier One\",\"transactionReference\":\"201361381752\",\"assessmentNo\":\"100080021111062\",\"controlNumber\":\"N/A\",\"paymentPeriod\":\"Jan. 2025\",\"payerId\":\"140849085\",\"platformCode\":\"\",\"paymentMethodName\":\"POS\",\"currencyCode\":\"NGN\",\"isReversed\":false,\"reversalID\":\"\",\"revenueName\":\"Direct assessment\",\"agencyName\":\"BOARD OF INTERNAL REVENUE\",\"bankName\":\"ACCESS BANK NIGERIA PLC\",\"branchName\":\"IBADAN 2 (IWO RD)\"},{\"providerCode\":\"INT\",\"channelCode\":\"INB\",\"paymentRefNumber\":\"ABP|BRH|OYOS|26-02-2025|9488912\",\"paymentDate\":\"2025-02-01T17:24:40\",\"amountPaid\":100.0,\"payerName\":\"John Doe\",\"payerAddress\":\"23 Oba Akinjobi Way\",\"depositSlipNumber\":\"556698791\",\"telephoneNumber\":\"80660941991\",\"paymentMethodCode\":\"01\",\"paymentValueStatusCode\":\"00\",\"valueStatus\":\"Cleared\",\"receiptNo\":\"201361381752_2232VO73\",\"receiptDate\":\"2025-02-01T17:24:40\",\"valueDate\":\"2025-02-01T17:24:40\",\"revenueCode\":\"401000222\",\"agencyCode\":\"4150333\",\"bankCode\":\"ABP\",\"branchCode\":\"IBADAN 2 (IWO RD)\",\"chequeNumber\":\"N/A\",\"chequeBankCode\":\"N/A\",\"chequeBankName\":\"N/A\",\"postedBy\":\"Cashier One\",\"transactionReference\":\"201361381753\",\"assessmentNo\":\"100080021111063\",\"controlNumber\":\"N/A\",\"paymentPeriod\":\"Jan. 2025\",\"payerId\":\"140849085\",\"platformCode\":\"\",\"paymentMethodName\":\"POS\",\"currencyCode\":\"NGN\",\"isReversed\":false,\"reversalID\":\"\",\"revenueName\":\"Direct assessment\",\"agencyName\":\"BOARD OF INTERNAL REVENUE\",\"bankName\":\"ACCESS BANK NIGERIA PLC\",\"branchName\":\"IBADAN 2 (IWO RD)\"}]}";
// Convert from Base64 to byte arrays
byte[] keyBytes = Base64.getDecoder().decode(keyBase64);
byte[] ivBytes = Base64.getDecoder().decode(ivBase64);
// Create key and IV specifications
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, AES_ALGORITHM);
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
// Encrypt the message
String encryptedMessage = encrypt(originalMessage.getBytes(StandardCharsets.UTF_8), keySpec, ivSpec);
System.out.println("Original message: " + originalMessage);
System.out.println("Encrypted message (Base64): " + encryptedMessage);
} catch (Exception e) {
System.err.println("Error during encryption/decryption: " + e.getMessage());
e.printStackTrace();
}
}
private static PrivateKey readPrivateKey(String base64Key) throws Exception {
// Convert from Base64 to byte array
byte[] keyBytes = Base64.getDecoder().decode(base64Key);
// Create PKCS8 key spec and generate private key
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
return keyFactory.generatePrivate(keySpec);
}
// Decrypt a message using RSA private key
private static String decrypt(byte[] encryptedData, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = cipher.doFinal(encryptedData);
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
// Encrypt data using AES with CBC mode and PKCS5 padding
private static String encrypt(byte[] data, SecretKeySpec keySpec, IvParameterSpec ivSpec) throws Exception {
Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encryptedBytes = cipher.doFinal(data);
return Base64.getEncoder().encodeToString(encryptedBytes);
}
}
}