Web Application Integration Process
This integration guide pertains to applications built using web-based frameworks. Stitch provides a JavaScript client-side SDK for accepting wallet payments. Stitch also vends framework-agnostic Web and React components to support quickly adding wallet payment buttons to your interface. The component supports customisation within the brand guidelines stipulated by Apple Pay, Samsung Pay and Google Pay™.
To offer all supported wallet providers, the aforementioned configuration must be completed and the payment methods must be enabled on your Stitch client.
Client
Description | Package | Language/Framework |
---|---|---|
Stitch SDK | @stitch-money/client | JavaScript |
React Components | @stitch-money/react | ReactJS |
Web Components | @stitch-money/web | Web/Angular |
Component Interactions
This sequence diagram outlines the high-level client and server-side component interactions for Apple Pay, Samsung Pay and Google Pay. The component interactions are generalised across providers, but note that the flows differ subtly. For example, there is no merchant verification step required for Google Pay.
Client-side Integration
SDK Integration
The integration can be sub-divided into three sections: installing the SDK, handling supported payment methods, and creating a payment button.
Installation
Run the following command to install the SDK and component package applicable to your client-side framework. The @stitch-money/web
package should be used for non-React applications.
- React
- Angular
- JS
npm install @stitch-money/client @stitch-money/react
npm install @stitch-money/client @stitch-money/web
npm install @stitch-money/client @stitch-money/web
Import and initialise the SDK.
import { StitchWalletClientSdk } from '@stitch-money/client';
const stitchWalletClient = new StitchWalletClientSdk({
clientId: 'your Stitch client ID',
});
Supported Payment Methods
Call supportedPaymentMethods
to fetch a list of supported wallets on the device and/or browser. The PayWithWalletButton
component can be used to render a payment button for any supported wallet. The method returns an array of WalletType
, where the inclusion of an enum value indicates that the provider is applicable to the device/browser.
supportedPaymentMethods
should be used to inform the set of payment buttons to surface to the user in your application. For example, if supportedPaymentMethods
returns ["SAMSUNG_PAY", "GOOGLE_PAY"]
for an Android device with a card provisioned in both the Samsung Wallet and Google Pay apps, then you may choose to display one or both payment buttons using the pre-built component.
Creating Payment Button
Define callback functions for each wallet type to verify a payment session and create a payment. Note that a verify
callback is only required for Apple Pay and Samsung Pay. These callbacks must be supplied as arguments along with related payment information to the onClick
handler functions contained in the SDK. See the example below for representative callback function implementations.
The create payment callback receives two arguments:
paymentToken
: A base64-encoded token used to initiate a transaction, andfingerprint
: a base64-encoded string containing the user's device fingerprint.
Both of these parameters must be provided when initating the transaction via the Stitch API from your server.
Bind each PayWithWalletButton
component (or wrapped web component) onclick
event with the corresponding onClick
handler function exported from the client-side SDK, e.g., onClickApplePaySessionHandler(...)
. Instantiate each handler function with the set of required and optional arguments.
Both verify
and createPayment
callback functions are required.
The validationUrl
is automatically retrieved within onClickApplePaySessionHandler
once an Apple Pay web session has been requested (via user interaction with the payment button). This URL must be a domain that has been previously verified in order for validation to be successful and enable the payment process to continue.
Both verify
and createPayment
callback functions are required.
A callback
or return URL must specified to handle the redirect after the payment has been verified by the user. When moving to this callback URL after user verification, the Samsung Pay Web checkout server adds the reference ID as a query parameter, called ref_id
(i.e. https://your.callback.url?ref_id={referenceID}). For more information on consuming the reference identifier, visit the Samsung Pay developer documentation. This reference must be supplied on the server-side when creating a payment via the Stitch API.
Only a createPayment
callback function is required.
Only information related to the display of the payment sheet is required; no billing or address information needs to be supplied.
Component Implementation
- React
- Angular
- JavaScript
Import the PayWithWalletButton
component and styles directly from the @stitch-money/react
package to create the payment button.
import {
type PayWithWalletButtonProps,
PayWithWalletButton,
} from "@stitch-money/react";
import "@stitch-money/react/build/styles/css";
For an Angular application, you will first need to create a standalone component that can be composed into your application. The web component exported from @stitch-money/web
is a modular HTML element that should be used to define the template for the component.
Use the apple-pay-enabled
, samsung-pay-enabled
and google-pay-enabled
boolean attributes to create buttons for Apple, Samsung and Google Pay respectively.
The stitch-gateway-merchant-id
and google-pay-merchant-id
attributes must be specified to create a Google Pay payment button using the web component. These correspond to your Stitch-supplied merchant identifier and Google merchant ID received post-registration.
The @Input
properties in the component class are not required i.e. do not need to be supplied by a parent component. These values can be defined directly in the standalone component and/or template file.
- Apple Pay
- Samsung Pay
- Google Pay
<!-- apple-pay-button.component.html -->
<stitch-pay-with-wallet
[attr.merchant-name]="merchantName"
[total]="total"
apple-pay-enabled
[attr.apple-pay-button-type]="applePayButtonType"
[attr.apple-pay-button-appearance]="applePayButtonAppearance"
[attr.google-pay-button-type]="googlePayButtonType"
[attr.google-pay-button-appearance]="googlePayButtonAppearance"
[onClick]="onClickHandler()"
>
</stitch-pay-with-wallet>
// apple-pay-button.component.ts
import { CUSTOM_ELEMENTS_SCHEMA, Component, Input } from '@angular/core';
import {
PayWithWallet as PayWithWalletWC,
type ApplePayButtonStyle,
type ApplePayButtonType,
} from '@stitch-money/web';
console.assert(PayWithWalletWC !== undefined);
@Component({
selector: 'apple-pay-wallet-button',
templateUrl: './apple-pay-button.component.html',
schemas: [CUSTOM_ELEMENTS_SCHEMA],
standalone: true,
})
export class ApplePayButtonComponent {
@Input() merchantName?: string;
@Input() applePayButtonType?: ApplePayButtonStyle;
@Input() applePayButtonAppearance?: ApplePayButtonStyle;
@Input() total?: string;
onClickHandler (_parameters?: {
googlePay?: { paymentData: google.payments.api.PaymentData };
}) {
// Define handler logic
}
}
<!-- samsung-pay-button.component.html -->
<stitch-pay-with-wallet
[attr.merchant-name]="merchantName"
[total]="total"
samsung-pay-enabled
[attr.apple-pay-button-type]="applePayButtonType"
[attr.apple-pay-button-appearance]="applePayButtonAppearance"
[attr.google-pay-button-type]="googlePayButtonType"
[attr.google-pay-button-appearance]="googlePayButtonAppearance"
[onClick]="onClickHandler()"
>
</stitch-pay-with-wallet>
// samsung-pay-button.component.ts
import { CUSTOM_ELEMENTS_SCHEMA, Component, Input } from '@angular/core';
import {
PayWithWallet as PayWithWalletWC,
type ApplePayButtonStyle,
type ApplePayButtonType,
} from '@stitch-money/web';
console.assert(PayWithWalletWC !== undefined);
@Component({
selector: 'samsung-pay-wallet-button',
templateUrl: './samsung-pay-button.component.html',
schemas: [CUSTOM_ELEMENTS_SCHEMA],
standalone: true,
})
export class SamsungPayButtonComponent {
@Input() merchantName?: string;
@Input() total?: string;
onClickHandler () {
// Define handler logic
}
}
<!-- google-pay-button.component.html -->
<stitch-pay-with-wallet
[attr.stitch-gateway-merchant-id]="gatewayMerchantId"
[attr.google-merchant-id]="googlePayMerchantId"
[attr.merchant-name]="merchantName"
[total]="total"
google-pay-enabled
[attr.apple-pay-button-type]="applePayButtonType"
[attr.apple-pay-button-appearance]="applePayButtonAppearance"
[attr.google-pay-button-type]="googlePayButtonType"
[attr.google-pay-button-appearance]="googlePayButtonAppearance"
[onClick]="onClickHandler()"
>
</stitch-pay-with-wallet>
// google-pay-button.component.ts
import { CUSTOM_ELEMENTS_SCHEMA, Component, Input } from '@angular/core';
import {
PayWithWallet as PayWithWalletWC,
type ApplePayButtonStyle,
type ApplePayButtonType,
} from '@stitch-money/web';
console.assert(PayWithWalletWC !== undefined);
@Component({
selector: 'google-pay-wallet-button',
templateUrl: './google-pay-button.component.html',
schemas: [CUSTOM_ELEMENTS_SCHEMA],
standalone: true,
})
export class GooglePayButtonComponent {
@Input() googlePayMerchantId?: string;
@Input() gatewayMerchantId?: string;
@Input() merchantName?: string;
@Input() googlePayButtonType?: google.payments.api.ButtonType;
@Input() googlePayButtonAppearance?: google.payments.api.ButtonColor;
@Input() total?: string;
onClickHandler (_parameters?: {
googlePay?: { paymentData: google.payments.api.PaymentData };
}) {
// Define handler logic
}
}
The web component can be used in any standard JavaScript application by including the custom element in an HTML file and using a script
tag to import the module. In this example, it is assumed that the PayWithWallet
component is exported in a seperate JavaScript file /src/pay-with-wallet.ts
.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Web Component Example</title>
<link rel="stylesheet" href="./src/index.css" />
<script type="module" src="/src/pay-with-wallet.ts"></script>
</head>
<body>
<style>
stitch-pay-with-wallet {
--button-border-radius: 20px;
}
</style>
<stitch-pay-with-wallet
stitch-gateway-merchant-id="merchant.energy.bigbag"
google-merchant-id="AAAABBBCC123"
merchant-name="Web Test"
total="100"
google-pay-enabled
></stitch-pay-with-wallet>
</body>
<script>
const button = document.querySelector('stitch-pay-with-wallet');
button.onClick = () => {
console.log('button clicked!');
};
</script>
</html>
Sample Implementation
While the following example assumes the use of React, the callback function logic is framework-agnostic and the sample code is valid for any integration.
- Apple Pay
- Samsung Pay
- Google Pay
import {
StitchWalletClientSdk,
WalletType,
type ApplePaySession,
type StitchTransaction,
} from "@stitch-money/client";
import {
PayWithWalletButton,
PayWithWalletButtonProps,
} from "@stitch-money/react";
import "@stitch-money/react/build/styles/css";
import { useCallback, useEffect, useState } from "react";
import { useRouter } from "next/router";
export interface WalletPayButtonProps {
amount: number;
reference: string;
disabled?: boolean;
}
export default function WalletPayButton({
amount,
reference,
disabled = false,
}: WalletPayButtonProps) {
const router = useRouter();
const [supportedMethods, setSupportedMethods] = useState<WalletType[]>([]);
const [selectedMethod, setSelectedMethod] = useState<WalletType | null>(null);
const stitchWalletClient = new StitchWalletClientSdk({});
useEffect(() => {
async function getSupportedPaymentMethods() {
const result = await stitchWalletClient.supportedPaymentMethods()
setSupportedMethods(result);
}
getSupportedPaymentMethods();
}, []);
const createApplePayPaymentCallback = useCallback(
async (paymentToken: unknown, fingerprint: unknown) => {
const response = await fetch(
`/api/wallet/apple-pay/create`,
{
method: "POST",
body: JSON.stringify({
paymentToken,
amount: {
quantity: amount,
currency: "ZAR",
},
externalReference: reference,
fingerprint,
}),
}
);
const transaction = (await response.json()) as StitchTransaction;
if (transaction.status === "TransactionSuccess") {
router.push("/success");
}
return { status: transaction.status };
},
[amount, router, selectedMethod]
);
const applePayVerifyCallback = useCallback(async (url: string) => {
const response = await fetch("/api/wallet/apple-pay/verify", {
method: "POST",
body: JSON.stringify({
validationUrl: url,
initiativeContext: window.location.hostname,
}),
});
const session = (await response.json()) as Promise<ApplePaySession>;
return session;
}, []);
const onClickApplePay = useCallback<
PayWithWalletButtonProps["onClick"]
>(() => {
setSelectedMethod(WalletType.ApplePay);
const applePaySessionHandler =
stitchWalletClient.onClickApplePaySessionHandler(
"ZAR",
amount,
"Stitch",
applePayVerifyCallback,
createApplePayPaymentCallback
);
try {
applePaySessionHandler();
} catch (error) {
console.error(`Error starting Apple Pay session: ${error}`);
}
}, [amount, applePayVerifyCallback, createApplePayPaymentCallback]);
if (supportedMethods.includes(WalletType.ApplePay)) {
return (
<>
<PayWithWalletButton
supportedMethods={[WalletType.ApplePay]}
onClick={onClickApplePay}
disabled={disabled}
total={`${amount}`}
/>
</>
);
}
}
import {
StitchWalletClientSdk,
WalletType,
type SamsungPaySession,
type StitchTransaction,
} from "@stitch-money/client";
import {
PayWithWalletButton,
PayWithWalletButtonProps,
} from "@stitch-money/react";
import "@stitch-money/react/build/styles/css";
import { useCallback, useEffect, useState } from "react";
import { useRouter } from "next/router";
export interface WalletPayButtonProps {
amount: number;
reference: string;
disabled?: boolean;
}
export default function WalletPayButton({
amount,
reference,
disabled = false,
}: WalletPayButtonProps) {
const router = useRouter();
const [supportedMethods, setSupportedMethods] = useState<WalletType[]>([]);
const [selectedMethod, setSelectedMethod] = useState<WalletType | null>(null);
const stitchWalletClient = new StitchWalletClientSdk({});
useEffect(() => {
async function getSupportedPaymentMethods() {
const result = await stitchWalletClient.supportedPaymentMethods()
setSupportedMethods(result);
}
getSupportedPaymentMethods();
}, []);
const samsungPayVerifyCallback = useCallback(async (amount: number) => {
const response = await fetch("/api/wallet/samsung-pay/verify", {
method: "POST",
body: JSON.stringify({
amount,
initiativeContext: `${window.location.origin}`,
callbackUrl: `${window.location.origin}/return/${amount}/${reference}`
}),
});
const session = (await response.json()) as Promise<SamsungPaySession>;
return session;
}, [reference]);
const onClickSamsungPay = useCallback(async () => {
try {
setSelectedMethod(WalletType.SamsungPay);
const samsungPaySessionHandler =
stitchWalletClient.onClickSamsungPaySessionHandler(
"ZAR",
amount,
`${window.location.origin}/return/${amount}/${reference}`,
`${window.location.origin}/error`,
samsungPayVerifyCallback
);
samsungPaySessionHandler();
} catch (error) {
console.error(`Error starting Samsung Pay session: ${error}`);
}
}, [amount, reference, samsungPayVerifyCallback]);
if (supportedMethods.includes(WalletType.SamsungPay)) {
return (
<>
<PayWithWalletButton
supportedMethods={[WalletType.SamsungPay]}
onClick={onClickSamsungPay}
disabled={disabled}
total={`${amount}`}
/>
</>
);
}
}
WALLET_MERCHANT_IDENTIFIER
is the Stitch-supplied gateway merchant ID (used for Apple and Google). Stitch automatically sets the correct gateway
in the payment button.
import {
StitchWalletClientSdk,
WalletType,
} from "@stitch-money/client";
import {
PayWithWalletButton,
PayWithWalletButtonProps,
} from "@stitch-money/react";
import "@stitch-money/react/build/styles/css";
import { useCallback, useEffect, useState } from "react";
import { useRouter } from "next/router";
export interface WalletPayButtonProps {
amount: number;
reference: string;
disabled?: boolean;
}
export default function WalletPayButton({
amount,
reference,
disabled = false,
}: WalletPayButtonProps) {
const router = useRouter();
const [supportedMethods, setSupportedMethods] = useState<WalletType[]>([]);
const [selectedMethod, setSelectedMethod] = useState<WalletType | null>(null);
const stitchWalletClient = new StitchWalletClientSdk({});
useEffect(() => {
async function getSupportedPaymentMethods() {
const result = await stitchWalletClient.supportedPaymentMethods()
setSupportedMethods(result);
}
getSupportedPaymentMethods();
}, []);
const createGooglePayPaymentCallback = useCallback(
async (paymentToken: unknown, fingerprint: unknown) => {
const response = await fetch(
`/api/wallet/google-pay/create`,
{
method: "POST",
body: JSON.stringify({
paymentToken,
amount: {
quantity: amount,
currency: "ZAR",
},
externalReference: reference,
fingerprint,
}),
}
);
const transaction = (await response.json()) as StitchTransaction;
if (transaction.status === "TransactionSuccess") {
router.push("/success");
}
return { status: transaction.status };
},
[amount, router, selectedMethod]
);
const onClickGooglePay = useCallback<PayWithWalletButtonProps["onClick"]>(
(parameters) => {
if (parameters?.googlePay) {
setSelectedMethod(WalletType.GooglePay);
const googlePaySessionHandler =
stitchWalletClient.onClickGooglePaySessionHandler(
createGooglePayPaymentCallback
);
try {
googlePaySessionHandler(parameters?.googlePay?.paymentData);
} catch (error) {
console.error(`Error starting Google Pay session: ${error}`);
}
}
},
[createGooglePayPaymentCallback]
);
if (supportedMethods.includes(WalletType.GooglePay)) {
return (
<>
<PayWithWalletButton
supportedMethods={[WalletType.GooglePay]}
googlePayMerchantId={"YOUR_GOOGLE_PAY_MERCHANT_ID"}
gatewayMerchantId={"WALLET_MERCHANT_IDENTIFIER"}
onClick={onClickGooglePay}
disabled={disabled}
total={`${amount}`}
/>
</>
);
}
}
Server-side Integration
The integration with the Stitch API should run on your trusted application server as calls are authenticated using your sensitive Stitch credentials. This guide describes integrating directly via the Stitch API.
The GraphQL API URL https://api.stitch.money/graphql can be used for all wallet requests (whether on test or live clients). Note that a Stitch client token with the scope transaction_initiate
is required to validate wallet merchants, or initiate any wallet transactions, via the API.
Validation API
The verify
SDK function encapsulates two distinct Stitch API interactions for Apple Pay and Samsung Pay - the validateApplePayMerchant
and verifySamsungPay
mutations. These mutations must be called in the server-side verification API routes for each wallet provider and are required before a payment can be initiated.
- Apple Pay
- Samsung Pay
The intitiative
field in the ValidateApplePayMerchantInput
input object must always be set to web
.
The intitiativeContext
field in the ValidateApplePayMerchantInput
input object refers to the fully qualified domain name where the request is originated (web application) and must match the domain associated with Apple under the merchantIdentifier
specified.
For Apple Pay, the sessionData
object in the validateApplePayMerchant
response must be converted to a JSON object before being returned by the server-side verify
API endpoint handler.
For Samsung Pay, the merchantSession
object in the verifySamsungPay
response must be returned unaltered by the server-side verify
API endpoint handler.
Setting the intiativeContext
field to test.stitch.money
returns mock session data.
Note that this session data cannot be used to verify and instantiate a client-side wallet provider session. This should be used to test server-side calls in isolation. Set this field with the verified domain when testing end-to-end transaction processing.
Transaction Initiation API
To create a wallet payment, a Stitch API initiateTransaction
mutation call is required in order to initiate the payment. The mutation must be called in the server-side payment creation API routes for each wallet provider.
The input
variable object must be constructed distinctly for each wallet provider to correctly replicate the interaction encapsulated by the create
SDK function.
The fingerprint argument supplied to the create payment callback on the client side should be specified in the deviceInformation.fingerprint
field. If this is unable to be provided, other fields within the deviceInformation
object are required, including all of deviceId
, ip
and screenDimensions
.
- Apple Pay
- Samsung Pay
- Google Pay
For Apple Pay and Google Pay payments, the payment token must be Base64-encoded. The Apple Pay payment token is a JavaScript object and is a serialised object for Google Pay.
The state
field contained in the response is a synchronous update on the status of a payment. Note that this status will also be returned once subscribed to updates via webhook.
Enforcing 3DS
The default configuration for Wallet transactions is for 3DS to not be enforced across transactions. However, if it is required to enforce 3DS on a per-transaction basis, this is done by specifying the requireSecure3d
boolean as true
within the respective payment method input, for example applePay.requireSecure3d
. These are shown in the Variables of the example requests, below:
- Apple Pay
- Samsung Pay
- Google Pay
The requireSecure3d
parameter should only be specified if your client is configured to allow you to control performing 3DS on payments. Including this parameter without proper configuration will result in an invalid configuration error. Please reach out to Stitch if you would like to enable this feature.
Handling Transaction Responses
Default Transactions
In the default setup, with 3DS not enforced on a transaction, the state
field contained in the response is a synchronous update on the status of a payment. This will either be TransactionSuccess
or TransactionFailure
(with a corresponding reason). Note that this status will also be returned as a webhook update, when subscribed to transaction
webhooks.
3DS-Enforced Transactions
Should 3DS have been enforced on a transaction (whether dynamically, based on agreed-upon configuration with Stitch, or per-transaction as described above), a transaction initiation response will return a TransactionPending
status, as well as an interactionUrl
.
The user must visit this URL, after appending a redirect_uri
query parameter. This will guide the user through the required 3DS interaction to complete their transaction.
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/02fa5c7f-3aea-4545-b4e9-5af7e128ff47?redirect_uri=https%3A%2F%2Fexample.payment
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.
Parameter | Description |
---|---|
transactionId | The payment's Stitch ID |
flow | The 3DS interaction type i.e. challenge or frictionless |
externalReference | The payment's external reference |
status | The payment's final status i.e. TransactionSuccess or TransactionFailure |
statusReason | The optional reason for the payment's status |
You will also receive a corresponding transaction
webhook to confirm the status of the transaction.
Transaction Statuses
The table below describes the different statuses of a wallet payment:
Status | Description |
---|---|
TransactionPending | A payment is initialised and awaiting user authentication. If an interactionUrl is returned, the user should be directed to this for the transaction to proceed. |
TransactionFailure | A payment authorised by a user but unsuccessful and the requested funds were not captured. |
TransactionSuccess | A payment has been successfully made and the requested funds were captured. |
Failure Reasons
The TransactionFailure
status indicates that the wallet transaction failed to be initiated, and includes a reason
explaining the cause.
Potential failure reasons are detailed below:
Reason | Description |
---|---|
authorizationFailed | The transaction was declined or blocked. |
authorizationNotFinalised | The transaction could not be processed by the acquirer. |
blockedByFraudChecks | The transaction was blocked due to fraud checks. |
downstreamProviderError | The transaction could not be processed due to downstream error. |
exceedsCardWithdrawalLimit | The transaction was declined due to withdrawal limits exceeded. |
insufficientFunds | The transaction was declined due to insufficient funds. |
internalServerError | The transaction could not be processed due to a server error. |
invalidCardError | The transaction was declined due to an expired card. |
invalidConfigurationError | The client has invalid or missing configuration. |
invalidTransactionError | The authorised payment amount (for the payment token) does not match the transaction input amount. |
secure3dDeclined | The user has declined 3DS authentication. |
secure3dLookupFailed | 3DS authentication attempt could not be initiated. |
secure3dNotCompleted | The user has not completed 3DS authentication. |
tokenDecryptionError | The payment token could not be decrypted. |
Querying Transactions
Transaction by ID
For implementing redundancy checks and logic, it is possible to query transaction statuses and details over the Stitch GraphQL API. Note that querying with the Stitch-provided id
is the most performant, and the recommended approach.
Transaction by External Reference
Alternatively, querying by an externalReference
is possible, and may be done with a filtering query, as follows:
When including this filter, the specific type of wallet transaction is required together with the external reference. As an example, the ApplePayTransaction
query is shown above for Apple Pay transactions.
Webhook Subscriptions
Wallet payments require that you subscribe to transaction
webhooks to receive asynchronous updates on transaction status changes.
If the subscription is successfully created, the body returned by the request will look similar to the sample in the Example Response
tab in the widget above.
The webhook will contain important information regarding the transaction, including the selected wallet provider, the transaction retrieval reference number (RRN) (used for reconcilliation), external reference, and nonce.
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
When subscribed to the transaction
webhook filter type, webhook updates will be sent whenever a transaction is updated to either of the following statuses:
TransactionSuccess
TransactionFailure
Testing Payment Initiation
To test payment initiation, you may use any device supported by the wallet providers applicable to your selected integration. See the Google Pay integration checklist for a more detailed description of recommended testing. Note that not all test cases/paths are applicable to the gateway integration.
- Payment initiation testing only applies to Stitch test clients.
- A real and valid credit/debit card must be added to either the Apple, Samsung and/or Google Wallet application.
- No funds will be captured when completing a payment with a real card and a transaction initiated by a test client.
Test Device Tokens
To simulate transaction initiation requests on test clients, you can specify J2V4YW1wbGVQYXltZW50TWV0aG9kVG9rZW4n as the paymentToken
to bypass token decryption and validation that would normally be performed on a real token.
Test Cards
Testing the integration on a real device may require linking a test card to that device. For each wallet method this approach is distinct.
- Apple Pay
- Google Pay
- Samsung Pay
Apple provides a number of test cards that can be added to an Apple Wallet. These require registering a sandbox account and signing into a test device with that account. See Apple's Developer Sandbox Testing page for more details.
Using a Stitch Test client for Google Pay does not require adding a card to the device used to initiate payment. You will need to add the Google Account on the device to the following Google Group. Clicking the Google Pay button will then display a suite of test cards to choose from for completing a test payment.
Samsung Pay requires a card from your acquirer. Please contact support@stitch.money for more information on this.
Simulating Transaction Statuses
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 transaction statuses:
Amount | Status | Reason |
---|---|---|
1.01 | FAILURE | insufficientFunds |
4.04 | FAILURE | authorizationFailed |
Other | SUCCESS | - |