> ## Documentation Index
> Fetch the complete documentation index at: https://waffo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 支付凭证化

> 使用 Waffo Tokens 安全存储支付凭证，在无需处理原始卡号的情况下，实现一键结账、周期性扣款与延后扣款。

export const CardGroup = ({children, cols = 2}) => {
  const items = Array.isArray(children) ? children.filter(Boolean) : [children];
  const layoutColumns = items.length === 3 ? 3 : cols === 1 ? 1 : 2;
  return <div className="waffo-guide-cards not-prose my-4 grid gap-4" data-columns={layoutColumns}>
      <style>{`
        .waffo-guide-cards {
          grid-template-columns: minmax(0, 1fr) !important;
        }
        .waffo-guide-cards .waffo-clickable-card {
          transition:
            transform 180ms ease,
            border-color 180ms ease,
            box-shadow 180ms ease,
            background 180ms ease !important;
        }
        html:not(.dark) .waffo-guide-cards .waffo-clickable-card:hover {
          border-color: rgba(109, 145, 245, 0.45) !important;
        }
        html.dark .waffo-guide-cards .waffo-clickable-card:hover,
        .dark .waffo-guide-cards .waffo-clickable-card:hover {
          border-color: rgba(109, 145, 245, 0.45) !important;
        }
        @media (min-width: 768px) {
          .waffo-guide-cards[data-columns="2"],
          .waffo-guide-cards[data-columns="3"] {
            grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
          }
          .waffo-guide-cards[data-columns="3"] .waffo-guide-card:nth-of-type(3) {
            grid-column: 1 / -1 !important;
          }
        }
      `}</style>
      {items}
    </div>;
};

