Persistent Payment Identifier

Generate a Paga persistent payment identifier for your customers

Persistent payment identifiers are static payment identifiers generated from Paga that allow merchants to receive payment via Bank Transfers. This payment identifier does not expire and allows merchants to receive payment in perpetuity from the customer unless deleted or deactivated by the merchant

📘

Persistent vs Dynamic Payment Identifier

  • Persistent Payment Identifier: For repeat use, linked to a customer permanently. Must be deleted to deactivate.
  • Dynamic Payment Identifier: For one-time use only. Expires after a transaction or set time.

How to Get Paid Using a Persistent Payment Identifier

3 Simple Steps

  1. Generate a persistent payment identifier for your customer.
  2. Display it with the bank name Paga.
  3. After successful payment, we will send you a callback with details of the payment.

Step 1: Get all the needed information

Below is the list of parameters required to generate a payment identifier

Argument

Data Type

Description

Required

referenceNumber

String

A unique reference number representing this request. The same reference number will be returned in the response and can be used to query the payment request status
hashIndex-1

True

phoneNumber

String

The phone number of the customer. This must be provided if the email is not provided.

True

accountName

String

The acountname of the customer.

True

firstName

String

The first name of the customer

True

lastName

String

The last name of the customer

True

accountReference

String

This is a unique reference number provided by the Organization which identifies the persistent payment identifier. It should have a minimum length of 12 characters and a maximum length of 30 characters
hashIndex-2

True

financialIdentificationNumber

String

BVN of the customer
hashIndex-3

False

email

String

The email of your customer. This must be provided if the phoneNumber is not provided.

False

creditBankId

String

If included, this is the UUID of the bank that you want deposits to be transferred directly to for every payment. You can get destination bank UUID from getBank Endpoint
hashIndex-4

False

creditBankAccountNumber

String

This must be provided if creditBankId is included in the request payload. It is the payment identifier of the bank that you want deposits to be transferred to. This must be a valid payment identifier for the bank specified by creditBankId
hashIndex-5

False

callbackUrl

String

A custom callback URL for the payment webhook notifications for this specific account to be sent to. If provided, requests are sent to this URL exactly as provided. This allows you to set custom query parameters to the URL which you will be provided during webhook notifications for this specific account.
hashIndex-6

False


How to Generate the Hash (HMAC)

To secure the request, compute an HMAC SHA-512 hash over the concatenated string of selected parameters in this order:

referenceNumber + accountReference + creditBankId + creditBankAccountNumber + callbackUrl
  • Omit any empty/null fields but do not change the order**.
  • Then generate the hash using your HMAC secret key.

Example in Javascript

const crypto = require("crypto");

function generateHash(payload,HMAC) {
  const rawData = payload.referenceNumber + payload.phoneNumber +
    payload.accountName + payload.accountReference +
    (payload.financialIdentificationNumber || "") +
    (payload.creditBankId || "") +
    (payload.creditBankAccountNumber || "") +
    (payload.callbackUrl || "") + HMAC;

  return crypto.createHmac("sha512").update(rawData).digest("hex");
}

Sample Request

POST /registerPersistentPaymentAccount HTTP/1.1
Host: beta-collect.paga.com
Content-Type: application/json
Authorization: "Basic base64(public Key:secret Key)"
hash: SHA-512(referenceNumber + accountReference + creditBankId + creditBankAccountNumber + callbackUrl + hashkey)
{
    "referenceNumber": "129632292292",
    "phoneNumber": "08012345678",
    "firstName": "Sample",
    "lastName": "Sample",
    "accountName": "Sample Sample",
    "accountReference": "0123872282456789",
    "callbackUrl": "https://webhook.site/850426c5-128e-4e23-a38d-7f0e21b9300c"
}

Sample Success Response

{
    "referenceNumber": "129632292292",
    "statusCode": "0",
    "statusMessage": "success",
    "accountReference": "123467891334",
    "accountNumber": "1061871576"
}

Step 3: Share the Payment Identifier

Show the account details in your app or via email:

  • Payment Identifier: 1061871576
  • Bank: Paga

Step 4: Handle Payment Callback

After every payment, we’ll send a callback notification to the callback URL you provided in your request
More about callback parameters

{
  "statusCode": "0",
  "statusMessage": "success",
  "transactionReference": "SC-C_20220915113942190_4293418_ND8K0_6dg5g",
  "fundingPaymentReference": null,
  "accountNumber": "2830163290",
  "accountName": "Bellview Walker",
  "financialIdentificationNumber": null,
  "amount": "200.00",
  "clearingFeeAmount": "1.50",
  "payerDetails": {
    "payerAccountNumber": "0745089449",
    "paymentReferenceNumber": null,
    "paymentMethod": "MONEY_TRANSFER",
    "payerName": "Bello Ramon"
  },
  "hash": "0d57b7d8d1a21a94eec7edd951aaeaeb5e8597672d05fb732f146e93e79ac7caa520ff86ed069f28c3322e469af4898a7d72f3e0c83d919d61c535140b4eef8e"
}
📘

Is callback retry available? Yes

The persistent payment identifier callback retries as follows:

  • At the initial time when the payment is made, it tries three times in succession to notify your endpoint with the following intervals: immediately, 1 second later, 5 seconds later, 15 seconds later

  • If none is successful, it gets added to a queue for intermittent retries every 5 minutes for the next 30 minutes or until a callback is successful

With the above, there shouldn't be any case where you do not receive the notification callback unless your callback endpoint is offline for more than 30 minutes

We have few more endpoint available to give you more flexibility


What’s Next