Skip to main content

DebiCheck Integration Process

A DebiCheck Mandate can be created via a Payment Consent Request with the debicheck method set to enabled under paymentMethods within the paymentConsentRequestCreate mutation.

When creating the Payment Consent Request, you are required to provide detailed DebiCheck mandate information about the customer and the collection subscription. Your customer will be prompted to authorise the mandate as per the provided details. Once a mandate is successfully authorised, the Payment Consent Request status will be GRANTED, and you will be able to initiate collections.

note

Throughout this integration document, the Payment Consent Request represents the DebiCheck Mandate, since debicheck is the only method enabled in the examples.

The below high-level diagram depicts mandate creation using Payment Consent Requests on the Stitch API. The outcome of the Payment Consent Request creation is a redirect URL and a consent ID. After authorisation by the user, the Payment Consent Request will be GRANTED. The consent ID can then be used to invoke future collections.

A Payment Consent Request can be created using the below mutation. Payment Consent Request creation requires a client token with the client_recurringpaymentconsentrequest scope. Follow the steps described in the client token guide to obtain a client token.

To create a Payment Consent Request with DebiCheck enabled, information about the customer and the collection is required. A redirect URL will be returned for you to surface to your customer, allowing them to provide any outstanding details, and to authorise the mandate.

The GraphQL API URL https://api.stitch.money/graphql can be used for all consent requests (whether on test or live clients).

The table below describes the fields detailed in the above mutation. Details about the DebicheckCollectionInput, DebicheckPayerBankInformationInput and PayerInformationInput types can be seen by exploring the variables in the above request.

NameDescriptionType
accountTypeOnly "current" (cheque) or "savings" accounts are supported.String
contractReferenceThe contract number for the customer. This will appear on the customer's statement and must be unique per mandate creation request with a maximum of 14 characters.String
collectionFrequencyIndicates how often the collection should occur. This can be "weekly", "fortnightly", "monthly", "quarterly", "biannually", "yearly", or "adHoc". The collectionFrequency determines the possible values for collectionDay. More details can be found below.String
collectionDayA number for the day of the week, or a day of the month when the collection will occur, as per the frequency specified in the collectionFrequency field.Number
instalmentAmountThe currency value in rands, to be collected from the customer at the frequency stipulated. This is required if the debitValueType is "fixed" or "variable" and can be optionally supplied for "usage-based".Number
maximumCollectionAmountThe maximum value in rands, that can be collected from the customer at the frequency stipulated. This is up to 1.5x the instalmentAmount in the case of "fixed" and "variable" mandates and R500 000.00 for "usageBased". This value will default to the upper limits if not provided.Number
firstCollectionAmountAn initial collection amount that will be different from the recurring collection amount. Only collected once.Number
firstCollectionDateThe date that the collection of the firstCollectionAmount should take place. Occurs a single time. Provided in ISO 8601 format i.e. "2024-04-04"String

The table below describes the fields that can be configured on your client, and will apply by default to all mandates unless an override is provided on the API mutation.

NameDescriptionType
accountTrackingIndicates whether account tracking is enabled for the mandate. Account tracking is the ability for the customer's account to be tracked for up to 10 days. As soon as money comes into the account, the collection will be resubmitted.Boolean
debitValueTypeThe DebiCheck type determining possible values for the instalmentAmount. This can be either "fixed", "variable", or "usageBased". "fixed" requires a fixed, specific amount as indicated by the instalment amount. "variable" and "usageBased" require a changeable amount for instalmentAmount. The upper limit for "fixed" and "variable" is 1.5x the instalment amount as provided in the maximumCollectionAmount field. "usageBased" is variable with an upper limit of R500 000.00.String
amountAdjustmentFrequencyThe frequency at which adjustment of the instalment amount can occur. This can be either "never", "quarterly", "biannually", annually", or "repo". If this is "never" or "repo", adjustmentAmount and adjustmentRate can be omitted.String
adjustmentAmountThe value that the instalment amount can be adjusted by. This can be a negative value.Number
adjustmentRateThe rate by which the instalmentAmount can be adjusted by.Number
Identifying Document types

For mandate creation, you need to provide one of the following identifying documents:

For Individual Accounts:

  • South African Identity Document
  • Passport Number
  • Temporary Residence ID

For Business Accounts:

  • Business Registration Number (Required for RM mandates)
Note
  • For individual accounts the phoneNumber supplied must be a South African phone number without the country code.
  • The amount is an amount in rands i.e. 10.00.
  • Either adjustmentAmount or adjustmentRate should be supplied if the adjustmentFrequency is supplied.
  • fullName is the customer's name and surname with a maximum of 35 characters.
  • For business accounts, an RM mandate will be automatically created instead of going through the real-time DebiCheck process.