export const Card = ({title, icon, href, children}) => {
  const resolvedHref = (() => {
    if (!href || typeof href !== "string") return href;
    if (!href.startsWith("/") || href.startsWith("//")) return href;
    if (typeof window === "undefined") return href;
    const docsPrefixMatch = window.location.pathname.match(/^\/docs(?=\/|$)/);
    const docsPrefix = docsPrefixMatch ? docsPrefixMatch[0] : "";
    if (!docsPrefix) {
      return href.startsWith("/docs/") ? href.slice(5) : href;
    }
    return href.startsWith(`${docsPrefix}/`) ? href : `${docsPrefix}${href}`;
  })();
  const Wrapper = resolvedHref ? "a" : "div";
  const interactiveClass = resolvedHref ? "waffo-clickable-card" : "";
  return <Wrapper href={resolvedHref} className={`waffo-guide-card waffo-hover-card block rounded-xl border border-slate-200 dark:border-neutral-700 bg-gradient-to-b from-slate-50 to-white dark:from-neutral-900 dark:to-neutral-950 p-6 no-underline ${interactiveClass}`}>
      <div className="flex flex-col items-start gap-3">
        <span className="inline-flex h-10 w-10 items-center justify-center rounded-lg border border-slate-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 text-blue-700 dark:text-[#4D7CFF]">
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
            {icon === "arrow-right" && <path d="M5 12h14M13 5l7 7-7 7" />}
            {icon === "bell" && <path d="M10 21h4M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9" />}
            {icon === "code" && <>
                <path d="m16 18 6-6-6-6" />
                <path d="m8 6-6 6 6 6" />
              </>}
            {icon === "globe" && <>
                <circle cx="12" cy="12" r="10" />
                <path d="M2 12h20" />
                <path d="M12 2a15.3 15.3 0 0 1 0 20" />
                <path d="M12 2a15.3 15.3 0 0 0 0 20" />
              </>}
            {icon === "gear" && <>
                <circle cx="12" cy="12" r="3" />
                <path d="M19.4 15a1.7 1.7 0 0 0 .3 1.9l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.9-.3 1.7 1.7 0 0 0-1 1.6V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1-1.6 1.7 1.7 0 0 0-1.9.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.9 1.7 1.7 0 0 0-1.6-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.6-1 1.7 1.7 0 0 0-.3-1.9l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.9.3H9a1.7 1.7 0 0 0 1-1.6V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.6 1.7 1.7 0 0 0 1.9-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.9v.1a1.7 1.7 0 0 0 1.6 1h.1a2 2 0 1 1 0 4H21a1.7 1.7 0 0 0-1.6 1Z" />
              </>}
            {icon === "shield-check" && <>
                <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10Z" />
                <path d="m9 12 2 2 4-4" />
              </>}
            {icon === "circle-check" && <>
                <circle cx="12" cy="12" r="10" />
                <path d="m9 12 2 2 4-4" />
              </>}
            {icon === "arrow-trend-up" && <path d="m3 17 6-6 4 4 8-8M14 7h7v7" />}
            {icon === "arrows-rotate" && <>
                <path d="M21 12a9 9 0 0 1-15.5 6.2" />
                <path d="M3 12A9 9 0 0 1 18.5 5.8" />
                <path d="M21 3v6h-6" />
                <path d="M3 21v-6h6" />
              </>}
            {icon === "calendar" && <>
                <rect x="3" y="4" width="18" height="17" rx="2" />
                <path d="M16 2v4M8 2v4M3 10h18" />
              </>}
            {icon === "clock" && <>
                <circle cx="12" cy="12" r="10" />
                <path d="M12 6v6l4 2" />
              </>}
            {icon === "desktop" && <>
                <rect x="3" y="4" width="18" height="12" rx="2" />
                <path d="M8 20h8M12 16v4" />
              </>}
            {icon === "calculator" && <>
                <rect x="5" y="2" width="14" height="20" rx="2" />
                <path d="M8 6h8M8 10h.01M12 10h.01M16 10h.01M8 14h.01M12 14h.01M16 14h.01M8 18h.01M12 18h.01M16 18h.01" />
              </>}
            {icon === "plug" && <>
                <path d="M12 22v-5" />
                <path d="M9 8V2" />
                <path d="M15 8V2" />
                <path d="M18 8v5a6 6 0 0 1-12 0V8Z" />
              </>}
            {icon === "gauge" && <>
                <path d="M12 14l4-4" />
                <path d="M3.3 19a10 10 0 1 1 17.4 0" />
              </>}
            {icon === "layer-group" && <>
                <path d="m12 3 9 5-9 5-9-5 9-5Z" />
                <path d="m3 12 9 5 9-5" />
                <path d="m3 16 9 5 9-5" />
              </>}
            {icon === "laptop-mobile" && <>
                <rect x="3" y="4" width="13" height="10" rx="2" />
                <path d="M2 18h12" />
                <rect x="17" y="8" width="5" height="12" rx="1" />
              </>}
            {icon === "paintbrush" && <>
                <path d="m14 5 5 5" />
                <path d="M4 20c2 0 4-1 4-3 0-1.1-.9-2-2-2-2 0-3 2-3 4 0 .6.4 1 1 1Z" />
                <path d="m6 15 9-9a2.1 2.1 0 0 1 3 3l-9 9" />
              </>}
            {icon === "key" && <>
                <circle cx="7.5" cy="14.5" r="4.5" />
                <path d="m11 11 8-8" />
                <path d="m15 7 2 2" />
              </>}
            {icon === "circle-minus" && <>
                <circle cx="12" cy="12" r="10" />
                <path d="M8 12h8" />
              </>}
            {icon === "wallet" && <>
                <path d="M3 7h15a3 3 0 0 1 3 3v8a3 3 0 0 1-3 3H3Z" />
                <path d="M3 7V5a2 2 0 0 1 2-2h11" />
                <path d="M16 14h.01" />
              </>}
            {icon === "users" && <>
                <path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" />
                <circle cx="9" cy="7" r="4" />
                <path d="M22 21v-2a4 4 0 0 0-3-3.9" />
                <path d="M16 3.1a4 4 0 0 1 0 7.8" />
              </>}
            {icon === "link" && <>
                <path d="M10 13a5 5 0 0 0 7.1 0l2-2a5 5 0 0 0-7.1-7.1l-1.1 1.1" />
                <path d="M14 11a5 5 0 0 0-7.1 0l-2 2a5 5 0 0 0 7.1 7.1l1.1-1.1" />
              </>}
            {icon === "eye" && <>
                <path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12Z" />
                <circle cx="12" cy="12" r="3" />
              </>}
            {icon === "file-lines" && <>
                <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z" />
                <path d="M14 2v6h6" />
                <path d="M8 13h8M8 17h6" />
              </>}
            {icon === "sliders" && <>
                <path d="M4 21v-7M4 10V3M12 21v-9M12 8V3M20 21v-5M20 12V3" />
                <path d="M2 14h4M10 8h4M18 16h4" />
              </>}
            {icon === "folder" && <path d="M3 6a2 2 0 0 1 2-2h5l2 2h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z" />}
            {icon === "dollar-sign" && <>
                <path d="M12 2v20" />
                <path d="M17 5H9.5a3.5 3.5 0 0 0 0 7H14a3.5 3.5 0 0 1 0 7H6" />
              </>}
            {icon === "toggle-on" && <>
                <rect x="2" y="7" width="20" height="10" rx="5" />
                <circle cx="16" cy="12" r="3" />
              </>}
            {icon === "infinity" && <path d="M18.2 8.2c2.1 0 3.8 1.7 3.8 3.8s-1.7 3.8-3.8 3.8c-4.2 0-8.2-7.6-12.4-7.6C3.7 8.2 2 9.9 2 12s1.7 3.8 3.8 3.8c4.2 0 8.2-7.6 12.4-7.6Z" />}
            {icon === "book-open" && <>
                <path d="M2 4h7a3 3 0 0 1 3 3v14a3 3 0 0 0-3-3H2Z" />
                <path d="M22 4h-7a3 3 0 0 0-3 3v14a3 3 0 0 1 3-3h7Z" />
              </>}
            {icon === "circle-play" && <>
                <circle cx="12" cy="12" r="10" />
                <path d="m10 8 6 4-6 4Z" />
              </>}
            {icon === "gamepad" && <>
                <rect x="3" y="8" width="18" height="10" rx="5" />
                <path d="M8 13h3M9.5 11.5v3M16 13h.01M18 11h.01" />
              </>}
            {icon === "rocket" && <>
                <path d="M4.5 16.5c-1.5 1.3-2 3.5-2 5 1.5 0 3.7-.5 5-2" />
                <path d="M9 15 4 10l6-6c4-4 9-2 10-1 1 1 3 6-1 10l-6 6-5-5Z" />
                <path d="M15 9h.01" />
              </>}
            {(icon === "flask" || icon === "flask-vial") && <>
                <path d="M9 2v6L4 20a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2L15 8V2" />
                <path d="M8 2h8" />
                <path d="M7 16h10" />
              </>}
            {icon === "credit-card" && <>
                <rect x="3" y="5" width="18" height="14" rx="2" />
                <path d="M3 10h18" />
                <path d="M7 15h4" />
              </>}
            {icon === "puzzle-piece" && <path d="M14 7V4a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v3H3a1 1 0 0 0-1 1v4a2 2 0 0 0 2 2h2v3a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2v-3h3a2 2 0 0 0 2-2V8a1 1 0 0 0-1-1Z" />}
            {(icon === "arrows-spin" || icon === "repeat") && <>
                <path d="M17 2l4 4-4 4" />
                <path d="M3 11V9a4 4 0 0 1 4-4h14" />
                <path d="M7 22l-4-4 4-4" />
                <path d="M21 13v2a4 4 0 0 1-4 4H3" />
              </>}
            {icon === "coins" && <>
                <ellipse cx="8" cy="7" rx="5" ry="3" />
                <path d="M3 7v6c0 1.7 2.2 3 5 3s5-1.3 5-3V7" />
                <path d="M13 10c2.8 0 5 1.3 5 3v4c0 1.7-2.2 3-5 3-1.2 0-2.3-.2-3.1-.7" />
              </>}
            {icon === "triangle-exclamation" && <>
                <path d="m21.7 18-8-14a2 2 0 0 0-3.4 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.7-3Z" />
                <path d="M12 9v4M12 17h.01" />
              </>}
            {icon === "list" && <>
                <path d="M8 6h13M8 12h13M8 18h13" />
                <path d="M3 6h.01M3 12h.01M3 18h.01" />
              </>}
            {icon === "star" && <path d="m12 2 3.1 6.3 6.9 1-5 4.9 1.2 6.8-6.2-3.3L5.8 21 7 14.2 2 9.3l6.9-1Z" />}
            {(icon === "rotate" || icon === "arrow-rotate-left") && <>
                <path d="M3 12a9 9 0 1 0 3-6.7" />
                <path d="M3 4v6h6" />
              </>}
            {icon === "clock-rotate-left" && <>
                <path d="M3 12a9 9 0 1 0 3-6.7" />
                <path d="M3 4v6h6" />
                <path d="M12 7v5l3 2" />
              </>}
            {icon === "circle-xmark" && <>
                <circle cx="12" cy="12" r="10" />
                <path d="m15 9-6 6M9 9l6 6" />
              </>}
            {icon === "paper-plane" && <path d="m22 2-7 20-4-9-9-4Z" />}
            {icon === "signal" && <>
                <path d="M2 20h.01M7 20v-4M12 20v-8M17 20V8M22 20V4" />
              </>}
            {icon === "circle-question" && <>
                <circle cx="12" cy="12" r="10" />
                <path d="M9.1 9a3 3 0 1 1 5.8 1c0 2-3 2-3 4" />
                <path d="M12 17h.01" />
              </>}
            {icon === "palette" && <>
                <path d="M12 22a10 10 0 1 1 7.5-3.4c-.9 1-2.4.4-2.4-.9 0-1.1-.9-2-2-2h-1.4c-1.2 0-2.2 1-2.2 2.2 0 1.1.9 2.1 2.1 2.1" />
                <circle cx="7.5" cy="10.5" r=".8" />
                <circle cx="12" cy="7.5" r=".8" />
                <circle cx="16.5" cy="10.5" r=".8" />
              </>}
            {(!icon || !["arrow-right", "bell", "code", "globe", "gear", "shield-check", "circle-check", "arrow-trend-up", "arrows-rotate", "calendar", "clock", "desktop", "calculator", "plug", "gauge", "layer-group", "laptop-mobile", "paintbrush", "key", "circle-minus", "wallet", "users", "link", "eye", "file-lines", "sliders", "folder", "dollar-sign", "toggle-on", "infinity", "book-open", "circle-play", "gamepad", "rocket", "flask", "flask-vial", "credit-card", "puzzle-piece", "arrows-spin", "repeat", "coins", "triangle-exclamation", "list", "star", "rotate", "arrow-rotate-left", "clock-rotate-left", "circle-xmark", "paper-plane", "signal", "circle-question", "palette"].includes(icon)) && <path d="M13 2 4 14h7l-1 8 9-12h-7l1-8Z" />}
          </svg>
        </span>
        <div className="flex flex-col gap-2">
          <h4 className="m-0 text-base font-semibold text-slate-900 dark:text-slate-100">
            {title}
          </h4>
          <div className="m-0 text-sm leading-6 text-slate-600 dark:text-slate-300">
            {children}
          </div>
        </div>
      </div>
    </Wrapper>;
};

