Note: This article is relevant to merchants integrating with Zepto in Australia.
This document outlines in detail how a merchant application could integrate with Zepto in a way that will allow them to manage multiple merchants and facilitate payment requests (Direct Debits) from a customer to a merchant without any money flowing through the main applications bank account.
Throughout this guide, the following terminology will be used
Main merchant - Merchant that is integrating with Zepto Payments
Managed merchant - Merchant that will use the main merchant to handle their payments.
Customer - The end customers of the managed merchants
Debtor - The party that will be debited as part of a transaction
Creditor - The party that will be credited as part of a transaction
Account Float - Virtual account held within Zepto that Payment Requests will settle into and Payments will draw from.
High-Level Transaction Flow
You will essentially have two types of Contacts that you will be creating and debiting/crediting. Firstly will be the managed merchants. Managed merchants are the companies that will be utilising your integration to create direct debits from their customers. The other type of contact will be the customer which is the user of your merchants and is the party being debited.
When a managed merchant wishes to debit their customer, you will be creating a Payment Request from the customer that will settle into an account float. Once this Payment Request clears, you will be creating a Payment from your account float to the managed merchant who is due to receive the funds for the transaction. The total time from creation to the managed merchant receiving the funds can be up to three business days.
This integration could be broken down into two parts that each involve a couple of steps:
1. Managed merchant and Customer On-Boarding
and
2. Direct Debit Creation and tracking
1. Managed Merchant and Customer On-Boarding
The managed merchants that will be initiating the direct debits and the customers being debited will need to be added as Contacts within your Zepto account and, as there may be the need to Direct Debit both of them depending on the scenario, there will also need to be an agreement
in place which is basically the authority to direct debit their account.
An Agreement is not needed in order to pay this contact, however, since there are scenarios in which either contact type may need to be debited, we recommend that you follow this guide and onboard them using the unassigned agreements endpoint so that all edge cases are covered.
When a managed merchant wishes to sign up to your service or a previously added merchant wishes to add a customer to be debited, you will first of all need to generate an Agreement link to direct them to. This can be done through the Unassigned Agreement endpoint and you can customise the resulting page and pre-fill any known data by adding query strings to the URL prior to redirecting this merchant. The available customisation options are documented here.
Example white-label, pre-filled agreement page
Both parties can also have the option of entering their BSB and account number rather than providing their online banking credentials. This option is enabled by appending the query string, allow_manual=1
to the end of the unassigned agreement link that was retrieved earlier. Please note that this option needs to be enabled in your Zepto account by the Zepto team, so please reach out to have this enabled.
Example white-label, pre-filled agreement page using allow_manual=1
When this link is followed and banking credentials or BSB and account numbers are entered, two things will happen. A Contact will be created and an Agreement will be put in place between your account and this contact. This agreement is basically the authority to Direct Debit this contact and will need to be in place.
You can use multiple methods to be notified when this happens, each of these is outlined in this article. We recommend using our webhook system for this and each time an Agreement is created, you will receive a webhook that will contain all details and ID's that you will need to persist within your system.
Example Received Webhook
{
"data": [
{
"ref": "A.ctg",
"terms": {
"per_payout": {
"max_amount": null,
"min_amount": null
},
"per_frequency": {
"days": null,
"max_amount": null
}
},
"status": "accepted",
"contact_id": "452ca5e6-bd3e-4a37-b32e-0ee7189c9b86",
"created_at": "2020-10-07T03:33:35Z",
"initiator_id": "f0a08009-4aa6-484d-b381-9a66232f81e7",
"responded_at": "2020-10-07T03:43:26Z",
"authoriser_id": "b46bdf97-5138-4d03-a3ec-55746759dcea",
"status_reason": null,
"bank_account_id": "5afedb76-3786-4f08-849e-d00f5356c98e",
"open_agreement_id": null
}
],
"event": {
"at": "2020-10-07T03:43:26Z",
"who": {
"account_id": "b46bdf97-5138-4d03-a3ec-55746759dcea",
"account_type": "AnyoneAccount"
},
"type": "agreement.accepted"
}
}
Note: In particular you will need to store the contact_id
as this will be used in future API calls to request payment from and send payment to this contact.
Once you have this ID it's as simple as one GET request to the contacts endpoint to retrieve any other details you wish to store such as contact name, email or bsb and account number should you need to.
Payment Request Creation
Now that you have a managed merchant and their customer's setup as contacts within Zepto and have persisted their Contact IDs, you are ready to create a Payment Request (Direct Debit) from the customer.
The payment request can be created by using our request payment endpoint and is as simple as telling us which contact id to debit, how much we should debit, where we should settle the funds, and when we should begin processing this transaction.
Example Payment Request Payload
{
"description": "Only visible within Zepto",
"matures_at": "08/09/2020T02:10:56.000AEST",
"amount": 99000,
"authoriser_contact_id": "de86472c-c027-4735-a6a7-234366a27fc7",
"your_bank_account_id": "9c70871d-8e36-4c3e-8a9c-c0ee20e7c679",
"metadata": {
"remitter": "merchant_name",
"custom_string": "some custom reference"
}
}
The authoriser_contact_id
in this scenario will be the contact id related to the customer that is being debited. This id should have been persisted as explained above in the customer onboarding section.
The your_bank_account_id
will need to be the id related to your float account. We will settle any debited funds into this account. If you need any information about float accounts and how to get this id, refer to our collection of articles that cover this.
Example Response
{
"data": {
"ref": "PR.3",
"initiator_id": "ca7bc5b3-e47f-4153-96fb-bbe326b42772",
"your_bank_account_id": "9c70871d-8e36-4c3e-8a9c-c0ee20e7c679",
"authoriser_id": "970e4526-67d9-4ed9-b554-f5cf390ab775",
"authoriser_contact_id": "de86472c-c027-4735-a6a7-234366a27fc7",
"schedule_ref": null,
"status": "pending_approval",
"responded_at": null,
"created_at": "2016-12-19T02:10:56Z",
"credit_ref": null,
"payout": {
"amount": 99000,
"description": "The elite package for 4",
"matures_at": "2016-12-25T00:00:00Z"
},
"metadata": {
"remitter": "merchant_name",
"custom_string": "some custom reference"
}
}
}
Payment Request Tracking
Our response to the above request includes all the details necessary to track this payment request from creation to a cleared or returned final status. We highly recommend you make use of our webhooks, explained in this article, to keep track of the progress of this transaction.
In a payment request from contact to your account float scenario, you will mainly be utilizing two webhooks to track the progress. These are:
creditor_debit.xxx
credit.xxx
The standard event cycle of a successful debit will look like the following
creditor_debit.scheduled
credit.scheduled
creditor_debit.matured
creditor_debit.processing
creditor_debit.clearing
creditor_debit.cleared
credit.matured
credit.processing
credit.clearing
credit.cleared
In the event of a failed payment request, this event flow will look different and may follow a path similar to the following.
creditor_debit.scheduled
credit.scheduled
creditor_debit.matured
creditor_debit.prefailed
credit.prefailed
or
creditor_debit.scheduled
credit.scheduled
creditor_debit.matured
creditor_debit.processing
creditor_debit.clearing
creditor_debit.returned
credit.voided
Each of these webhook payloads will include all information needed to track a payment request from start to finish. For example, the following is an example creditor_debit.scheduled
event and the parent_ref
field will be shown in all subsequent webhooks for this payment request. This field alone can be used to track a transaction from start to finish.
{
"data": [
{
"ref": "D.2sov",
"type": "debit",
"amount": 6789,
"status": "matured",
"bank_ref": null,
"category": "payout",
"channels": [
"direct_entry"
],
"cleared_at": null,
"created_at": "2020-10-09T03:40:14Z",
"matures_at": "2020-10-08T13:00:00Z",
"parent_ref": "PR.l8f",
"party_name": "Demo Account",
"description": "custom description",
"party_bank_ref": null,
"party_nickname": "demo",
"bank_account_id": "569f4597-b64d-477e-83e3-6d63b803778a",
"current_channel": "direct_entry",
"party_contact_id": null,
"status_changed_at": "2020-10-09T03:40:14Z"
}
],
"event": {
"at": "2020-10-09T03:40:14Z",
"who": {
"account_id": "5d9d445c-ec48-44f6-a845-9e9b21a7148d",
"account_type": "AnyoneAccount",
"bank_account_id": "569f4597-b64d-477e-83e3-6d63b803778a",
"bank_account_type": "BankAccount"
},
"type": "creditor_debit.scheduled"
}
}
Payment Creation
Now that the payment request from the customer has cleared and you have the managed merchants contact id, it's time to pay the merchant for the amount of the debit. This is achieved by making one POST request.
The payment can be created by using our make a payment endpoint and is as simple as telling us which contact id to pay, how much we should credit, which account to use to fund the payment and when we should begin processing this transaction.
Example Payment Payload
{
"description": "Payment batch desc. only visible within Zepto",
"your_bank_account_id": "9c70871d-8e36-4c3e-8a9c-c0ee20e7c679",
"matures_at": "11/10/2020T00:00:00AEST",
"payouts": [
{
"matures_at": "11/10/2020T00:00:00AEST",
"amount": 99000,
"description": "Payment desc. only visible within Zepto",
"recipient_contact_id": "21066764-c103-4e7f-b436-4cee7db5f400",
}
]
"metadata": {
"remitter": "customer_ref",
"custom_string": "some custom reference"
}
}
The recipient_contact_id
in this scenario will be the contact id related to the merchant that is receiving the funds. This id should have been persisted during the onboarding process earlier.
The your_bank_account_id
will need to be the id related to your float account. We will draw the funds for this refund from this account. If you need any information about float accounts and how to get this id, refer to our collection of articles that cover this.
Example Response
{
"data": {
"ref": "PB.2qby",
"your_bank_account_id": "9c70871d-8e36-4c3e-8a9c-c0ee20e7c679",
"payouts": [
{
"ref": "D.2sp5",
"recipient_contact_id": "d90d4a62-e469-4939-89ed-8ec9dcc3ee4e",
"batch_description": "Payment batch desc. only visible within Zepto",
"matures_at": "2020-10-10T13:00:00Z",
"created_at": "2020-10-09T04:35:27Z",
"status": "maturing",
"amount": 99000,
"description": "Payment desc. only visible within Zepto",
"from_id": "83623359-e86e-440c-9780-432a3bc3626f",
"to_id": "21066764-c103-4e7f-b436-4cee7db5f400",
},
],
"metadata": {
"remitter": "customer_ref",
"custom_string": "some custom reference"
}
}
}
Payment Tracking
Our response to the above request includes all the details necessary to track this from payment creation to a cleared or returned final status. We highly recommend you make use of our webhooks, explained in this article, to keep track of the progress of this transaction.
Payment to your managed merchant from your account float scenario, you will mainly be utilising two webhooks to track the progress. These are:
debit.xxx
debtor_credit.xxx
The standard event cycle of a successful payment will look like the following
debit.scheduled
debtor_credit.scheduled
debit.matured
debit.processing
debit.clearing
debit.cleared
debtor_credit.matured
debtor_credit.processing
debtor_credit.clearing
debtor_credit.cleared
In the event of a failed payment, this event flow will look different and may follow a path similar to the following.
debit.scheduled
debtor_credit.scheduled
debit.matured
debit.processing
debit.clearing
debit.cleared
debtor_credit.matured
debtor_credit.processing
debtor_credit.clearing
debtor_credit.returned
credit.scheduled
credit.matured
credit.processing
credit.clearing
credit.cleared
Each of these webhook payloads will include all information needed to track payment from start to finish. For example, the following is an example debit.scheduled
event and the parent_ref
field will be shown in all subsequent webhooks for this payment request. This field alone can be used to track a transaction from start to finish.
{
"data": [
{
"ref": "D.2spg",
"type": "debit",
"amount": 99000,
"status": "matured",
"bank_ref": null,
"category": "payout",
"channels": [
"float_account"
],
"cleared_at": null,
"created_at": "2020-10-09T05:00:48Z",
"matures_at": "2020-10-08T13:00:00Z",
"parent_ref": "PB.2qc4",
"party_name": "Demo Contact",
"description": "custom description",
"party_bank_ref": null,
"party_nickname": null,
"bank_account_id": "01b01b35-08d1-4ef9-a82c-040a0070fb2e",
"current_channel": "float_account",
"party_contact_id": "0ebbbfe9-2b05-41d9-a381-dd4aab281e4f",
"status_changed_at": "2020-10-09T05:00:48Z"
}
],
"event": {
"at": "2020-10-09T05:00:48Z",
"who": {
"account_id": "f0a08009-4aa6-484d-b381-9a66232f81e7",
"account_type": "Account",
"bank_account_id": "01b01b35-08d1-4ef9-a82c-040a0070fb2e",
"bank_account_type": "BankAccount"
},
"type": "debit.scheduled"
}
}
Feel free to reach out if you have further questions by emailing us directly at support@zepto.com.au or clicking on the blue bubble icon from the corner of the screen.