Skip to main content

Initialization

  1. Create .env file
  2. Store your credentials from Authentification in .env file
NEXT_PUBLIC_CLIENT_ID=YOUR_CLIENT_ID
  1. Import SDK
  • import VeryfiLens from 'veryfi-lens-wasm'
  • const VeryfiLens = require('veryfi-lens-wasm').default
  1. Add a function to validate partner and receive session token (it is necessary to initialize Lens)
const validatePartner = async (clientId: string): Promise<any> => {
const validateUrl = 'https://lens.veryfi.com/rest/validate_partner';
const requestOptions = {
method: 'POST',
headers: {
'CLIENT-ID': clientId,
},
};

return fetch(validateUrl, requestOptions)
.then((response) => response.json())
.then((data) => {
return data.session;
})
.catch((error) => {
return error;
});
};
  1. Initialize lens
useEffect(() => {
const startWasm = () => {
if (typeof window !== "undefined") {
veryfiLens.initCC(sessionToken, CLIENT_ID);
}
};
startWasm();
}, []);
  1. Get card data
useEffect(() => {
let isMounted = true;
if (veryfiLens) {
const intervalId = setInterval(async () => {
if (!isMounted) return;
try {
const data = await veryfiLens.getCardData();
setPhase(veryfiLens.getCardPhase());
if (data) {
setCardData(data);
if (
data.cvv !== "" ||
(data.status === "AutoCaptureResultDone" &&
phase === "ScanningBack")
) {
setCardData(data);
setHasData(true);
clearInterval(intervalId);
console.log("All data received, interval cleared.");
setIsEditing(true);
veryfiLens.stopCameraWasm();
return;
}
}
} catch (error) {
console.error("An error occurred while fetching data:", error);
}
}, 1000);
return () => {
isMounted = false;
clearInterval(intervalId);
};
}
}, []);
Take a look at the complete Next.js component
import React, { useEffect, Dispatch, SetStateAction, useState } from "react";
import GoHomeButton from "./GoHomeButton";

export interface CardComponentProps {
sessionToken: string;
setImage: Dispatch<SetStateAction<string>>;
setIsEditing: Dispatch<SetStateAction<boolean>>;
deviceData: any;
setDeviceData: React.Dispatch<React.SetStateAction<any>>;
setIsCard: React.Dispatch<React.SetStateAction<any>>;
cardData: {
status: string;
name: string;
number: string;
cvv: string;
date: string;
};
setCardData: React.Dispatch<
React.SetStateAction<{
status: string;
name: string;
number: string;
cvv: string;
date: string;
}>
>;
veryfiLens: any;
}

const CardComponent = ({
sessionToken,
deviceData,
setDeviceData,
setIsEditing,
cardData,
setIsCard,
setCardData,
veryfiLens,
}: CardComponentProps) => {

const [hasData, setHasData] = useState(false);
const [phase, setPhase] = useState("");
const CLIENT_ID = process.env.NEXT_PUBLIC_CLIENT_ID;

useEffect(() => {
const startWasm = () => {
if (typeof window !== "undefined") {
veryfiLens.initCC(sessionToken, CLIENT_ID);
}
};
startWasm();
}, []);

useEffect(() => {
let isMounted = true;
if (veryfiLens) {
const intervalId = setInterval(async () => {
if (!isMounted) return;
try {
const data = await veryfiLens.getCardData();
setPhase(veryfiLens.getCardPhase());
if (data) {
setCardData(data);
if (
data.cvv !== "" ||
(data.status === "AutoCaptureResultDone" &&
phase === "ScanningBack")
) {
setCardData(data);
setHasData(true);
clearInterval(intervalId);
console.log("All data received, interval cleared.");
setIsEditing(true);
veryfiLens.stopCameraWasm();
return;
}
}
} catch (error) {
console.error("An error occurred while fetching data:", error);
}
}, 1000);
return () => {
isMounted = false;
clearInterval(intervalId);
};
}
}, []);

const handleSubmit = () => {
setIsEditing(true);
veryfiLens.stopCameraWasm();
};

return (
<div className="flex relative h-full w-full">
<GoHomeButton id="go_home" setter={setIsCard} />
<div
className="flex absolute justify-center w-full h-full overflow-hidden"
id="veryfi-container"
></div>
<div className="text-black bg-white z-[100]"></div>
{
<div className="absolute flex w-full flex-col justify-center items-center z-[900]">
<div className="w-full h-full flex flex-col justify-center items-center pointer-events-none z-[60] mt-[40vh]">
<div className="border-solid loading-border-relative border-[8px] w-[400px] h-[250px] border-white rounded-xl p-4 bg-black bg-opacity-30 relative overflow-hidden">
{cardData && (
<div>
<p className="text-white text-xl m-10 ml-14">
{cardData.number}
</p>
<p className="text-white text-lg text-left">
{cardData.date}
</p>
<p className="text-white text-lg text-left">
{cardData.name}
</p>
{hasData && cardData.cvv && (
<p className="text-white text-lg text-right">
{cardData.cvv}
</p>
)}
</div>
)}
</div>
</div>
{cardData && (
<div>
{phase === "FlipCard" && (
<p className=" z-[60] text-white font-bold mt-5 text-[25px]">
Please flip your card
</p>
)}
</div>
)}
<button
className="z-[60] h-[50px] w-[200px] mt-5 bg-[#00FA6C] text-white font-bold"
onClick={() => handleSubmit()}
>
Submit
</button>
</div>
}
</div>
);
};

export default CardComponent;