React SDK - Overview
Version 2.1.7 or later required
Fat Zebra is updating its 3D Secure integration. Merchants using this SDK must be on @fat-zebra/sdk 2.1.7 or later for 3DS to keep working. See the Upgrade Notice for details.
Introduction
Fat Zebra provides a JavaScript package called @fat-zebra/sdk that enables merchants to access features including:
- 3DS2
- Card tokenization
Authentication
Each feature accessible via the SDK requires OAuth authentication whereby merchants obtain an OAuth access token for each payment session required. Refer to Obtain an OAuth token for more details.
Usage
First, install the package (version 2.1.7 or later):
npm install @fat-zebra/sdk@^2.1.7Or add it to your package.json as a dependency:
"dependencies": {
"@fat-zebra/sdk": "^2.1.7"
}Card verification
The processes for new card and existing card verification are separate. Each process is detailed below.
Verify a new card
To use this package, you can import the relevant parts we need from the SDK. To then verify a card, we can use the VerifyCard component along with the verification hash.
Calculation of the verification hash
The new card verification hash is calculated using reference, amount and currency.
This part needs to be done server side to protect the FATZEBRA_SHARED_SECRET variable
// server side
import { createHmac } from "crypto";
const payment = {
reference: "payment-001",
amount: 100,
currency: "AUD",
};
const newCardVerificationHash = createHmac("md5", process.env.FATZEBRA_SHARED_SECRET)
.update(`${payment.reference}:${payment.amount}:${payment.currency}`)
.digest("hex");From this action of this component, we can pull out the token from the card tokenization event, and (if required) wait until the PublicEvent.SCA_SUCCESS event has happened before continuing with a customer's purchase.
The reference, amount and currency passed to the component must match the values used to calculate the hash.
Example code
// app.tsx
import VerifyNewCard from "./VerifyNewCard";
export default function Main() {
// These are typically sourced from your backend
const REFERENCE = "payment-001";
const ACCESS_TOKEN = "<oauth access token goes here>"; // see: Obtain an OAuth token
const NEW_CARD_VERIFICATION_HASH = "<calculated server side as shown above using your shared secret>";
return (
);
}// VerifyNewCard.tsx
import { useState } from "react";
import {
Environment,
Payment,
PaymentIntent,
PublicEvent,
PaymentConfig,
Handlers,
} from "@fat-zebra/sdk/dist";
import { VerifyCard } from "@fat-zebra/sdk/dist/react";
type Props = {
verification: string;
accessToken: string;
reference: string;
};
export default function VerifyNewCard({ verification, accessToken, reference }: Props) {
const [events, setEvents] = useState([]);
const addEvent = (event: CustomEvent) => {
setEvents((prev) => [...prev, event]);
};
const payment: Payment = {
reference,
amount: 100,
currency: "AUD",
};
const paymentIntent: PaymentIntent = {
payment,
verification,
};
const config: PaymentConfig = {
username: "your-username-here",
environment: Environment.sandbox, // or Environment.production
accessToken,
paymentIntent,
options: {
sca_enabled: true,
},
};
const tokenizationSuccessful = (event: CustomEvent) => {
// event.detail contains the card token: send it to your backend
addEvent(event);
};
const scaSuccess = (event: CustomEvent) => {
// event.detail contains the 3DS result fields to include in your purchase call
addEvent(event);
};
const scaError = (event: CustomEvent) => {
addEvent(event);
};
// Subscribe to the particular events you wish to handle
const handlers: Handlers = {
[PublicEvent.FORM_VALIDATION_ERROR]: addEvent,
[PublicEvent.FORM_VALIDATION_SUCCESS]: addEvent,
[PublicEvent.TOKENIZATION_SUCCESS]: tokenizationSuccessful,
[PublicEvent.SCA_SUCCESS]: scaSuccess,
[PublicEvent.SCA_ERROR]: scaError,
};
return (
<div className="App flex gap-8 mx-8">
<div className="w-1/2">
</div>
</div>
);
}Verify Existing Card
To then verify an existing card, we can use the VerifyExistingCard component.
From the action of this component, the successful or failed tokenised credit card event will fire. Indicating whether or not a card has been previously tokenised.
This component will return either: “Could not find card on file” or “fz.tokenization.success” status and run sca on each verification.
Calculation of the verification hash
The verification hash for verify an existing card is calculated by hashing the card token. This is to be done server-side as an example:
// server side
import { createHmac } from "crypto";
const CARD_TOKEN = "fdsde3yx";
// Never expose FATZEBRA_SHARED_SECRET to the client
const existingCardVerificationHash = createHmac("md5", process.env.FATZEBRA_SHARED_SECRET)
.update(CARD_TOKEN)
.digest("hex");Example code
// app.tsx
import VerifyOurCard from "./VerifyOurCard";
export default function Main() {
// These are typically sourced from your backend
const REFERENCE = "payment-001";
const ACCESS_TOKEN = "<oauth access token goes here>";
const CARD_TOKEN = "fdsde3yx";
const EXISTING_CARD_VERIFICATION_HASH = "<calculated server side as shown above using your shared secret>";
return (
);
}// VerifyOurCard.tsx
import { useState } from "react";
import {
Environment,
PaymentConfig,
PublicEvent,
Handlers,
} from "@fat-zebra/sdk/dist";
import { VerifyExistingCard } from "@fat-zebra/sdk/dist/react";
type Props = {
verification: string;
accessToken: string;
reference: string;
cardToken: string;
};
export default function VerifyOurCard({ verification, accessToken, reference, cardToken }: Props) {
const [events, setEvents] = useState<string[]>([]);
const config: PaymentConfig = {
username: "your-username-here",
environment: Environment.sandbox, // or Environment.production
accessToken,
paymentIntent: {
payment: {
reference,
amount: 100,
currency: "AUD",
},
verification,
},
options: {
sca_enabled: true, // if you are enabled for 3D Secure
},
};
const handleEvent = (event: CustomEvent) => {
setEvents((prev) => [...prev, event.type]);
};
// Subscribe to the particular events you wish to handle
const handlers: Handlers = {
[PublicEvent.TOKENIZATION_SUCCESS]: handleEvent,
[PublicEvent.TOKENIZATION_ERROR]: handleEvent,
[PublicEvent.SCA_SUCCESS]: handleEvent,
[PublicEvent.SCA_ERROR]: handleEvent,
};
return (
<>
<ol>
{events.map((event, index) => (
<li key={index}>{event}</li>
))}
</ol>
</>
);
}Creating a payment
There's currently no form support for taking a payment with this SDK.
Instead, we would recommend passing the token from a TOKENIZATION_SUCCESS event back to your backend, and then processing a payment from there using the FatZebra API.