Version |
Date |
Author |
Comments |
Draft |
10/01/2021 |
bgrobler |
Initial |
1.1.2 |
23/06/2021 |
bgrobler |
Add reference and institution id description. |
1.1.3 |
15/07/2021 |
bgrobler |
Add push/pull transaction description. |
1.1.3-1 |
19/07/2021 |
bgrobler |
Change BSP to PSP, Remove architecture diagram (superseded transaction description diagrams) |
1.2.0 |
23/07/2021 |
bgrobler |
Remove |
1.2.1 |
19/08/2021 |
bgrobler |
modify section3.3 - include authorizedCredentialId and merchantId information |
1.2.1-1 |
06/09/2021 |
bgrobler |
update references to change reference between req/rsp pair. Update camelCasing for
|
1.3.0 |
11/03/2022 |
bgrobler |
add response code, and field definitions. |
1.4.0 |
27/04/2022 |
bgrobler |
add response codes section (helper) for auth response, Add 2.2 - Protocol (describes the PayGo REST API), Update expirySeconds description to be more informative. |
1.5.0 |
17/05/2022 |
bgrobler |
rename document to REST API Transaction Protocol Specification, Add EMVco QR Code specification |
| This document is only intended for the recipient only and may not be used, shared, published or distributed without the prior written consent of Veritran (Pvt) Ltd t/a ZSS |
2. Integration
The PayGo API is an enrichment of the Vsuite Bridge Protocol.
Each PayGo Transaction is a strict contract between PayGo and the Member, any non-compliant messages will be dropped. See the PayGo Contract for further details concerning compliance and SLA.
2.1. Concepts & Terms
2.1.1. PayGo Directory Services (PayGo DS)
PayGo DS is a central routing/validation service that allows prefix allocation and message routing between numerous organizations.
2.1.2. Credential
A credential is the way to identify a payment method, for example it may represent a bank account at a specific institution, or it may represent a token (a card) at a network, an acceptor at an acquirer, etc.
2.1.3. Push vs Pull Transaction
There are currently two methods of processing a transaction between financial institutions (or between payer and payee, customer and merchant, etc).
2.1.4. Point of Capture Initiator
PCI represents the point at which a code was captured and turned into a lookup, i.e. a mobile phone has entered into a PayGo Members mobile banking and entered the code that was displayed.
2.1.5. Transaction Originator
A TO creates a transaction, it is the first point at which at financial transaction is originated, typically this is the customer’s bank.
On receipt of a valid AUTH response, a TO is expected to construct a transaction that will be sent to PayGo DS.
Critically, a TO must act on the following information
| A payment is not the same as transaction, a transaction is used to effect a payment. |
2.1.6. Nominated Credential
This field indicates how the merchant / person can be paid, therefore, depending on the credential type, the financial transaction can be constructed in various ways.
Type |
Description |
Action |
ACCEPTOR |
This indicates that this credential (merchant/person account) is overlayed as a cardAcceptorId & terminalId pair |
Construct a transaction that has cardAcceptorId set to nominatedCredential.additionalData.cardAcceptorId, terminalId set to nominatedCredential.additionalData.terminalId acquiringInstitutionId set to nominatedCredential.institutionId usually card based though there may be exceptions (i.e. set debitAccount), set this based on availability of the Transaction Originator. |
2.1.7. Requested Payment
A requested payment, is a payment that has been created at the MSP, and now available to be paid. it indicates critical information, such as, amount, narration, currency, etc.
In the event that a AUTH response contains a requestedPayment, the TO must override the acceptance flow i.e. if requestedPayment.amount is set, then the user must not be requested to capture it, the same follows for narration. The initiator field may be shown to the user to indicate who/what initiated this payment, for example "Till No.3 - A. Another". The MSP is responsible for "payment initiation", and therefore must specify the expiry of the payment, i.e. what is the period of time that the payment is valid.
| In the local market (ZWE), if the currency of the users selected payment method, does not match the requested currency, then the payment must be aborted, or a different payment method selected. |
2.1.8. References
A paymentReference is provided by PayGo for a completed transaction, this is shared between the PSP, DS, and MSP, therefore, each payment can be tracked by this paymentReference.
2.1.9. Institution ID’s
As a transaction transits the ecosystem, it must identify where it is coming from, who it is going to, who will it be forwarded too, etc.
| Field | Description |
|---|---|
|
The institution that captured the transaction. Point of Capture Initiator |
|
not set |
|
The prefix of the MSP. |
Field |
Description |
|
The institution id (bin) of the institution that can settle the merchant. |
|
not set |
|
The prefix of the MSP. |
2.2. Protocol
2.2.1. HTTP Request Headers
| Header | Type | Format | Example | Description |
|---|---|---|---|---|
X-Api-Key |
String |
VAR36 UUID |
5c177bee-deeb-4273-9966-51359e47fc54 |
See link:API Key |
Accept-Version |
String |
VAR255 vM.m.p (M - Major, m - minor, p - patch) |
v1.0.0 |
API Version Information |
Content-Type |
String |
VAR |
application/json |
Encoding information |
2.2.2. HTTP Response Headers
| Header | Type | Format | Example | Description |
|---|---|---|---|---|
X-Api-Key |
String |
VAR36 UUID |
5c177bee-deeb-4273-9966-51359e47fc54 |
See link:API Key |
Accept-Version |
String |
VAR255 vM.m.p (M - Major, m - minor, p - patch) |
v1.0.0 |
API Version Information |
Content-Type |
String |
VAR |
application/json |
Encoding information |
2.2.3. Fields
| Field | Type | Format | Mandatory | Example | Description |
|---|---|---|---|---|---|
acquiringInstitutionId |
String |
N.11 |
Y |
123456 |
The institution who originated (acquired) the transaction and/or maintains the merchant. |
additionalData |
Complex |
O |
|
Additional variables |
|
amount |
Number |
D19.2 |
*O |
12345.67 |
Transaction Amount |
balances |
Complex |
O |
|
Balances of debitAccount |
|
card |
Complex |
O |
|
Card |
|
cardAcceptorId |
String |
AN15 |
Y |
123456789012345 |
Id of the card acceptor (usually merchant id) |
cardAcceptorNameLocation |
Complex |
N |
|
Merchant Information |
|
channel |
String |
VAR255 |
Y |
SMARTPHONE |
Field to identify the platform on which this transaction originated |
created |
String |
VAR255 ISO86012 Timestamp |
Y |
2021-01-19T14:06:34.223+02:00 |
Timestamp representing the creation of the transaction. |
creditAccount |
Complex |
*O |
|
Account to be credited / to account. |
|
creditReference |
String |
VAR255 |
*O |
000000003232 |
A reference from the system the performed the credit. |
currencyCode |
String |
ISO4217-alpha3 |
Y |
USD |
Transaction Currency Code (of the 'amount' field) |
debitAccount |
Complex |
*O |
|
Account to be debited, or queried if type is ENQUIRY, etc. |
|
debitReference |
String |
VAR255 |
O |
74e68e29-ae0d-4bf0-bf3c-5628aeb4e662 |
A reference from the system the peformed a debit. |
destinationInstitutionId |
String |
N.11 |
O |
654321 |
The destination institution used to process this transaction, (commomly used for routing and reporting purposes) |
destinationMsisdn |
String |
N.20 ITU-T e.164 |
O |
554545455454 |
The msisdn that was the beneficiary of thie transaction, common in transfer, payments, etc. |
deviceReference |
String |
VAR255 |
O |
db7c708ccb43 |
A reference from the transaction acceptor (usually an RRN) |
extendedType |
String |
VAR255 |
Y |
P2P |
Additional tag to identify this transaction (common to provide metainfo) |
forwardingInstitutionId |
String |
N.11 |
O |
999999 |
The institution that has forwarded this transaction, usually identifying a network or processor, however commonly used for ancialliary routing purposes. |
transactionFees |
Complex |
O |
|
Fee’s to be charged for this transaction. |
|
settlementFees |
Complex |
0 |
|
Fee’s to charged for this transaction (usually specified in the response). |
|
issuingInstitutionId |
String |
N.11 |
O |
111111 |
The issuer of the card / accounts related to this transaction |
messageRepeats |
Number |
N.2 |
O |
0 |
Indicates how many times this message has been re-transmitted. |
messageType |
String |
VAR255 |
Y |
REQUEST |
Indicates the type of 'request' |
msisdn |
String |
N.20 ITU-T e.164 |
O |
4343545654 |
The mobile number of the initiator of this transaction (commonly used for notification purposes) |
narration |
String |
VAR255 |
O |
Pay you back for dinner |
A description of this transactions purpose capured by the original initiator of the transaction. |
network |
String |
VAR255 |
O |
VODAFONE |
The network on which this transaction was captured |
traceId |
String |
VAR255 |
M |
tRBGIzztumxbZOeYLDzXMl |
A system id generated by the source system that correlates all subsequent activities for the purposes of tracing and troubleshooting. |
originalCreated |
String |
VAR255 ISO8601 Timestamp |
*O |
2020-06-10T13:50:02.922+02:00 |
Time at which the original transaction was created (commonly used in ADVICE transactions) |
originalParticipantReference |
String |
*O |
2959e6c1-0e90-476e-b614-4c2ced967366 |
||
originalReference |
String |
*O |
5e790f84-4ffe-4b17-9541-709c99afd110 |
||
participantReference |
String |
VAR255 |
500d4038-66b3-443e-911a-a8bfa95de23e |
The reference generated by the participant (unique by participant) |
|
payee |
String |
VAR255 |
O |
A. ANOTHER |
|
payeeProduct |
String |
VAR255 |
O |
DEFAULT |
|
paymentMethod |
String |
VAR255 |
O |
ACCOUNT |
The method used to debit the originator of this transaction. |
reference |
String |
VAR36 UUIDv4 |
Y |
2385d527-4fa3-486a-b743-5111229b63a3 |
Reference generated by the receiving system, intended to correlate the request and response. |
responseCode |
String |
N3 |
*O |
000 |
The status of this transaction. |
responseDescription |
String |
VAR255 |
*O |
APPROVED |
|
terminalId |
String |
AN8 |
Y |
12345678 |
|
paymentReference |
String |
VAR255 |
*O |
TRBG-IZZT-UMXB-ZOEY |
Link all transaction realted to a payment and shared with third parties to identify this payment. |
type |
String |
VAR255 |
Y |
CREDIT_PUSH |
|
upstreamResponseCode |
String |
VAR255 |
*O |
00 |
|
upstreamResponseDescription |
String |
VAR255 |
*O |
APPROVED |
2.2.4. Message Types
Type |
Description |
ADVICE |
An advice (must process) of a financial transaction. |
REQUEST |
A financial transaction request. |
REVERSAL |
A reversal of a financial transaction request. |
2.2.5. Transaction Types
| Type | Description |
|---|---|
PURCHASE |
A purchase transaction |
2.2.6. Extended Types
| Type | Description |
|---|---|
P2M |
A Person to Merchant Transaction |
2.2.7. AdditionalData
Represents a dictionary of Key Values, where the Key is a String, and the Value is an Object.
This element is used to hold various metadata.
{
"KEY": {
"value": "foo"
},
"ANOTHER_KEY": "BAR"
}
2.2.8. Balances
[
{
"balance": 997861.8,
"balanceType": "LEDGER",
"currency": "USD"
},
{
"balance": 997861.8,
"balanceType": "AVAILABLE",
"currency": "USD"
}
]
2.2.9. Card
{
"expiry": "2025-12-01",
"pan": "6058720040005994",
"sequenceNumber": null,
"serviceRestrictionCode": null,
"track2": null,
"pinData": null
}
2.2.10. Account
{
"currency": "USD",
"id": "0242310812",
"product": null,
"type": "00"
}
2.2.12. CardAcceptorNameLocation
{
"name": "ACME SHOP",
"address": "",
"city": "Harare",
"region": "Af",
"countryCode": "ZW",
"phoneNumber": "4459596222",
"url": "http: //bit.ly/3443ccr3",
"emailAddress": "merchant@acme.com"
}
2.2.13. MinistatementData
[
{
"amount": 123.45,
"currency": "ZWL",
"destinationAccountId": "4000000011149649",
"feeAmount": 0,
"location": "Joe Blogs",
"narration": "paying you back for dinner the other night",
"reference": "TRBG-IZZT-UMXB-ZOEY",
"sourceAccountId": "4000000011149649",
"sourceAccountType": "00",
"transactionDate": "2020-06-14T23:50:37.322+02:00",
"transactionType": "27",
"transactionTypeDesc": "Payment Credit (VISA Direct)"
},
{
"amount": 123.45,
"currency": "ZWL",
"destinationAccountId": "0001234560",
"feeAmount": 0,
"location": "Acme Another",
"narration": "paying you back for breakfast the other morning",
"reference": "6HL2-V2G6-32CA-20M6",
"sourceAccountId": "0001234560",
"sourceAccountType": "00",
"transactionDate": "2020-06-14T23:50:37.322+02:00",
"transactionType": "27",
"transactionTypeDesc": "Payment Credit (ZIPIT)"
}
]
3. Roles
3.1. Financial Institution
An FI is the primary funding institution for all financial impact transactions that occur on the PayGo Network. MSP’s must have a relationship with an FI to create a Credential - and therefore receive funds. PSP’s must have a relationship (albeit the same institution in most cases) with an FI to originate authorized transactions into the PayGo network and thus permit onward settlement.
3.2. Payment Service Provider (PSP)
PSP’s provide service to the customer, i.e. a Bank creating a platform to allow their customers access to the PayGo ecosystem. They are primarily responsible for "originating" a financial transaction, a Transaction Originator
A PSP requires a "sponsor/partnering" Financial Institution to operate.
3.2.1. Transaction Sets
| TxnRef | Description | Message | Type | Extended | API Reference |
|---|---|---|---|---|---|
1 |
PSP P2M PayGoID Query |
AUTH |
PURCHASE |
MERCHANT_ALIAS |
|
2 |
PSP P2M PayGoID Tran |
REQUEST |
PURCHASE |
P2M |
3.2.2. Transactions
P2M - PayGoID / Merchant Code
Summary
Person to Merchant (P2M) transaction, to effect a payment between a payer (person) and a merchant (payee), using the payee’s PayGoID to retrieve the nominated credential.
The following examples represent the flow of transactions from the initiator to PayGo Directory Services (DS).
Examples
{
"acquiringInstitutionId": "605872",
"additionalData": {
"entryType": "MANUAL",
"pointOfInitiation": "QR_STATIC",
"directoryQuery": {
"alias": "40044",
"type": "MERCHANT_ALIAS"
},
"complianceData": {
"origin": {
"contactNumber": "N/A",
"emailAddress": "N/A",
"firstName": "N/A",
"lastName": "N/A",
"nationalId": "N/A",
"type": "PERSON"
}
}
},
"amount": 0,
"card": {
"expiry": "2025-12-30",
"pan": "6058720040005994"
},
"cardAcceptorId": "605872000009001",
"channel": "USSD",
"created": "2021-06-16T10:24:43.594+02:00",
"currencyCode": "ZWL",
"extendedType": "MERCHANT_ALIAS",
"forwardingInstitutionId": "400",
"messageDirection": "REQUEST",
"messageType": "AUTH",
"msisdn": "263772726298",
"network": "econet",
"participantReference": "db47acf4-1b4c-4bd5-b7a1-12eb9046c150",
"payee": "40044",
"paymentMethod": "CARD",
"reference": "ddc51524-c1c4-4305-967c-c2d9e7ece925",
"terminalId": "MFS09001",
"traceId": "u1ikdoKHnMtbZtGhyaVkSr",
"type": "PURCHASE"
}
{
"acquiringInstitutionId": "605872",
"additionalData": {
"directoryInformation": {
"name": "Acme Shop",
"nominatedCredential": {
"credential": "12341234",
"currencyCode": "ZWL",
"institutionId": "605872",
"type": "ACCEPTOR"
},
"requestedPayment": {
"amount": 5,
"currencyCode": "ZWL",
"narration": "bananas",
"expirySeconds": 600,
"initiator": "A. Another (Acme Shop)"
},
"sourceDirectoryName": "paygo_msp",
"type": "MERCHANT"
},
"complianceData": {
"origin": {
"type": "PERSON",
"firstName": "N/A",
"lastName": "N/A",
"nationalId": "N/A",
"contactNumber": "N/A",
"emailAddress": "N/A"
}
}
},
"amount": 0,
"cardAcceptorId": "605872000009001",
"channel": "USSD",
"created": "2021-06-16T10:24:43.594+02:00",
"currencyCode": "ZWL",
"deviceReference": "3c096f9f-ce7c-11eb-8ffd-b1eed8df0d79",
"extendedType": "MERCHANT_ALIAS",
"forwardingInstitutionId": "400",
"messageDirection": "RESPONSE",
"messageType": "AUTH",
"msisdn": "263772726298",
"network": "econet",
"participantReference": "db47acf4-1b4c-4bd5-b7a1-12eb9046c150",
"payee": "40044",
"paymentMethod": "CARD",
"reference": "ddc51524-c1c4-4305-967c-c2d9e7ece925",
"responseCode": "000",
"responseDescription": "APPROVED",
"terminalId": "MFS09001",
"type": "PURCHASE"
}
{
"acquiringInstitutionId": "605872",
"additionalData": {
"complianceData": {
"origin": {
"contactNumber": "N/A",
"emailAddress": "N/A",
"firstName": "N/A",
"lastName": "N/A",
"nationalId": "N/A",
"type": "PERSON"
}
}
},
"amount": 5,
"card": {
"expiry": "2025-12-30",
"pan": "6058720040005994"
},
"cardAcceptorId": "605872000009001",
"channel": "USSD",
"created": "2021-06-16T10:24:46.165+02:00",
"creditAccount": {
"id": "12341234"
},
"currencyCode": "ZWL",
"extendedType": "P2M",
"forwardingInstitutionId": "400",
"messageDirection": "REQUEST",
"messageType": "REQUEST",
"msisdn": "263772726298",
"narration": "bananas",
"network": "econet",
"originalParticipantReference": "db47acf4-1b4c-4bd5-b7a1-12eb9046c150",
"originalReference": "db47acf4-1b4c-4bd5-b7a1-12eb9046c150",
"participantReference": "13081b4e-8463-4cac-afdd-037988efbcd6",
"payee": "40044",
"paymentMethod": "CARD",
"reference": "67b72bda-d9ab-4086-8bae-25f599b28b8f",
"terminalId": "MFS09001",
"traceId": "dHJ22OJFpqldWriuItNbgo",
"type": "PURCHASE"
}
{
"acquiringInstitutionId": "605872",
"additionalData": {
"complianceData": {
"origin": {
"contactNumber": "N/A",
"emailAddress": "N/A",
"firstName": "N/A",
"lastName": "N/A",
"nationalId": "N/A",
"type": "PERSON"
}
}
},
"amount": 5,
"card": {
"expiry": "2025-12-30",
"pan": "6058720040005994"
},
"cardAcceptorId": "605872000009001",
"channel": "USSD",
"created": "2021-06-16T10:24:46.475+02:00",
"creditAccount": {
"id": "12341234"
},
"currencyCode": "ZWL",
"debitReference": "000000000000",
"deviceReference": "3c096f9f-ce7c-11eb-8ffd-b1eed8df0d79",
"extendedType": "P2M",
"forwardingInstitutionId": "400",
"messageDirection": "RESPONSE",
"messageType": "REQUEST",
"msisdn": "263772726298",
"narration": "bananas",
"network": "econet",
"originalParticipantReference": "db47acf4-1b4c-4bd5-b7a1-12eb9046c150",
"originalReference": "db47acf4-1b4c-4bd5-b7a1-12eb9046c150",
"participantReference": "13081b4e-8463-4cac-afdd-037988efbcd6",
"payee": "40044",
"paymentMethod": "CARD",
"paymentReference": "EEWR4AS4MX62LSC1N40F54NYDM",
"reference": "1756e334-eef8-4eee-a58a-e6b18e28fbd0",
"responseCode": "000",
"responseDescription": "Approved",
"terminalId": "MFS09001",
"traceId": "dHJ22OJFpqldWriuItNbgo",
"type": "PURCHASE"
}
3.3. Merchant Service Provider (MSP)
MSP’s provide service to a merchant (or numerous merchants), and are allocated a specific prefix by PayGo.
The service is that of payment lookup and advice, such that the MSP’s responsibility is to answer a request from PayGo where PayGo has captured a Merchant Code / Dynamic Code ( both referred to as PayGoID’s), This answer (if successful) must contain relevant information for the specific code, i.e. tying a code to a merchant, or to a specific merchants "pending payment" (in the case of dynamic).
The relevant information is specified as an authorizedCredentialId which will be returned to the PSP as a Nominated Credential, a merchantId which will indicate which merchant this payment is for (see the PayGo Admin API for further information), and any other ancillary information complementary to the payment process (such as a Requested Payment).
An MSP is a completely autonomous concept, and provided that they honour the API call’s, the method by which this is achieved is entirely at the discretion of the MSP.
| PayGo requires that the merchant and their credentials are registered with the Directory Service, if the credential and / or merchant returned are not registered, the payment will be declined, and an message sent to the MSP advising of the decline, the payment cannot proceed. See the PayGo Admin API for further information regarding this registration process. |
3.3.1. Transaction Sets
| TxnRef | Description | Message | Type | Extended | API Reference |
|---|---|---|---|---|---|
1 |
MSP P2M PayGoID Query |
AUTH |
PURCHASE |
MERCHANT_ALIAS |
|
2 |
MSP Payment Notification |
ADVICE |
PURCHASE |
P2M |
3.3.2. Transactions
MSP P2M - PayGoID / Merchant Code
Summary
Person to Merchant (P2M) transaction, to effect a payment between a payer (person) and a merchant (payee), using the payee’s PayGoID to retrieve the nominated credential.
The following examples represent the flow of transactions from PayGo Directory Services (DS) to the MSP.
Examples
{
"acquiringInstitutionId": "605872",
"additionalData": {
"directoryQuery": {
"alias": "40044",
"type": "MERCHANT_ALIAS"
},
"complianceData": {
"origin": {
"contactNumber": "N/A",
"emailAddress": "N/A",
"firstName": "N/A",
"lastName": "N/A",
"nationalId": "N/A",
"type": "PERSON"
}
},
"entryType": "MANUAL",
"pointOfInitiation": "QR_STATIC"
},
"amount": 0,
"card": {
"expiry": "2025-12-30",
"pan": "6058720040005994"
},
"cardAcceptorId": "605872000009001",
"channel": "USSD",
"created": "2021-06-16T10:24:43.594+02:00",
"currencyCode": "ZWL",
"extendedType": "MERCHANT_ALIAS",
"forwardingInstitutionId": "400",
"messageDirection": "REQUEST",
"messageType": "AUTH",
"msisdn": "263772726298",
"network": "econet",
"participantReference": "db47acf4-1b4c-4bd5-b7a1-12eb9046c150",
"payee": "40044",
"paymentMethod": "CARD",
"reference": "ddc51524-c1c4-4305-967c-c2d9e7ece925",
"terminalId": "MFS09001",
"traceId": "u1ikdoKHnMtbZtGhyaVkSr",
"type": "PURCHASE"
}
{
"acquiringInstitutionId": "605872",
"additionalData": {
"complianceData": {
"origin": {
"type": "PERSON",
"firstName": "N/A",
"lastName": "N/A",
"nationalId": "N/A",
"contactNumber": "N/A",
"emailAddress": "N/A"
}
},
"directoryService": {
"merchantId": "efd59fb8-e850-47d1-ab1d-257e0fe0fcc0",
"authorizedCredentialId": "0469aafe-9961-4c53-8bf5-b4be45ab8b07",
"requestedPayment": {
"amount": 5.00,
"currencyCode": "ZWL",
"narration": "bananas",
"expirySeconds": 600,
"initiator": "A. Another (Acme Shop)"
}
}
},
"amount": 0,
"cardAcceptorId": "605872000009001",
"channel": "USSD",
"created": "2021-06-16T10:24:43.594+02:00",
"currencyCode": "ZWL",
"extendedType": "MERCHANT_ALIAS",
"forwardingInstitutionId": "400",
"messageType": "AUTH",
"msisdn": "263772726298",
"network": "econet",
"participantReference": "db47acf4-1b4c-4bd5-b7a1-12eb9046c150",
"payee": "40044",
"paymentMethod": "CARD",
"reference": "ddc51524-c1c4-4305-967c-c2d9e7ece925",
"terminalId": "MFS09001",
"type": "PURCHASE",
"responseCode": "000",
"responseDescription": "APPROVED",
"deviceReference": "3c096f9f-ce7c-11eb-8ffd-b1eed8df0d79"
}
The directoryService object must contain a previously created Merchant / Authorized Credential Pair as this is what indicates to PayGo DS what directoryInformation (with nominated credential) object to send back to the PSP.
see the PayGo Admin API for more information.
|
| Response Code | Description | Comment |
|---|---|---|
000 |
Approved |
(Expect credential and requestedPayment - i.e. directoryInformation) |
001 |
Generic Error |
failure to process payment due to non-technical error i.e. not exceptional. |
003 |
Merchant Not Found |
in the event that the code (PayGoId) is not found. |
006 |
Error |
indicates an error occurred (i.e. a known exception - (handled) has occurred and the payment cannot proceed) |
096 |
System Malfunction |
an error has occurred that is unhandled. |
MSP - Payment Notification
Summary
A Merchant Service Provider (MSP) offers a payment service on behalf of merchants, it is not the immediate recipient of the financial transaction, a notification is sent to the MSP upon completion of the transaction (approved/declined) to advise the status of the financial transaction.
| This is an ADVICE class message, meaning that it will be repeated until acknowledged. |
Examples
{
"acquiringInstitutionId": "605872",
"additionalData": {
"complianceData": {
"origin": {
"contactNumber": "N/A",
"emailAddress": "N/A",
"firstName": "N/A",
"lastName": "N/A",
"nationalId": "N/A",
"type": "PERSON"
}
}
},
"amount": 5,
"card": {
"expiry": "2025-12-30",
"pan": "6058720040005994"
},
"cardAcceptorId": "605872000009001",
"channel": "USSD",
"created": "2021-06-16T10:24:46.483+02:00",
"creditAccount": {
"id": "12341234"
},
"currencyCode": "ZWL",
"debitReference": "000000000000",
"deviceReference": "3c096f9f-ce7c-11eb-8ffd-b1eed8df0d79",
"extendedType": "P2M",
"forwardingInstitutionId": "400",
"messageDirection": "REQUEST",
"messageType": "ADVICE",
"msisdn": "263772726298",
"narration": "bananas",
"network": "econet",
"originalCreated": "2021-06-16T10:24:46.475+02:00",
"originalParticipantReference": "13081b4e-8463-4cac-afdd-037988efbcd6",
"originalReference": "1756e334-eef8-4eee-a58a-e6b18e28fbd0",
"participantReference": "13081b4e-8463-4cac-afdd-037988efbcd6",
"payee": "40044",
"paymentMethod": "CARD",
"paymentReference": "EEWR4AS4MX62LSC1N40F54NYDM",
"reference": "1e098591-2227-4029-86f1-e320e73f991e",
"responseCode": "000",
"responseDescription": "Approved",
"terminalId": "MFS09001",
"traceId": "fquCGlvTecGOpzEmnkEIjs",
"type": "PURCHASE"
}
{
"acquiringInstitutionId": "605872",
"additionalData": {
"complianceData": {
"origin": {
"type": "PERSON",
"firstName": "N/A",
"lastName": "N/A",
"nationalId": "N/A",
"contactNumber": "N/A",
"emailAddress": "N/A"
}
}
},
"amount": 5,
"cardAcceptorId": "605872000009001",
"channel": "USSD",
"created": "2021-06-16T10:24:46.483+02:00",
"currencyCode": "ZWL",
"extendedType": "P2M",
"forwardingInstitutionId": "400",
"messageType": "ADVICE",
"msisdn": "263772726298",
"narration": "bananas",
"network": "econet",
"participantReference": "13081b4e-8463-4cac-afdd-037988efbcd6",
"payee": "40044",
"paymentMethod": "CARD",
"reference": "1e098591-2227-4029-86f1-e320e73f991e",
"terminalId": "MFS09001",
"type": "PURCHASE",
"responseCode": "000",
"responseDescription": "APPROVED",
"paymentReference": "EEWR4AS4MX62LSC1N40F54NYDM",
"deviceReference": "3c096f9f-ce7c-11eb-8ffd-b1eed8df0d79"
}
3.3.3. Response Codes
| Response Code | Description | Final |
|---|---|---|
000 |
Approved, The payment may be completed successfully. |
yes |
001 |
Contact Issuer |
no |
002 |
Future |
no |
003 |
Invalid Merchant |
no |
004 |
Future |
no |
005 |
Do not honour |
no |
006 |
Error |
no |
007-008 |
Future |
no |
009 |
Request in progress |
no |
010 |
Approved Partial |
no |
011-012 |
Future |
no |
013 |
Invalid Amount |
no |
014 |
Invalid Card |
no |
015 |
Invalid Issuer |
no |
016-018 |
Future |
no |
019 |
Reenter Transaction |
no |
020 |
Invalid Response |
no |
021 |
No action taken |
no |
022-024 |
Future |
no |
025 |
Not Found |
no |
026 |
Duplicate |
no |
027 |
Incomplete |
no |
028-029 |
Future |
no |
030 |
Format Error |
no |
040 |
Function Not Support |
no |
041 |
Card on Hold |
no |
042 |
Invalid Account |
no |
043-044 |
Future |
no |
045 |
Account Closed |
no |
046-047 |
Future |
no |
048 |
No Customer Record |
no |
049-050 |
Future |
no |
051 |
Insufficient Funds |
no |
052-053 |
Future |
no |
054 |
Expired Card |
no |
055 |
Invalid Pin |
no |
056 |
Future |
no |
057 |
Transaction not permitted |
no |
058-059 |
Future |
no |
060 |
Contact Acquirer |
no |
061 |
Exceeds Limit |
no |
062 |
Restricted Card |
no |
063 |
Security Violation |
no |
064-066 |
Future |
no |
067 |
Pick up card |
no |
068 |
Payment Expired, The payment did not complete within the expiry window. |
yes |
069-074 |
Future |
no |
075 |
Pin tries exceeded |
no |
076-090 |
Future |
no |
091 |
Timeout |
no |
092 |
Routing Error |
no |
093-094 |
Future |
no |
095 |
Reconciliation Error |
no |
096 |
System Malfunction |
no |
097-ZZZ |
Future |
no |
4. Data Structures
| Unless otherwise specified all fields are limited to VAR255 (ANS) |
4.1. Directory Query
This object is used to provide information to the directory to execute a query.
{
"type": "PERSON_ALIAS",
"alias": "80017"
}
| Field | Description |
|---|---|
type |
Indicates the “Type” of query that is to be executed, this information may not necessarily be available in the directory, however it is informational and may be acted upon if available. Available Options: PERSON_ALIAS, MERCHANT_ALIAS, PERSON_MSISDN, PERSON_EMAIL_ADDRESS |
alias |
The information to be searched in the directory, specifically the 'alias' field, this may be a “Merchant Code”, “PayGoID”, "PayGoCode" as an example. |
4.2. Directory Service
This object is the response to a successful information query from an MSP.
{
"merchantId": "a57b1a23-b379-4794-b708-293d51c9c735",
"authorizedCredentialId": "039dc851-498c-4f74-b33e-60e5711e2459",
"requestedPayment": {
"amount": 5.00,
"currencyCode": "ZWL",
"narration": "bananas",
"expirySeconds": 600,
"initiator": "A. Another (Acme Shop)"
}
}
4.3. Directory Information
This object is the response to a successful information query from PayGo.
{
"type": "PERSON",
"alias": "80017",
"name": "Acme Another",
"contactNumber": "26377555444212",
"emailAddress": "aanother@acmemail.com",
"addressLine1": "123 Acme Rd",
"addressLine2": "Acme Gardens",
"city": "Acme",
"country": "Acme",
"requestedPayment": {
"amount": 5.00,
"currencyCode": "ZWL",
"narration": "bananas",
"expirySeconds": 600,
"initiator": "A. Another (Acme Shop)"
},
"nominatedCredential": {
"credentialType": "ACCEPTOR",
"institutionId": "411111",
"currencyCode": "ZWL",
"additionalData": {
"cardAcceptorId":"123456789012345",
"cardAcceptorTerminalId":"12345678"
}
},
"sourceDirectoryName": "ACME_BANK"
}
| Field | Description |
|---|---|
type |
The type of entry Available Options: PERSON, MERCHANT |
name |
The display name of the entity |
alias |
The associated alias (primarily used for lookup) |
contactNumber |
The phone number of the entity (ITU-T e.164) |
*emailAddress |
The email address of the entity |
addressLine1 |
The address of the entity |
addressLine2 |
The address of the entity |
city |
The city in which the entity is located |
country |
The country in which the entity is located |
requestedPayment |
The payment that has been requested by the payee. [Optional - Required for dynamic payments.] |
nominatedCredential |
The credential associated with this directory entry |
sourceDirectoryName |
Indicates the directory where this information eventually originated. |
4.4. Requested Payment
A payment request, if this object is set the transaction must comply to the values specified.
{
"amount": 123.45,
"currencyCode": "ZWL",
"narration": "Please pay me back for dinner the other night",
"created": "2021-06-09T09:48:53.445+02:00",
"expirySeconds": 600,
"initiator": "A. Another (Acme Shop)"
}
| Field | Description |
|---|---|
amount |
The amount in decimal (2 decimal place precision) |
currencyCode |
The currency of the requested amount, ISO4217 currency code (alpha3) e.g. USD |
narration |
A comment or short description of this payment request, e.g. "Please pay me back for dinner." |
created |
The time at which the payment was initiated at the MSP |
expirySeconds |
The length of time (seconds) from "creation" that this payment will be valid. i.e. this is the time permitted between the AUTH Response and the receipt of a TRAN Request, beyond this time that payment will be expired and an ADVICE sent to the MSP notifying of such action. The deviceReference is no longer valid and must be created anew to proceed with this payment. The maximum time permitted by PayGo (at the time of writing is 24 hours). |
initiator |
The individual or organization responsible for this request, e.g. "Acme Another" - a teller. |
4.5. Nominated Credential
{
"credentialType": "BANK_ACCOUNT",
"institutionId": "411111",
"credential": "0001234560",
"currencyCode": "ZWL",
"additionalData": {
"cardAcceptorId":"123456789012345",
"cardAcceptorTerminalId":"12345678"
}
}
| Field | Description |
|---|---|
credentialType |
The type of credential, this indicates to the origin the type of credential, and thus the available payment options available. Available Options: BANK_ACCOUNT, ACCEPTOR |
institutionId |
The generic id associated with this credential, SwiftCode or BIN, etc |
credential |
The identifying credential at the institution |
currencyCode |
The currency of the account associated with the credential (This is usefull to indicate to the payer that currency conversion may take place). ISO4217 currency code (alpha3) e.g. USD |
4.6. Compliance Data
{
"origin": {
...
},
"destination": {
...
}
}
| Field | Description |
|---|---|
origin |
The KYC defining the originating entity of this transaction |
destination |
The KYC defining the destination entity of this transaction |
| Field | Description |
|---|---|
type |
Defines the type of data contained in this object. Available Options: PERSON, MERCHANT, CORPORATE |
name |
A full name or a business name. |
firstName |
A Persons first name/s e.g. Acme A. |
lastName |
A Persons last name e.g. Another |
nationalId |
A Persons national identity number or identifying credential of similar function. |
contactNumber |
The primary phone number for this entity |
addressLine1 |
First line of the entities address (Domicilium citandi) |
addressLine2 |
Second line of the entities address (Domicilium citandi) |
city |
… |
country |
… |
registrationNumber |
An id that is recognizable with a governing body (for example a company registration nr with the registrar of companies) |
taxIdNumber |
The id (TIN) allocated to the entity by the revenue authority. |
emailAddress |
The email address that the entity wishes to make available for primary communications |
url |
A url related to the entity |
5. Appendix
5.1. QR Code Specification
EMV® QR Code Specification for Payment Systems (EMV QRCPS) https://www.emvco.com/terms-of-use/?u=/wp-content/uploads/documents/EMVCo-Merchant-Presented-QR-Specification-v1.1.pdf
| A publicly accessible EMVco QR (PayGo Specification) generator is available in the Admin API, please see the document for further information. https://api.paygo.co.zw/admin/public/qr?shortCode=40010&narration=bananas&merchantName=My%20Shop&address=23%20Cookie%20Lane&amount=123 |
Reference - Data Object under the root of a QR Code (as per Table 3.6)
| Tag | Specification | Description |
|---|---|---|
01 |
N.10 |
Version Tag i.e. 1 |
02 |
N.19 LUHN |
This is the Short PayGoID suffixed with a Luhn Check Digit (based on the compressed value, i.e. negating consecutive zeroes) e.g. 40010 (not the long code i.e. 4000000000000010 - the luhn is correct foe the long code, not the short code , one must decompress the shortcode, to calculate a valid luhn) |
03 |
VARCHAR.255 |
A short description of the payment, i.e. "Paying you back for lunch", or "INVOICE1234" |
| For the below example, the https://github.com/mvallim/emv-qrcode library was used. |
private static MerchantAccountInformationTemplate getMerchanAccountInformationPayGo(int version,String paygoId,
String shortDesc) {
TagLengthString paygoVersion = new TagLengthString();
paygoVersion.setTag("01");
paygoVersion.setValue(version + "");
TagLengthString paygoIdTag = new TagLengthString();
paygoIdTag.setTag("02");
paygoIdTag.setValue(paygoId);
TagLengthString shortDescTag = new TagLengthString();
shortDescTag.setTag("03");
shortDescTag.setValue(shortDesc);
MerchantAccountInformationReservedAdditional merchantAccountInformationValue = new MerchantAccountInformationReservedAdditional();
merchantAccountInformationValue.setGloballyUniqueIdentifier("com.paygo");
merchantAccountInformationValue.addPaymentNetworkSpecific(paygoVersion);
merchantAccountInformationValue.addPaymentNetworkSpecific(paygoIdTag);
merchantAccountInformationValue.addPaymentNetworkSpecific(shortDescTag);
return new MerchantAccountInformationTemplate("36", merchantAccountInformationValue);
}
public static String generateDynamicQrCodeString(int version, String paygoId, String shortDesc,
String countryCode, String mcc, String city, String merchantName,
String transactionAmount, String transactionCurrency){
//paygo transaction details
MerchantAccountInformationTemplate merchanAccountInformationReservedAdditional =
getMerchanAccountInformationPayGo(version,paygoId,shortDesc); // 36 PayGo Specification
TagLengthString rFUforEMVCo = new TagLengthString("65", "00");
MerchantPresentedMode merchantPresentMode = new MerchantPresentedMode();
merchantPresentMode.setPayloadFormatIndicator("01"); //mandatory
merchantPresentMode.setCountryCode(countryCode); //mandatory
merchantPresentMode.setMerchantCategoryCode(mcc); //mandatory
merchantPresentMode.setMerchantCity(city); //mandatory
merchantPresentMode.setPointOfInitiationMethod("12"); //optional 11 static 12 dynamic
merchantPresentMode.setMerchantName(merchantName); //mandatory
merchantPresentMode.setTransactionAmount(transactionAmount);
merchantPresentMode.setTransactionCurrency(transactionCurrency);
merchantPresentMode.addMerchantAccountInformation(merchanAccountInformationReservedAdditional);
merchantPresentMode.addRFUforEMVCo(rFUforEMVCo);
return merchantPresentMode.toString();
| The generated QR image must be compliant with the PayGo Certification Standard. |
5.2. Examples
5.2.1. Purchase P2M Auth (Initiator to PayGo DS)
The following example is from the perspective of PayGo DS receiving a request to process a P2M Auth from Bank A to Bank B.
[PAYGO] Message To Remote [http://172.17.0.4:8477/vsuite/vintegration/bridge]
{
"acquiringInstitutionId" : "111111",
"additionalData" : {
"entryType": "MANUAL",
"pointOfInitiation": "QR_STATIC",
"directoryQuery" : {
"alias" : "20014",
"type" : "MERCHANT_ALIAS"
},
"complianceData" : {
"origin" : {
"contactNumber" : "N/A",
"emailAddress" : "N/A",
"firstName" : "N/A",
"lastName" : "N/A",
"nationalId" : "N/A",
"type" : "PERSON"
}
}
},
"cardAcceptorId" : "111111012345678",
"channel" : "USSD",
"created" : "2021-02-02T08:43:08.266+02:00",
"currencyCode" : "USD",
"debitAccount" : {
"id" : "1234567890"
},
"destinationInstitutionId" : "200",
"extendedType" : "MERCHANT_ALIAS",
"messageType" : "AUTH",
"participantReference" : "b1119174-1b70-47d0-98d5-6adcf2c29d07",
"payee" : "20014",
"reference" : "9dd81f76-f99c-4911-b92c-21a97d8cf03e",
"terminalId" : "11111111",
"traceId" : "ElZeH1mxEXRydIgKeYbxlM",
"type" : "PURCHASE"
}