export const TokenizationUseCases = ({cases = []}) => {
  const icons = [<path key="bolt" d="M13 2 4 14h7l-1 8 9-12h-7l1-8Z" />, <path key="rotate" d="M21 12a9 9 0 1 1-3-6.7M21 4v6h-6" />, <path key="clock" d="M12 8v5l3 2M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Z" />];
  return <div className="not-prose my-5 grid grid-cols-1 gap-4 md:grid-cols-2">
      {cases.map((item, index) => <div key={item.title} className={`waffo-hover-card rounded-xl border border-slate-200 dark:border-neutral-700 bg-gradient-to-b from-slate-50 to-white dark:from-neutral-900 dark:to-neutral-950 p-5 ${index === 2 ? "md:col-span-2" : ""}`}>
          <div className="mb-4 flex h-10 w-10 items-center justify-center rounded-lg border border-slate-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 text-blue-700 dark:text-[#4D7CFF]">
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              {icons[index] || icons[0]}
            </svg>
          </div>
          <h3 className="m-0 text-base font-semibold text-slate-900 dark:text-slate-100">
            {item.title}
          </h3>
          <p className="mt-3 mb-0 text-sm font-medium text-slate-700 dark:text-slate-200">
            {item.scenario}
          </p>
          <p className="mt-3 mb-0 text-sm leading-6 text-slate-600 dark:text-slate-300">
            {item.description}
          </p>
        </div>)}
    </div>;
};

export const TokenizationCoreValueCards = ({items = []}) => {
  const iconSrc = "/images/essentials/tokenization/check-icon.svg";
  return <div className="tokenization-core-value-cards not-prose my-4 grid grid-cols-1 gap-4 md:grid-cols-2">
      <style>{`
        .tokenization-core-value-cards .tokenization-core-value-card {
          padding: 24px !important;
          box-sizing: border-box;
        }
        @media (min-width: 768px) {
          .tokenization-core-value-cards .tokenization-core-value-card:nth-of-type(3) {
            grid-column: 1 / -1 !important;
          }
        }
        .tokenization-core-value-cards .tokenization-check-icon {
          background-color: #071f66;
        }
        .dark .tokenization-core-value-cards .tokenization-check-icon {
          background-color: #4D7CFF;
        }
      `}</style>
      {items.map(item => <div key={item.title} className="tokenization-core-value-card waffo-hover-card rounded-xl border border-slate-200 dark:border-neutral-700 bg-gradient-to-b from-slate-50 to-white dark:from-neutral-900 dark:to-neutral-950">
          <div className="flex flex-col items-start gap-3">
            <span className="tokenization-check-icon inline-flex h-6 w-6 shrink-0" aria-hidden="true" style={{
    WebkitMask: `url("${iconSrc}") center / contain no-repeat`,
    mask: `url("${iconSrc}") center / contain no-repeat`
  }} />
            <div className="flex flex-col gap-2">
              <h4 className="m-0 text-base font-semibold text-slate-900 dark:text-slate-100">
                {item.title}
              </h4>
              <p className="m-0 text-sm leading-6 text-slate-600 dark:text-slate-300">
                {item.description}
              </p>
            </div>
          </div>
        </div>)}
    </div>;
};

export const TokenizationIntegrationMigration = ({methods = [], migrationTitle, migrationDescription, migrationItems = [], apiLabel, apiHref = "/docs/api-reference/introduction"}) => {
  const methodIcons = ["object", "code"];
  return <div className="not-prose my-5 flex flex-col gap-4">
      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
        {methods.map((method, index) => <div key={method.title} className="waffo-hover-card relative overflow-hidden rounded-xl border border-slate-200 dark:border-neutral-700 bg-gradient-to-b from-slate-50 to-white dark:from-neutral-900 dark:to-neutral-950 p-5">
            <div className="absolute right-0 top-0 h-28 w-28 rounded-full bg-blue-100/70 dark:bg-blue-950/40 blur-2xl" />
            <div className="relative flex flex-col gap-4">
              <div className="flex items-center gap-3">
                <div className="flex h-10 w-10 items-center justify-center rounded-lg border border-slate-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 text-blue-700 dark:text-[#4D7CFF]">
                  {methodIcons[index] === "code" ? <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                      <path d="m16 18 6-6-6-6" />
                      <path d="m8 6-6 6 6 6" />
                    </svg> : <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                      <rect x="3" y="3" width="7" height="7" rx="1.5" />
                      <rect x="14" y="3" width="7" height="7" rx="1.5" />
                      <rect x="3" y="14" width="7" height="7" rx="1.5" />
                      <path d="M14 17.5h7" />
                      <path d="M17.5 14v7" />
                    </svg>}
                </div>
                <h3 className="m-0 text-base font-semibold text-slate-900 dark:text-slate-100">
                  {method.title}
                </h3>
              </div>
              <p className="m-0 text-sm leading-6 text-slate-600 dark:text-slate-300">
                {method.description}
              </p>
              {method.imageSrc && <div className="mt-1 overflow-hidden rounded-lg border border-slate-200 dark:border-neutral-700 bg-white dark:bg-neutral-900">
                  <img src={method.imageSrc} alt={method.imageAlt || method.title} className="m-0 block h-auto w-full" />
                </div>}
            </div>
          </div>)}
      </div>

      <div className="rounded-xl border border-slate-200 dark:border-neutral-700 bg-white dark:bg-neutral-950 overflow-hidden">
        <div className="border-b border-slate-200 dark:border-neutral-800 bg-slate-50 dark:bg-neutral-900 px-5 py-4">
          <h3 className="m-0 text-base font-semibold text-slate-900 dark:text-slate-100">
            {migrationTitle}
          </h3>
          <p className="mt-2 mb-0 text-sm leading-6 text-slate-600 dark:text-slate-300">
            {migrationDescription}
          </p>
        </div>

        <div className="grid grid-cols-1 md:grid-cols-2 divide-y md:divide-y-0 md:divide-x divide-slate-200 dark:divide-neutral-800">
          {migrationItems.map(item => <div key={item.title} className="p-5">
              <div className="mb-3 flex items-center gap-2">
                <span className="flex h-6 w-6 items-center justify-center rounded-full bg-blue-50 dark:bg-blue-950/60 text-blue-700 dark:text-[#4D7CFF]">
                  <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                    <path d={item.type === "export" ? "M12 3v13" : "M12 21V8"} />
                    <path d={item.type === "export" ? "m7 8 5-5 5 5" : "m7 16 5 5 5-5"} />
                    <path d="M5 21h14" />
                  </svg>
                </span>
                <h4 className="m-0 text-sm font-semibold text-slate-900 dark:text-slate-100">
                  {item.title}
                </h4>
              </div>
              <p className="m-0 text-sm leading-6 text-slate-600 dark:text-slate-300">
                {item.description}
              </p>
            </div>)}
        </div>
      </div>

      <a href={apiHref} className="inline-flex self-start items-center gap-2 rounded-lg border border-slate-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 px-4 py-2 text-sm font-medium text-blue-700 dark:text-[#4D7CFF] no-underline hover:bg-slate-50 dark:hover:bg-neutral-800">
        {apiLabel}
        <span aria-hidden="true">→</span>
      </a>
    </div>;
};

支付凭证化技术使商户能够在不接触原始卡号的情况下，安全地存储用户的支付信息。它将敏感的银行卡数据替换为一个非敏感的随机字符串——**Waffo Token**。

Waffo 提供标准化的支付凭证化解决方案。商户通过对接统一的 Token 接口，即可在无需管理复杂的卡组织规则或安全加密细节的情况下，实现\*\*“一键支付”**与**“周期性扣款”\*\*。

## 核心价值

<TokenizationCoreValueCards
  items={[
{
  title: "极致支付体验",
  description: "用户只需输入一次卡信息。后续购买无需重复输入，大幅降低结账摩擦。",
},
{
  title: "降低合规成本",
  description:
    "敏感数据托管在 Waffo 通过 PCI-DSS Level 1 认证的金库中。商户系统无需处理明文卡号，显著缩小合规审计范围。",
},
{
  title: "跨渠道通用",
  description:
    "生成的 Token 可在你的所有渠道中使用——App、Web、移动 Web 等——用于构建统一的用户支付账户体系。",
},
]}
/>

## 为什么选择 Waffo Tokenization

我们的 Token 不只是一个简单的存储型凭证。它集成了 Waffo 的智能支付引擎，可持续优化你的交易表现。

### 智能优化

Waffo 在基础设施层采用多项行业领先的优化技术。当你使用 Waffo Token 发起扣款时，智能引擎会基于发卡行偏好、交易类型和风险特征，自动选择最优的 ISO 报文格式与路由策略。

<CardGroup cols={2}>
  <Card title="效果" icon="arrow-trend-up">
    通过 Waffo Token 发起的交易，相比传统的明文卡支付，可获得更高的授权通过率。
  </Card>

  <Card title="无缝" icon="circle-check">
    所有优化都会在毫秒级自动完成，无需你进行任何额外配置。
  </Card>
</CardGroup>

### 账户更新器

Waffo 与主要卡组织网络深度集成，支持自动化的卡生命周期管理。

<CardGroup cols={2}>
  <Card title="自动续期" icon="arrows-rotate">
    当用户的实体卡到期、挂失或补换卡，或卡号发生变更时，系统会自动获取最新的卡信息。
  </Card>

  <Card title="业务零中断" icon="infinity">
    Waffo 会在后台静默更新映射关系。你的 **Waffo Token 字符串保持不变**，但它现在指向新卡——确保订阅扣款不会因换卡而失败。
  </Card>
</CardGroup>

## 用例

<TokenizationUseCases
  cases={[
{
title: "一键结账",
scenario: "场景：回访用户在该商户再次购物。",
description: "用户在结账页直接看到“使用尾号 8888 的 Visa 支付”。他们点击按钮即可完成订单，无需掏出钱包或再次输入卡信息。"
},
{
title: "周期扣款与订阅",
scenario: "场景：每月 SaaS 软件付费、视频会员续费。",
description: "通过 Token 建立周期性计费计划。商户定期发起 MIT（商户发起交易）指令，实现静默扣款。"
},
{
title: "预订与延迟扣款",
scenario: "场景：酒店预订、共享服务押金。",
description: "用户在预订时授权 Token，也可与预授权结合冻结资金。商户在入住或服务完成后，根据实际消费金额通过 Token 发起扣款。"
}
]}
/>

## 生命周期管理流程

<Steps>
  <Step title="创建 Token">
    * **用户侧：** 用户在结账时勾选“保存此卡以便日后使用”。
    * **系统侧：** Waffo 校验卡片数据，执行多层加密，并向商户返回 Token ID。
  </Step>

  <Step title="验证并扣款">
    * **验证：** 在绑定时执行 Zero-Auth（0 金额）或 1 美元预授权，以确认卡片处于有效状态且可扣款。
    * **扣款：** 发起支付时，你的后端直接发送 Token ID —— 无需卡号。
  </Step>

  <Step title="管理与展示">
    * 通过 API 获取指定用户已绑定的全部 Token 列表。
    * API 返回脱敏信息（卡品牌、后四位、到期日、卡面背景色），用于前端展示与用户选择。
  </Step>
</Steps>

## 集成与迁移

### 集成方式

<TokenizationIntegrationMigration
  methods={[
{
  title: "UI 组件集成",
  description: "使用 Waffo Elements。组件会在内部自动处理卡号采集与 Token 化，你的前端代码永远不会接触明文卡号。",
  imageSrc: "/images/essentials/tokenization/UI%20Component%20Integration.png?v=20260429-1822",
  imageAlt: "UI 组件集成流程"
},
{
  title: "API 集成",
  description: "适用于 PCI 认证商户，支持通过服务端 API 直接创建 Token，同时将敏感数据保留在合规环境内。",
  imageSrc: "/images/essentials/tokenization/API%20Integration.png?v=20260429-1822",
  imageAlt: "API 集成流程"
}
]}
  migrationTitle="数据迁移"
  migrationDescription="Waffo 支持灵活的数据迁移方案，以消除供应商锁定顾虑。"
  migrationItems={[
{
  type: "import",
  title: "导入",
  description: "将你在其他平台的现有 Token 数据平滑迁移至 Waffo。回流用户无需重新绑卡。"
},
{
  type: "export",
  title: "导出",
  description: "如果你停止使用服务，Waffo 将依据 PCI 标准，安全地将加密卡数据传输给新的合格接收方。"
}
]}
  apiLabel="查看 API 文档"
  apiHref="/api-reference/zh/introduction"
/>

## 常见问题

<AccordionGroup>
  <Accordion title="保存信用卡信息安全吗？">
    非常安全。Waffo 持有最高级别的安全认证——PCI-DSS Level 1（金融级安全标准）。实际卡号数据经过加密，存储在物理隔离的保险库中。商户的系统和数据库仅存储无实际意义的 Token 字符串。即使商户的数据库遭到攻击，黑客也无法还原真实的银行卡信息。
  </Accordion>

  <Accordion title="Token 会过期吗？">
    Waffo Token 本身永久有效，除非您主动调用 API 将其删除。即使底层实体卡到期，依托我们的账户更新器（Account Updater）功能，系统在大多数情况下会自动维护映射关系，无需您或用户手动干预。
  </Accordion>

  <Accordion title="如何验证已绑定的卡是否有效？">
    建议在创建 Token 的同时执行 Zero Amount Verify（零金额验证）。这可以确保 Token 对应的卡片在绑定时是真实有效的、未被挂失，且具备扣款能力。
  </Accordion>

  <Accordion title="我可以将 Token 分享给我的子商户吗？">
    这取决于您的账户架构。如果您是平台型商户，可以通过"Token 克隆（Token Cloning）"将支付凭证授权给子商户，从而实现统一的钱包体验。
  </Accordion>
</AccordionGroup>

***

需要帮助？[联系支持](mailto:support@waffo.com)
