Skip to main content

Initiating Transactions with Consent Tokens

Following the creation of consent tokens, it is seamless to initiate card transactions over the Stitch API. For any transactions that require 3DS to be completed, you will receive an interaction URL to redirect the user to, for this step. Upon successful completion of the transaction initiation, the user's card will have been charged.


info

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.

Initiating a Transaction

The initiateTransaction API call requires a client token with the scope transaction_initiate.

The GraphQL API URL https://api.stitch.money/graphql should be used for this API query (whether on test or live clients). A typical initiateTransaction API call is shown below:

API Input Fields
  • 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 request id value, representing the card that is being charged.

Payer information

The payerInformation object should be specified with information of the payer on your system's records. The set of provided information is used to increase the efficacy of fraud risk checks done by Stitch. All possible inputs may be found found in the API reference.

At a minimum, the payerId should always be specified within a request. This may be any internal identifier that always uniquely identifies users across Stitch requests.

3DS-enforcement

Typically, 3DS-enforcement rules are automatically determined by Stitch for all requests processed on your client, as described here.

However, there is a requirement to specify 3DS-enforcement on a per-request basis, the paymentMethods.card.requireSecure3d parameter can be used to enable or disable 3DS enforcement. Contact the technical team to assist in enabling your client for this feature.

Metadata

The metadata field may be populated with any additional metadata relating to your payment request, such as further order information, shipping information, or sub-entity for which the payment is being processed.

note

This must be specified as an object of type Json, that includes key-value pairs. Note that nested objects must be JSON-stringified.

To assist with fraud and risk checks performed on payments for physical goods, include shipping information within your metadata, as shown in the request examples. Values to be specified include:

  • billingAddress of the user,
  • shippingAddress of the order,
  • deliveryMethod noting whether this is a delivery or collection order, and
  • giftCardAmount if a gift card or discount code was used in conjunction with the order's payment.

Fingerprinting

If fingerprinting is required for your integration, the deviceInformation object should have a fingerprint field defined containing an encoded value. This value is obtained in your app using the relevant Stitch SDK and must be passed to your server to be used in the initiateTransaction mutation.

Handling Transaction Responses

After initiating a transaction, one of two scenarios typically occur:

  • If 3DS is not required, transaction initiation is immediately successful. The returned status in the response will indicate this, and a corresponding webhook will be sent.
  • Alternatively, if 3DS verification is required by the user, the transaction status will be pending, and you will need to redirect the user to complete this step (as described below).

In the scenario of 3DS verification being required, an interactionUrl is returned as part of the response. A redirect_uri query parameter must be appended to this interactionUrl, before the user is guided to the full URL. This will open an interaction with Stitch, guiding the user through the required 3DS verification.

As an example, if you choose to redirect your user to the whitelisted URL https://example.com/payment, you'd append the following additional query string to the url returned from the API: ?redirect_uri=https%3A%2F%2Fexample.com%2Fpayment. The full URL you would expose to the user should look similar to the following:

https://3ds.stitch.money/2ce31de7-a30d-4f3b-bfaa-cd06cb30db79?redirect_uri=https%3A%2F%2Fexample.payment
danger

The URL specified as the redirect_uri must be secure i.e. an HTTPS URL.

Once the user has successfully completed the interaction and the payment has been processed, they will be redirected back to your specified redirect_uri with the following query parameters.

ParameterDescription
idThe Stitch ID of the transaction
flowThe 3DS interaction type of the transaction: challenge or frictionless
externalReferenceThe external reference of the transaction
statusThe final status of the transaction after the user's interaction: TransactionSuccess or TransactionFailure
statusReasonThe status reason, if applicable to the transaction status

You will also receive a corresponding webhook to confirm the status of the transaction.

Transaction Statuses

The table below describes the different statuses a transaction can have:

StatusDescription
TransactionPendingThe 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.
TransactionSuccessThe 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.
TransactionFailureThe transaction failed to be charged on the user's card. An associated reason will be returned with this status.

Failure Reasons

The TransactionFailure status indicates that the card transaction failed to be initiated, and includes a reason explaining the cause.

Potential failure reasons are detailed below:

ReasonDescription
authorizationFailedThe transaction was declined or blocked.
authorizationNotFinalisedThe transaction could not be processed by the acquirer.
blockedByFraudChecksThe transaction was blocked due to fraud checks.
downstreamProviderErrorThe transaction could not be processed due to downstream error.
exceedsCardWithdrawalLimitThe transaction was declined due to withdrawal limits exceeded.
insufficientFundsThe transaction was declined due to insufficient funds.
internalServerErrorThe transaction could not be processed due to a server error.
invalidCardErrorThe transaction was declined due to an expired card.
invalidConfigurationErrorThe client has invalid or missing configuration.
invalidTransactionErrorThe transaction could not be processed due to invalid data.
secure3dDeclinedThe user has declined 3DS authentication.
secure3dLookupFailed3DS authentication attempt could not be initiated.
secure3dNotCompletedThe user has not completed 3DS authentication.
tokenDecryptionErrorThe payment token could not be decrypted.

Subscribe to Webhooks

Webhooks for transactions can be subscribed to by running the clientWebhookAdd mutation, to receive transaction webhook events.

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
Example Payload
{
"data": {
"amount": {
"currency": "ZAR",
"quantity": "1"
},
"card": {
"bin": "41111111",
"cardHolderName": "Joe Soap",
"expiryMonth": 12,
"expiryYear": 2024,
"first6": "41111111",
"id": "Y2FyZC85YWY4OGE4MS05ZjNhLTRlNDItYWRiYy04ZTA1M2Q1YTM3M2U=",
"issuer": {
"name": "capitec",
"country": "ZA"
},
"last4": "1111",
"maskedPan": "411111******1111",
"network": "Visa",
"type": "Credit"
},
"createdAt": "2023-05-10T12:22:42.865Z",
"eci": "05",
"externalReference": "79261d16-c53b-48eb-9019-dc9cfb6c5126",
"id": "Y2FyZHRyYW5zYWN0aW9uLzQwNDMxRTY5LTNERjctNEIyQS1CNDY0LURFNTQwNDc0QkMxQw==",
"nonce": "abb1c3b7-b39b-4a4c-93cb-3bbb363a3171",
"originalAmount": {
"currency": "ZAR",
"quantity": "1"
},
"paymentRequestId": "RRFyZHRyYW5zYWN0aW9uLzQwNDMxRTY5LTNERjctNEIyQS1CNDY0LURFNTQwNDc0QkMxQw==",
"retrievalReferenceNumber": "508714102541",
"secure3dDecision": "skip",
"secure3dDecisionReason": "clientSpecified",
"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:

Testing

For testing purposes, specific amounts can be used to simulate different scenarios when using a test client.

The table below shows the mapping between amounts and the transaction status reason to replicate real-world failures.

AmountStatusReason
1.01FAILUREinsufficientFunds
2.02FAILUREexceedsCardWithdrawalLimit
3.03FAILUREdownstreamProviderError
4.04FAILUREauthorizationFailed
OtherSUCCESS-

The table below shows the mapping between amounts and the riskResult outcome returned in the transaction webhook or via API.

AmountStatusOutcome
10.01SUCCESSsuspicious
11.01SUCCESSnoop
OtherSUCCESSok