**Last updated**: 24 June 2025 | [**Change log**](/products/checkout/web/changelog/) # React integration Integrate the Access Checkout Web SDK in a React application. ## Integration 1. You must add the SDK `checkout.js` script to your app html code and make sure this is done **only once**. To do this, you may want to add it in your main application or add it dynamically as part of one of your components. 2. Before initializing the SDK, you must load the `checkout.js` script successfully. The reason is that this script creates an object on the `window` object which is required by the initialization mechanism. 3. You must call the SDK's `remove()` method **only once** as part of your component unmounting phase but when the DOM is still available. You can do this by using the `useLayoutEffect` hook and by calling the `remove()` method in the cleanup function run by the hook. ### Full integration example JavaScript import React, {useEffect, useLayoutEffect} from "react"; import "./CheckoutIntegrationSample.css"; function scriptAlreadyLoaded(src) { return document.querySelector(`script[src="${src}"]`); } function loadCheckoutScript(src) { return new Promise((resolve, reject) => { if (scriptAlreadyLoaded(src)) { resolve(); return; } let checkoutScript = document.createElement("script"); checkoutScript.src = src; checkoutScript.onload = resolve; checkoutScript.onerror = reject; document.head.appendChild(checkoutScript); }); } function addWorldpayCheckoutToPage() { return new Promise((resolve, reject) => { (function () { window.Worldpay.checkout.init( { id: "your-checkout-id", form: "#container", fields: { pan: { selector: "#card-pan", }, expiry: { selector: "#card-expiry", }, cvv: { selector: "#card-cvv", }, }, styles: { "input.is-valid": { "color": "green", }, "input.is-invalid": { "color": "red", }, "input.is-onfocus": { "color": "black", }, }, enablePanFormatting: true, }, function (error, checkout) { if (error) { reject(error); } else { resolve(checkout); } }, ); })(); }); } function CheckoutIntegrationSample() { const checkoutScriptUrl = "https://try.access.worldpay-bsh.securedataplatform.com/access-checkout/v2/checkout.js"; let checkout; function generateSession () { checkout.generateSessionState( function (error, session) { if (error) { console.warn(`Failed to generate session: ${error}`); return; } const infoDiv = document.querySelector(".info"); infoDiv.innerHTML += `
Session retrieved is ${session}
`; }); } function clearForm () { checkout.clearForm(() => { document.querySelector(".info").innerHTML = ""; }); } useEffect(() => { loadCheckoutScript(checkoutScriptUrl) .then(() => { addWorldpayCheckoutToPage() .then((checkoutInstance) => { checkout = checkoutInstance; }) .catch(console.warn); }) .catch(console.warn); }, []); useLayoutEffect(() => { // Make sure to call the remove method (once) in order to deallocate the SDK from memory return () => checkout.remove(); }, []); return (
); } export default CheckoutIntegrationSample; CSS .container { display: flex; align-items: center; flex-direction: column; } .card { background: white; padding: 20px 30px; top: -30px; width: 100%; max-width: 300px; border-radius: 12px; box-shadow: 3px 3px 60px 0px rgba(0, 0, 0, 0.1); } .columns { display: flex; } .columns > * { margin-right: 15px; } .field { height: 40px; border-bottom: 1px solid lightgray; } .field.is-onfocus { border-color: black; } .field.is-empty { border-color: orange; } .field.is-invalid { border-color: red; } .field.is-valid { border-color: green; } #card-pan { margin-bottom: 30px; } .submit { background: green; cursor: pointer; width: 200px; margin-top:30px; color: white; outline: 0; font-size: 14px; border: 0; border-radius: 30px; text-transform: uppercase; font-weight: bold; padding: 15px 0; transition: background 0.3s ease; margin-right:20px; } .clear { background: green; cursor: pointer; width: 100px; margin-top:30px; color: white; outline: 0; font-size: 14px; border: 0; border-radius: 30px; text-transform: uppercase; font-weight: bold; padding: 15px 0; transition: background 0.3s ease; } .buttons { display: flex; } .info { width: 600px; word-wrap:break-word; margin-top: 20px; color: green; }