FirstCollectionDate and FirstCollectionAmount
  • These values represent an initial amount to be collected from your customers. These values do not correspond with the specified collectionDay and collectionFrequency values and are a once-off collection.
  • If provided, both of these values are required.
  • firstCollectionDate should be at least 4 days in the future, counting the current day (today) as day 1.

CollectionFrequency and CollectionDay

The collectionDay field is bound by the collectionFrequency value provided. The possible values per collectionFrequency are detailed below.

CollectionFrequencyCollectionDay
weekly1 = Monday to 7 = Sunday
fortnightly1 = Monday to 7 = Sunday (first week).
8 = Monday to 14 = Sunday (second week).
monthly1 - 30, or 99 = last day
quarterly1 - 30, or 99 = last day
biAnnually1 - 30, or 99 = last day
yearly1 - 30, or 99 = last day
adHoc1 = the last Monday to 6 = last Saturday.
7 = first Monday to 12 = first Saturday.
14 = 2nd last day.
99 = last day.
1 - 30, or 99 = last day
  • "1 - 30, or 99 = last day" represent the days in a month.
  • In the case of quarterly, biAnnually, or yearly, the term begins from the date of the first collection.

Surface URL and Handle Callback

The redirect URL returned by the API requires that an allowlisted returnUrl is appended as a query string parameter. If a customer is redirected to this URL, they will be guided through the process of authorising the mandate. For test clients, the following URLs are allowlisted by default:

For example, if your allowlisted URL configuration included the URL https://example.com/subscription, you'd append the following query parameter to the url returned from the API: &returnUrl=https%3A%2F%2Fexample.com%2Fsubscription. The full URL you expose to the customer should look like this

https://secure.stitch.money/v2/consent?requestId=2b068bd5-6a5a-42e1-8a45-673cb3ede612&
clientId=test-195944A9-E957-4532-B574-D37BD5FD9297&
returnUrl=https%3A%2F%2Fexample.com%2Fpayment
Allowlisting Redirect URLs

To add or remove a URL from the whitelist, please reach out to the Stitch team.

Please note that production clients will not be allowed to use an unsecure (http) returnUrl value. For example:

http://example.com/subscription

https://example.com/subscription

Once the customer completes or cancels the mandate creation request, they'll be redirected to the returnUrl. The below query string parameters will be passed back to the returnUrl.

Request FieldDescriptionType
idThe unique id of this mandate creation request.ID
statusStatus will have the value complete if successful, closed if the customer clicked close in the UI, or failed if something went wrong when attempting the mandate creation requestString

The id can be used to retrieve the final mandate creation request status and other details from the Stitch API, as well as relate to incoming webhooks.

danger

The status field should not be used for any database operations since an external party can tweak it. To secure yourself from attackers who can send a fake payload to your redirect or webhook endpoint, we recommend:

  1. using the webhooks as the source of truth as they are secure and will always be sent from Stitch.
  2. making use of signed webhooks since you'll be able to verify the signature of each incoming webhook's request payload.

Using the webhooks also ensures you'll still be able to know the final status of a mandate creation request if for example the request times out.

A Payment Consent Request can be revoked via the Stitch API by you, by your users in an operation that allows them to suspend a DebiCheck Mandate, or by Stitch. A revocation would result in a Payment Consent Request with a status of PaymentConsentRevoked. The Payment Consent Request would be inactive and any collection attempts against it would fail. In order to revoke a Payment Consent Request, you need to call the paymentConsentRequestRevoke mutation as detailed below:

The table below describes the fields detailed in the above mutation.

NameDescriptionType
idThe unique id of the original payment consent request ID as returned by the Stitch API when you create a payment consent request.ID
reasonThe reason for revoking the payment consent request. The cancellation reason supplied needs to be one of the reasons as indicated in the "Reason" column below.String
ReasonDescription
EARLY_SETTLEMENTMandate cancelled due to early settlement.
CONTRACT_EXPIREDContract expired.
FRAUDMandate cancelled due to fraud cancelled due to early settlement.
GENERALGeneral cancellation that isn't for one of the aforementioned reasons.
PaymentConsentRevoked

A Payment Consent Request can only move to a PaymentConsentRevoked status from a PaymentConsentGranted status.

A Payment Consent Request that is PENDING can be cancelled. You may want to cancel a Payment Consent Request to prevent a user from granting consent. Cancellation would result in a Payment Consent Request with a status of PaymentConsentCancelled. In order to cancel a Payment Consent Request, you need to call the paymentConsentRequestCancel mutation as detailed below:

