Translation disclaimer

Documentation is written in English and subsequently translated. This page, therefore, might not have the most up-to-date content. If any questions arise relating to the accuracy of the translated content, please refer to the English version of the page.

Menu

React 集成


在 React 应用程序中集成 Access Checkout Web SDK。

集成

  1. 您必须将 SDK checkout.js 脚本添加到应用程序 html 代码中,并确保仅执行一次。 为此,您要将脚本添加到主应用程序中,或作为其中一个组件的一部分,动态添加。

  2. 在初始化 SDK 之前,您必须成功加载 checkout.js 脚本。 因为该脚本在 window 对象上创建了一个初始化机制所必需的对象。

  3. 在组件卸载阶段,且在 DOM 仍然可用的情况下,您只能调用一次 SDK 的 remove() 方法。 通过使用 useLayoutEffect 钩子和调用由此钩子运行的 cleanup 函数中的 remove() 方法,可执行此操作。

完整集成示例

Copied!
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: "identity",
          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.com/access-checkout/v1/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 += `<div>Session retrieved is ${session}</div>`;
      });
  }

  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 (
    <section className="container" id="container">
      <section className="card">
        <section id="card-pan" className="field" />
        <section className="columns">
        <section>
        <section id="card-expiry" className="field" />
        </section>
        <section>
        <section id="card-cvv" className="field" />
        </section>
        </section>
        <section className="buttons">
          <button className="submit" type="button" onClick={generateSession}>
            Generate Session
          </button>
          <button className="clear" type="button" onClick={clearForm}>
            Clear
          </button>
        </section>
      </section>
      <div id="info" className="info" />
    </section>
  );
}

export default CheckoutIntegrationSample;
.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;
}