Skip to main content

Consent Requests

For any recurring payments to be captured from a user, with Capitec Pay, a consent token is required to be created. This instruction must then be authorized by the user, to grant consent for the token to be subsequently charged.

A Capitec Pay recurring payment can be created by creating a Stitch Payment Consent Request with the Capitec Pay method enabled. When creating a Payment Consent Request with the Capitec Pay method, detailed information about the customer and the recurring payment is required. Your customer will be prompted to authorise the recurring payment as per the provided details. Once a recurring payment is successfully authorised, the Payment Consent Request status will move to GRANTED, and you will be able to initiate transactions.

note

Throughout this integration document, the Payment Consent Request represents the Capitec Pay recurring payment, since (for the purposes of this guide) Capitec Pay is the only method enabled in the examples.

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

sequenceDiagram participant Client participant Customer as Customer (Stitch SafeLink) participant Stitch API Client->>+Stitch API: create Payment Consent Request Stitch API->>Stitch API: input validation Stitch API-->>-Client: Payment Consent Request ID + redirect URL Client->>+Customer: browser redirect Customer->>+Stitch API: confirms details and grants consent Stitch API->>Stitch API: initiate authorization via Capitec Stitch API-->>-Customer: mobile banking app authorization required Customer->>+Stitch API: successfully authorized Stitch API->>Stitch API: update Payment Consent Request status Stitch API-->>-Customer: success Customer-->>-Client: browser redirect par Stitch API->>Client: Webhook: Payment Consent Request ID + status end

  • Creating the Payment Consent Request,
  • Redirecting the customer, and
  • Handling the resulting redirect, with webhook.

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 Capitec Pay 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 recurring payment.

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

Payment Variability

The above mutation specifies a fixed recurring payment. However, a variable payment can be configured by specifying the paymentOptions.variable property instead.

Future Once-off Payments

Once-off payments for fixed or variable amounts are supported. In order to create a consent for a once-off future payment, specify ONCE_OFF for the paymentSchedule.frequency input, together with either a fixed or variable amount.

Request Fields

The table below describes the fields that can be populated when creating a payment request.

NameDescriptionType
nonceA nonce is a generated, unique, random value that can only be used once to ensure the uniqueness of the request.String
externalReferenceOptional value that will be returned in the redirect URL and on queries after the customer grants consent.String
paymentOptionsCan be used to define whether the customer will be charged a fixed, or variable recurring amount.Object
paymentOptions.fixedDefines a fixed recurring amount.Money
paymentOptions.variable.maxDefines a maximum amount for a variable recurring amount. Displayed to the customer on their mobile banking app.Money
paymentSchedule.startThe date the payment consent will be active, and can be charged against. Displayed to the customer on their mobile banking app.Date (ISO-8601)
paymentSchedule.frequencyIndicates how often the collection will occur. This can be ONCE_OFF, DAILY, WEEKLY, MONTHLY, or YEARLY. Displayed to the customer on their mobile banking app.Enum
paymentDescriptionThe description displayed to the customer on their banking app.String
payerInfo.identifyingDocumentThe customer's valid South African identity number, as registered with Capitec.IdentifyingDocument
payerInfo.mobileNumberThe customer's mobile number, as registered with Capitec.String
payerInfo.bankAccountNumberThe customer's Capitec account number.String
User Authorization

To create a Payment Consent Request with Capitec Pay, the user will require one of the following when authorizing:

  • South African identity number
  • Mobile phone number
  • Capitec account number

Temporary residence numbers and passports are not currently supported.

Handle Interaction URL

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 consent request. 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 value returned from the API: &returnUrl=https://example.com/subscription. The full URL you expose to the customer would then look like this:

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

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

Please note that production clients will not be allowed to use unsecure returnUrl parameters such as http.

http://example.com/subscription

https://example.com/subscription

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

Request FieldDescriptionType
idThe unique id of this payment consent 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 while authorizing.String
externalReferenceThe externalReference that was used when creating the consent request, if provided.String

The id can be used to retrieve the final consent 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 alter it before redirecting. 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 to verify the signature of each incoming webhook's payload.

Using the webhooks also ensures you'll always be able to know the final status of a payment consent request. If for example the request times out due to a network issue.

Handling Granted Consents

Once a user has granted consent for you to process recurring transactions via Capitec Pay, the consent request will be in a PaymentConsentGranted state. At this point, you may proceed to initiate transactions using the respective consent ID.

In the case that a subscription has ended, or a user chooses to remove their consent from your platform, you should revoke the consent request, so that it is no longer possible to initiate transactions from their account.

A Payment Consent Request can be revoked directly via the Stitch API, or by a customer revoking consent in their banking app. A revocation would result in a Payment Consent Request with a status of PaymentConsentRevoked. The Payment Consent Request would be inactive and any payment 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 revocation reason supplied needs to be one of the reasons as indicated in the "Reason" column below.String
ReasonDescription
CONTRACT_TERMINATEDThe contract has been terminated.
FRAUDRevoked due to fraud related activity by the customer.
GENERALGeneral cancellation that isn't for one of the aforementioned reasons.
note

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

A Payment Consent Request that has been created, and is still pending, can be cancelled in order to prevent a user from granting their consent on the current request. This can be done by executing the paymentConsentRequestCancel mutation with a consent ID and a reason. This is different to revocation in that a user has not previously granted consent to the recurring payment. See the status descriptions in the table below for more information.

An example of a cancellation mutation is shown below:

Payment Consent Request statuses can be queried directly or obtained via a subscription to the webhooks.

StatusDescription
PaymentConsentPendingThe initial status after creation via the API.
PaymentConsentGrantedThe consent request was authorised by the customer, and can be charged against.
PaymentConsentFailedThe consent request 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 consent request has been cancelled while it was still pending, before it was authorised.
PaymentConsentExpiredThe consent request has expired while it was still pending, before it was authorised.
PaymentConsentRevokedThe consent request was revoked and cannot be charged against.

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

flowchart LR A(((created))) --> P(Pending) P(Pending) --> G(Granted) G(Granted)--> R(Revoked) P(Pending) --> Ca(Cancelled) P(Pending) --> E(Expired) P(Pending) --> F(Failed)

Subscribe to Webhooks

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

If the webhook 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 CapitecPay VRP Payload
{
"data": {
"createdAt": "2023-06-11T11:52:49.230Z",
"id": "cmVjdXJyaW5nUGF5bWVudENvbnNlbnRSZXF1ZXN0L2NiNmYyYmQ5LTVjODgtNDFmOS04MmE1LWE0NWEyNDYxMGJmNg==",
"status": "granted",
"type": "capitecpay",
"updatedAt": "2023-06-21T11:52:49.230Z"
},
"datetime": "2023-05-10T12:22:42.865Z",
"id": "consent-request:status:success:cb6f2bd9-5c88-41f9-82a5-a45a24610bf6",
"type": "consent-request-status"
}

Testing and Simulation

When using a test client, the default flow will result in a GRANTED payment consent request, and the default transaction result will be successful. However, it is possible to simulate other outcomes.

Simulated Statuses

Payment consent request scenarios can be simulated by configuring the productDescription when creating the payment consent request.

productDescription valueScenarioConsent status outcome
successSimulates the user accepting the recurring payment in-app prompt. This is the default successful scenario, the same as if the field was left empty.GRANTED
timeoutSimulates the user not responding to in-app prompt before the request expires. The user may be able to retry.PENDING
declinedSimulates the user declining the in-app prompt on their device.PENDING
clientTransactionLimitExceededSimulates the not being able to authorize the consent due to transaction limits.FAILED