The table below describes the fields detailed in the above mutation.

NameDescriptionType
idThe unique ID of the original payment consent request ID as returned by the Stitch API when you create a payment consent request.ID
reasonThe reason for revoking the payment consent request.String
PaymentConsentCancelled

A Payment Consent Request can only move to a PaymentConsentCancelled status from a PaymentConsentPending status.

The underlying mandate statuses are represented by the Payment Consent Request status. This can be queried directly or obtained via a subscription to the webhooks. At different stages in its lifecycle, the payment consent request can have the following statuses:

StatusDescription
PaymentConsentPendingThe initial status of a mandate creation request after creation via the API. This indicates that authorisation of the mandate is pending.
PaymentConsentProcessingThis indicates that mandate has moved from pending and is currently being processed. This would happen when a scheduled mandate is created. Once the mandate has been successfully processed, the status will move to PaymentConsentGranted.
PaymentConsentGrantedThe DebiCheck mandate was authorised and can be collected against. In the case of RM, this indicates that the RM mandate was created and can be collected against.
PaymentConsentFailedThe DebiCheck mandate initiation failed. This is usually due to rejection or error by a downstream provider. Further failure codes and descriptions are included with this status.
PaymentConsentCancelledThe DebiCheck mandate has been cancelled before it was authorised. This is in-flight cancellation, triggered by you via API.
PaymentConsentExpiredThe DebiCheck mandate has expired before it was authorised. This is triggered by a pre-set expiry for the mandate initiation request.
PaymentConsentRevokedThe mandate was revoked and cannot be collected against. The revocation will explicitly be carried out by you via API or internally due to an operation resulting in collection not being permitted i.e. disputes.

While we encourage the use of webhooks for obtaining status updates, as they are immediate and don't require polling, the following query is an example of fetching a payment consent request by ID to obtain the status.

Below is a diagram depicting the possible Payment Consent Request Statuses

Webhooks

Webhooks for updates on consent requests can be subscribed to by running the following mutation:

If the subscription is successfully created, the body returned by the request will look similar to the sample in the Example Response tab in widget above.

For more information on receiving webhook events, listing active webhook subscriptions, unsubscribing from webhooks and validating signed webhook subscriptions, please visit the Webhooks page.

Webhook Statuses

The payment-consent-request webhook will be dispatched for each of the following status updates:

  • PaymentConsentProcessing
  • PaymentConsentFailed
  • PaymentConsentGranted
  • PaymentConsentCancelled
  • PaymentConsentExpired
  • PaymentConsentRevoked
Example Debicheck Payload
{
"datetime": "2023-05-10T12:22:42.865Z",
"id": "consent-request:status:success:cb6f2bd9-5c88-41f9-82a5-a45a24610bf6",
"type": "consent-request-status"
"data": {
"createdAt": "2023-06-11T11:52:49.230Z",
"id": "cmVjdXJyaW5nUGF5bWVudENvbnNlbnRSZXF1ZXN0L2NiNmYyYmQ5LTVjODgtNDFmOS04MmE1LWE0NWEyNDYxMGJmNg==",
"status": "GRANTED",
"type": "DEBICHECK",
"updatedAt": "2023-06-21T11:52:49.230Z"
}
}

Registered Mandate (RM) Mandates

DebiCheck authenticated mandates rely on customer authorisation. In cases where:

  • Customers have failed to authenticate a mandate
  • The account is a business account
  • Other scenarios where real-time authentication isn't possible

Stitch will create an RM mandate with the customer. The RM mandate does not require customer authorisation and will serve similar to a regular debit order, allowing for collections based on the terms provided in the mandate request.

note
  • RM mandates are similar to regular electronic debit orders and thus, are disputable given that an authorised agreement does not exist between you and the customer.
  • Any existing RM mandate in future can be upgraded to a regular authenticated DebiCheck mandate by using mandate amendment process.
  • RM mandate allows tracking option.
  • A business account can also be collected via RM mandate.

RM mandate can be created against a business account by running the following mutation:

Scheduled Mandates

DebiCheck mandate initiation requests are only processed within the banking window of 03h00 - 22h00 each day. To ensure that your customers are still able to sign up for your goods or services via DebiCheck outside of the banking window, a scheduled mandate will be created. After your customer confirms their details:

  • You will receive a webhook indicating that the consent is in a PROCESSING state.
  • The mandate will be submitted to the bank during the next available processing window. This will be the following day from 09h00 onwards.
  • Your customer will receive the MFA prompt for authorisation once the scheduled mandate has been submitted for processing.
  • You will receive a final status for the mandate once the request has been actioned by your customer.