Debicheck Mandate Amendments
Overview
Debicheck mandates can be amended using the paymentConsentRequestAmend mutation.
Before proceeding with an amendment, please note the following fields may not be amended and will require a new mandate (PaymentConsentRequest) to be created.
- Collection frequency
- Debtor bank branch code or bank
- Combination of debtor identification number and bank account number
- Contract reference (unless no collections have been made).
Amending the following fields will require re-authentication by the customer:
| FIELD NAME | REMARKS |
|---|---|
maximumCollectionAmount | If the maximumCollectionAmount is amended and amountAdjustmentFrequency = never, then re-authentication is required. |
firstCollectionDate | If the firstCollectionDate is amended, then the debtor must authorise. |
firstCollectionAmount | If the firstCollectionAmount is amended, then the debtor must authorise. |
instalmentAmountand amountAdjustmentFrequency | If the instalmentAmount is amended and amountAdjustmentFrequency = never, then re-authentication is required. |
collectionDay | If the collectionDay is amended, then the debtor must reauthenticate. |
ultimateCreditorAbbreviatedShortName | If the ultimateCreditorAbbreviatedShortName is amended, then the debtor must reauthenticate. |
dayAdjustmentAllowed | If the dayAdjustmentAllowed is amended, then the debtor must reauthenticate. |
adjustmentAmount | If the adjustmentAmount is amended, then the debtor must reauthenticate. |
adjustmentRate | If the adjustmentRate is amended, then the debtor must reauthenticate. |
Amending the following fields will trigger a notification to the customer, but they will not be required to authenticate:
| MANDATE FIELD | NOTES |
|---|---|
maximumCollectionAmount | If amountAdjustmentFrequency on the initial mandate is not set to never, then maximumCollectionAmount can be amended and a notification is sent to the customer. |
instalmentAmountand amountAdjustmentFrequency | If amountAdjustmentFrequency on the initial mandate is not set to never, then instalmentAmount can be amended by the exact amount or rate that was specified under adjustmentAmount or adjustmentRate on the initial mandate. Otherwise, it can only be amended as per the amountAdjustmentFrequency i.e. quarterly, biannually, annually. A notification is sent to the customer. |
trackingIndicator | A notification is sent to the customer. |
contractReference | Can only be amended before the first collection is made. Otherwise, a new mandate is required. A notification is sent to the customer. |
ultimateCreditorName | A notification is sent to the customer. |
fullName | A notification is sent to the customer. |
identifyingDocument | A notification is sent to the customer. |
accountType | A notification is sent to the customer. |
accountNumber | If the account number exists in the same bank, then a notification would be sent to the customer. Otherwise, a new mandate is required. |
Amendment Example Mutation
You may identify the mandate to amend using either its Stitch consentRequestId or the bank-issued mandate reference number (MRN) via paymentConsentIdentifier - exactly one must be provided. Both are top-level arguments on the mutation; the input object carries the amendment details.
Example response payload from AmendMandate mutation
{
"data": {
"paymentConsentRequestAmend": {
"id": "cGF5bWVudGNvbnNlbnRyZXF1ZXN0LzMwN2VhYTFmLTczMjQtNDAzNy05NjNiLWJlYWQ3NDY2YTNhNQ==",
"status": {
"__typename": "PaymentConsentGranted",
"date": "2025-10-08T10:33:14.747279+00:00"
},
"amendmentDetails": {
"authenticationChannel": "authRealtime",
"reason": "CUSTOMER_REQUEST",
"status": "PROCESSING",
"statusReason": null,
"bankReasonCode": null,
"bankReasonDescription": null,
"expectedAction": "Re-authentication required from customer",
"amendedFields": {
"collection": {
"collectionDay": 3,
"instalmentAmount": null,
"adjustmentAmount": null,
"adjustmentRate": null,
"amountAdjustmentFrequency": null,
"dayAdjustmentAllowed": null,
"firstCollectionAmount": null,
"firstCollectionDate": null,
"maximumCollectionAmount": null,
"trackingIndicator": null
},
"customer": {
"accountName": null,
"accountNumber": null,
"accountType": null,
"bankId": null,
"branchCode": null,
"email": null,
"fullName": null,
"identifyingDocument": null,
"phoneNumber": null
}
}
}
}
}
}
Amendment Details Response Fields
The table below describes the fields of the amendmentDetails object returned by the mutation. The bank-outcome fields (statusReason, bankReasonCode, bankReasonDescription) are null on the mutation response — the bank has not yet processed the amendment — and are populated once the bank responds, when querying the consent request or via the amendment webhook.
| Name | Description | Type |
|---|---|---|
| status | The status of the amendment attempt. One of PENDING, PROCESSING, SUCCESS, or FAILED. | AmendmentStatusEnum |
| statusReason | Additional context about the current state or outcome of the amendment. On success this is MFA_ACCEPTED if the amendment required customer re-authentication, or SUCCESS if it did not (notification-only) or it was for a registered-mandate amendment. See the possible values below. | String |
| reason | The original reason supplied when the amendment was requested, echoed back regardless of outcome. | String |
| bankReasonCode | The original reason code returned by the bank, if any. | String |
| bankReasonDescription | The description of the reason code returned by the bank, if any. | String |
| expectedAction | The action expected from the customer, e.g. re-authentication or notification. | String |
| authenticationChannel | The authentication mechanism used for the amendment. | MandateAuthenticationChannelEnum |
| contractReference | The creditor contract number for the end-user. | String |
| amendedFields | The fields that were requested to be amended. | AmendedFields |
Alternatively, if you identify mandates by the bank-issued mandate reference number (MRN) rather than the Stitch ID:
mutation AmendMandateByMRN(
$mandateReferenceNumber: String!,
$nonce: String!,
$reason: String!,
$authenticationChannel: MandateAuthenticationChannelEnum!,
$collectionDay: Int!
) {
paymentConsentRequestAmend(
paymentConsentIdentifier: { debicheck: { mandateReferenceNumber: $mandateReferenceNumber } },
input: {
reason: $reason,
nonce: $nonce,
debicheck: {
authenticationChannel: $authenticationChannel,
collection: {
collectionDay: $collectionDay
}
}
}
) {
id
status {
... on PaymentConsentGranted {
__typename
date
}
}
amendmentDetails {
status
statusReason
expectedAction
}
}
}
Amendment Fields
The table below describes the fields of the debicheck amendment object in the above mutation. All fields are optional — supply only the fields you want to amend.
| Name | Description | Type |
|---|---|---|
| authenticationChannel | The authentication mechanism used for the amendment. One of authRealtime, authEndOfDay, auth48Hour, or registeredMandate. | String |
| contractReference | The creditor contract number for the end-user. Can only be amended before the first collection is made. | String |
| collection.firstCollectionAmount | The amount of the first collection. | Money |
| collection.instalmentAmount | The recurring instalment amount to collect. | Money |
| collection.maximumCollectionAmount | The maximum amount that may be collected. | Money |
| collection.dayAdjustmentAllowed | Whether the collection day may be adjusted. | Boolean |
| collection.amountAdjustmentFrequency | How often the collection amount may be adjusted. One of never, quarterly, biannually, annually, or repo. | String |
| collection.adjustmentAmount | The exact amount by which the instalment amount may be adjusted. Provide only one of adjustmentAmount or adjustmentRate. | Money |
| collection.adjustmentRate | The rate by which the instalment amount may be adjusted. Provide only one of adjustmentAmount or adjustmentRate. | Decimal |
| collection.trackingIndicator | Whether account tracking is enabled for the mandate. | Boolean |
| collection.firstCollectionDate | The date of the first collection, in YYYY-MM-DD format. | String |
| collection.collectionDay | The day on which collections occur. | Int |
| customer.fullName | The customer's full name. | String |
| customer.accountNumber | The customer's bank account number. Must be an account at the same bank — changing the debtor bank requires a new mandate. | String |
| customer.accountType | The customer's account type. One of current or savings. | String |
| customer.identifyingDocument | The customer's identifying document details. | Object |
| customer.phoneNumber | The customer's mobile number. | String |
| customer.email | The customer's email address. | String |
| customer.debtorBranchCode | The debtor bank branch code (6 characters). The debtor bank cannot be changed by amending the mandate — a new mandate is required. | String |
The following values for $reason field are accepted:
| Reason code | Description |
|---|---|
CUSTOMER_REQUEST | Request by customer |
INITIATOR_REQUEST | Amendment requested by initiating party |
GENERAL | Reason has not been specified by customer |
UNSUSPEND_WITH_CHANGE | Unsuspend a mandate with changes |
UNSUSPEND_WITHOUT_CHANGE | Unsuspend an unchanged mandate |
UPGRADE_RM_WITH_CHANGES | Upgrade registeredMandate with changes |
UPGRADE_RM_WITHOUT_CHANGES | Upgrade registeredMandate without changes |
Identifier Resolution
Provide exactly one of consentRequestId or paymentConsentIdentifier.debicheck.mandateReferenceNumber. Supplying both or neither will be rejected with BAD_USER_INPUT. An identifier that doesn't resolve to a consent request for your client returns NOT_FOUND.
The mutation additionally requires the consent request to be GRANTED before it will proceed, or PAUSED when the reason is one of the unsuspension reasons (UNSUSPEND_WITH_CHANGES, UNSUSPEND_WITHOUT_CHANGES).
In case of failed validation, the below error codes would be returned:
| Error | Description |
|---|---|
| NOT_FOUND | No consent request matches the supplied paymentConsentIdentifier.debicheck.mandateReferenceNumber or consentRequestId |
| BAD_USER_INPUT | Invalid identifier combination. See Identifier Resolution |
| NONCE_DUPLICATE | Nonce provided is already in use |
| BAD_USER_INPUT | Failed amendment validation rules |
Example error response payload from AmendMandate mutation
{
"errors": [
{
"message": "Invalid amendment consent inputs",
"locations": [
{
"line": 8,
"column": 3
}
],
"path": [
"paymentConsentRequestAmend"
],
"extensions": {
"errors": [
{
"property": "collection.instalmentAmount.quantity",
"description": "Collection Amount exceeds maximum."
}
],
"code": "BAD_USER_INPUT"
}
}
],
"data": null
}
Webhooks
When amendment requests are either successful or failed, a webhook will be sent with the status, and amended fields or failure reason respectively. Please see the webhooks section in the integration guide for information on integrating webhooks.
Example webhook payload for a success case
{
"datetime": "2023-05-10T12:22:42.865Z",
"id": "payment-consent-request:status:granted:cmVjdXJyaW5nUGF5bWVudENvbnNlbnRSZXF1ZXN0L2NiNmYyYmQ5LTVjODgtNDFmOS04MmE1LWE0NWEyNDYxMGJmNg==",
"type": "payment-consent-request",
"data": {
"createdAt": "2023-06-11T11:52:49.230Z",
"id": "cmVjdXJyaW5nUGF5bWVudENvbnNlbnRSZXF1ZXN0L2NiNmYyYmQ5LTVjODgtNDFmOS04MmE1LWE0NWEyNDYxMGJmNg==",
"nonce": "2296ad8e-15a4-4f73-a0ad-fb9f7194fb52",
"status": "GRANTED",
"type": "DEBICHECK",
"externalReference": "my-external-reference",
"updatedAt": "2023-06-21T11:52:49.230Z",
"metadata": {
"billingAddress": "{\"addressLine1\": \"123 Test Street\",\"addressLine2\": \"Apartment 4A\",\"city\": \"Cape Town\", \"province\": \"Western Cape\",\"postalCode\": \"8001\",\"country\": \"ZA\"}"
},
"statusReason": "MFA_ACCEPTED",
"consentDetails": {
"accountTracking": true,
"contractReference": "CONTRACT123",
"mandateReferenceNumber": "098765432123456789",
"authenticationChannel": "authRealtime",
"bankReasonCode": null,
"bankReasonDescription": null,
"collection": {
"dayAdjustmentAllowed": true,
"adjustmentAmount": 0,
"adjustmentRate": 0,
"amountAdjustmentFrequency": "annually",
"collectionDay": 7,
"debitValueType": "variable",
"collectionFrequency": "monthly",
"instalmentAmount": {
"quantity": 1000,
"currency": "ZAR"
},
"maximumCollectionAmount": {
"quantity": 1500,
"currency": "ZAR"
},
"firstCollectionDate": "2024-01-01",
"firstCollectionAmount": {
"quantity": 500,
"currency": "ZAR"
}
},
"customer": {
"phoneNumber": "0821234567",
"email": "john.doe@example.com",
"accountName": "John Doe Account",
"bankBranchCode": "123456",
"accountNumber": "1234567890",
"accountType": "CURRENT",
"fullName": "John Doe",
"identifyingDocument": {
"type": "IDENTITY_DOCUMENT",
"country": "ZA",
"number": "8001015009087"
}
},
"creditor": {
"schemeName": "CREDITOR_SCHEME_001",
"name": "Example Creditor Ltd",
"phoneNumber": "+27123456789",
"email": "creditor@example.com",
"accountNumber": "9876543210",
"branchCode": "654321",
"ultimateCreditorName": "Ultimate Creditor Name",
"ultimateCreditorAbbreviatedShortName": "UCN"
}
},
"amendment": {
"status": "SUCCESS",
"statusReason": "MFA_ACCEPTED",
"reason": "CUSTOMER_REQUEST",
"bankReasonCode": null,
"bankReasonDescription": null,
"amendedFields": {
"collectionDay": 7
}
}
}
}
Example webhook payload for a failure case
{
"datetime": "2023-05-10T12:22:42.865Z",
"id": "payment-consent-request:status:granted:cmVjdXJyaW5nUGF5bWVudENvbnNlbnRSZXF1ZXN0L2NiNmYyYmQ5LTVjODgtNDFmOS04MmE1LWE0NWEyNDYxMGJmNg==",
"type": "payment-consent-request",
"data": {
"createdAt": "2023-06-11T11:52:49.230Z",
"id": "cmVjdXJyaW5nUGF5bWVudENvbnNlbnRSZXF1ZXN0L2NiNmYyYmQ5LTVjODgtNDFmOS04MmE1LWE0NWEyNDYxMGJmNg==",
"nonce": "2296ad8e-15a4-4f73-a0ad-fb9f7194fb52",
"status": "GRANTED",
"type": "DEBICHECK",
"externalReference": "my-external-reference",
"updatedAt": "2023-06-21T11:52:49.230Z",
"metadata": {
"billingAddress": "{\"addressLine1\": \"123 Test Street\",\"addressLine2\": \"Apartment 4A\",\"city\": \"Cape Town\", \"province\": \"Western Cape\",\"postalCode\": \"8001\",\"country\": \"ZA\"}"
},
"statusReason": "MFA_ACCEPTED",
"consentDetails": {
"accountTracking": true,
"contractReference": "CONTRACT123",
"mandateReferenceNumber": "098765432123456789",
"authenticationChannel": "authRealtime",
"bankReasonCode": null,
"bankReasonDescription": null,
"collection": {
"dayAdjustmentAllowed": true,
"adjustmentAmount": 0,
"adjustmentRate": 0,
"amountAdjustmentFrequency": "annually",
"collectionDay": 1,
"debitValueType": "variable",
"collectionFrequency": "monthly",
"instalmentAmount": {
"quantity": 1000,
"currency": "ZAR"
},
"maximumCollectionAmount": {
"quantity": 1500,
"currency": "ZAR"
},
"firstCollectionDate": "2024-01-01",
"firstCollectionAmount": {
"quantity": 500,
"currency": "ZAR"
}
},
"customer": {
"phoneNumber": "0821234567",
"email": "john.doe@example.com",
"accountName": "John Doe Account",
"bankBranchCode": "123456",
"accountNumber": "1234567890",
"accountType": "CURRENT",
"fullName": "John Doe",
"identifyingDocument": {
"type": "IDENTITY_DOCUMENT",
"country": "ZA",
"number": "8001015009087"
}
},
"creditor": {
"schemeName": "CREDITOR_SCHEME_001",
"name": "Example Creditor Ltd",
"phoneNumber": "+27123456789",
"email": "creditor@example.com",
"accountNumber": "9876543210",
"branchCode": "654321",
"ultimateCreditorName": "Ultimate Creditor Name",
"ultimateCreditorAbbreviatedShortName": "UCN"
}
},
"amendment": {
"status": "FAILED",
"statusReason": "ACCOUNT_STOPPED",
"reason": "CUSTOMER_REQUEST",
"bankReasonCode": "900004",
"bankReasonDescription": "Payment stopped by Account Holder",
"amendedFields": {
"collectionDay": 7
}
}
}
}
A failed amendment never changes the mandate's own status , it stays GRANTED, and the top-level statusReason continues to describe the mandate's status. Only the nested amendment object describes the outcome of the amendment attempt.
Amendment Webhook Fields
The table below describes the fields in the amendment object.
| Name | Description | Type |
|---|---|---|
| status | The status of the amendment attempt. One of PENDING, PROCESSING, SUCCESS, or FAILED. | String |
| statusReason | Additional context about the current state or outcome of the amendment. On success this is MFA_ACCEPTED if the amendment required customer re-authentication, or SUCCESS if it did not (notification-only) or it was for a registered-mandate amendment. See the possible values below. | String |
| reason | The original reason supplied when the amendment was requested, echoed back regardless of outcome. | String |
| bankReasonCode | The original reason code returned by the bank, if any. | String |
| bankReasonDescription | The description of the reason code returned by the bank, if any. | String |
| amendedFields | The fields that were requested to be amended. | Object |
Amendment Status Reasons
The statusReason field on a Payment Consent Amendment provides additional context about the current state or outcome of the amendment. The table below lists all possible values.
| Value | Description |
|---|---|
SUCCESS | The amendment was successfully processed. |
ACCOUNT_DORMANT | The amendment failed because the account is dormant. |
ACCOUNT_HOLDER_DECEASED | The amendment failed because the account holder is deceased. |
ACCOUNT_INVALID | The amendment failed because the account number is invalid or closed. |
ACCOUNT_STOPPED | The amendment failed because the account has been stopped. |
ACCOUNT_TYPE_RESTRICTED | The amendment failed because the account type does not allow debit collections. |
ACCOUNT_UNDER_LEGAL | The amendment failed because the account is under legal restriction. |
ACQUIRER_CONFIG_ERROR | The amendment failed due to a configuration error on the acquirer side. |
ACQUIRER_INTERNAL_ERROR | The amendment failed due to an internal error at the acquirer. |
DUPLICATE | A duplicate amendment request was detected. |
INSUFFICIENT_FUNDS | The amendment failed because the account does not have sufficient funds. |
INVALID_INPUT | The amendment request contained invalid input. |
INVALID_PERSONAL_DETAILS | The personal details provided do not match the account holder's details. |
ISSUER_INTERNAL_ERROR | The amendment failed due to an internal error at the issuing bank. |
LIMITS_EXCEEDED | The amended amount exceeds the account or mandate limits. |
MANDATE_CANCELLED | Unable to amend a cancelled mandate. |
MANDATE_EXPIRED | Unable to amend an expired mandate. |
MANDATE_PROCESSING | Unable to amend a mandate that is still being processed by the bank. |
MANDATE_SUSPENDED | Unable to amend a suspended mandate. |
MFA_ACCEPTED | The customer accepted the authentication prompt for the amendment. |
MFA_EXPIRED | The customer's authentication prompt for the amendment expired before they responded. |
MFA_FAILED | The customer's authentication for the amendment failed. |
MFA_REJECTED | The customer rejected the authentication prompt for the amendment. |
NEW_MANDATE_REQUIRED | The requested change cannot be amended; a new mandate is required. |
REAUTHENTICATION_REQUIRED | The amendment requires the customer to re-authenticate the mandate. |
TRANSMISSION_ERROR | The amendment failed due to a transmission error when communicating with the bank. |
UNKNOWN | The reason is unknown. |