Initiating Preauthorized Payments with Consent Tokens
Consent tokens can also be used to initiate preauthorized card transactions over the Stitch API. Similarly to a standard recurring card payment, an initiateTransaction
API call is used to authorize an initial amount on the user's card.
A subsequent continueTransaction
API call is used to capture an amount not exceeding the original authorization. Transactions can be automatically voided or manually cancelled using the cancelTransaction
API.
Transactions can only be initiated using consent tokens that are in the PaymentConsentGranted
state.
Attempting to initiate a transaction on a consent with any other status will result in an API error being returned.
Preauthorization
To preauthorize an initial amount on a user's card, use the initiateTransaction
API. The initiateTransaction
API call requires a client token with the scope transaction_initiate
.
- The
externalReference
field (4096-character limit) field may be used to associate the transaction to your payment/order's reference. - The
nonce
field (4096-character limit) is required to be unique per request, and hence, transaction. - The
token
field should contain the previously granted consent requestid
value, representing the card that is being charged. - The
paymentMethods.card.preAuthorization.enabled
field must be set totrue
. - The
voidAt
field optionally specifies the datetime at which the preauthorization should be voided.
Completion
To capture the preauthorized amount and complete a transaction, use the continueTransaction
API. The continueTransaction
API call requires a client token with the scope transaction_initiate
.
- The
id
field must contain the transaction ID returned in theinitiateTransaction
API response. - The
amount
field specifies the final amount to capture, up to the preauthorized value.
The capture amount
in the continueTransaction
API call must not exceed the original amount that was preauthorized in the initiateTransaction
call. Attempting to capture an amount greater than that which was preauthorized will result in an API error being returned.
Cancellation
To cancel a transaction manually and void the initial authorization, use the cancelTransaction
API. The cancelTransaction
API call requires a client token with the scope transaction_cancel
.
- Transactions are cancelled by default after 72 hours.
- A default
voidAt
for all transaction can be configured on your client. - If the
voidAt
field has been specified in theinitiateTransaction
API call, then manually cancelling the transaction is not required, but can be actioned before the duration has elapsed.
Transaction Statuses
The table below describes the different statuses a transaction can have:
Status | Description |
---|---|
TransactionPending | The transaction has been initiated, but an interaction is required for the transaction to be successfully completed. An associated reason will be returned with this status. |
TransactionSuccess | The transaction has been successfully completed, and user's card has been charged. If 3DS is disabled, or not required for the transaction, this will be returned immediately on successful intiation. |
TransactionFailure | The transaction failed to be charged on the user's card. An associated reason will be returned with this status. |
TransactionCancelled | The transaction has been cancelled automatically or manually, and the preauthorization has been successfully voided. |
Subscribe to Webhooks
Webhooks for transactions can be subscribed to by running the clientWebhookAdd
mutation, to receive transaction
webhook events. The webhook will contain originalAmount
and amount
fields that denote the preauthorized and final captured amount respectively.
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 transaction
webhook will be dispatched for each of the following status updates:
TransactionSuccess
TransactionFailure
TransactionCancelled
Example Payload
{
"data": {
"amount": {
"currency": "ZAR",
"quantity": "1"
},
"card": {
"cardHolderName": "Joe Soap",
"expiryMonth": 12,
"expiryYear": 2024,
"first6": "41111111",
"id": "Y2FyZC85YWY4OGE4MS05ZjNhLTRlNDItYWRiYy04ZTA1M2Q1YTM3M2U=",
"last4": "1111",
"network": "Visa"
},
"createdAt": "2023-05-10T12:22:42.865Z",
"externalReference": "79261d16-c53b-48eb-9019-dc9cfb6c5126",
"id": "Y2FyZHRyYW5zYWN0aW9uLzQwNDMxRTY5LTNERjctNEIyQS1CNDY0LURFNTQwNDc0QkMxQw==",
"originalAmount": {
"currency": "ZAR",
"quantity": "1"
},
"originalTransactionId": "GBFyZHRyYW5zYWN0aW9uLzQwNDMxRTY5LTNERjctNEIyQS1CNDY0LURFNTQwNDc0QkMxQw",
"paymentConsentRequestId": "FRFyZHRyYW5zYWN0aW9uLzQwNDMxRTY5LTNERjctNEIyQS1CNDY0LURFNTQwNDc0QkMxQw==",
"paymentRequestId": "RRFyZHRyYW5zYWN0aW9uLzQwNDMxRTY5LTNERjctNEIyQS1CNDY0LURFNTQwNDc0QkMxQw==",
"status": "success",
"statusReason": null,
"type": "card",
"updatedAt": "2023-05-10T12:22:42.865Z"
},
"datetime": "2023-05-10T12:22:42.865Z",
"id": "transaction:status:success:40431E69-3DF7-4B2A-B464-DE540474BC1C",
"type": "transaction"
}
Querying Transaction Status
You can check any transaction's status, as well as other corresponding details, with a query to the GraphQL API. An example query is shown below: