> ## 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.

# サブスクリプションと継続課金

> 継続決済シナリオ向けに、自動化された高成功率の課金ソリューションを提供します。一度の承認で複数回の自動引き落としを行うメカニズムを通じて、柔軟な課金サイクル設定とスマートリトライをサポートします。

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 PM = {
  VISA: {
    alt: "Visa",
    src: "https://cdn.waffo.com/payment-method/PMI_CC001.png"
  },
  MASTERCARD: {
    alt: "Mastercard",
    src: "https://cdn.waffo.com/payment-method/PMI_CC008.png"
  },
  JCB: {
    alt: "JCB",
    src: "https://cdn.waffo.com/payment-method/PMI_CC068.png"
  },
  UNIONPAY: {
    alt: "UnionPay",
    src: "https://cdn.waffo.com/payment-method/PMI_CC762.png"
  },
  AMEX: {
    alt: "American Express",
    src: "https://cdn.waffo.com/payment-method/PMI_CC015.png"
  },
  BANCONTACT: {
    alt: "Bancontact",
    src: "/images/essentials/one-time-payment/bancontact-logo.svg"
  },
  APPLE_PAY: {
    alt: "Apple Pay",
    src: "https://cdn-dev.waffo.com/payment-method/PMI_155.png"
  },
  GOOGLE_PAY: {
    alt: "Google Pay",
    src: "https://cdn-dev.waffo.com/payment-method/PMI_161.png"
  },
  WECHAT_PAY: {
    alt: "WeChat Pay",
    src: "https://cdn.waffo.com/payment-method/PMI_170.png"
  },
  ALIPAY: {
    alt: "Alipay",
    src: "https://cdn.waffo.com/payment-method/PMI_168.png"
  },
  DANA: {
    alt: "DANA",
    src: "https://cdn.waffo.com/payment-method/PMI_001.png"
  },
  PAYPAY: {
    alt: "PayPay",
    src: "https://cdn.waffo.com/payment-method/PMI_247.png"
  },
  ZALOPAY: {
    alt: "ZaloPay",
    src: "https://cdn.waffo.com/payment-method/PMI_084.png"
  },
  PIX: {
    alt: "PIX",
    src: "https://cdn.waffo.com/payment-method/PMI_040.png"
  },
  BANK_LOCAL_SEPA: {
    alt: "SEPA",
    src: "/images/essentials/one-time-payment/SEPA.png"
  },
  BANK_LOCAL_IDEAL: {
    alt: "iDEAL",
    src: "/images/essentials/one-time-payment/ideal.png"
  },
  BANK_LOCAL_BANCONTACT: {
    alt: "Bancontact",
    src: "/images/essentials/one-time-payment/Bancontact.png"
  },
  BANK_LOCAL_MORE: {
    alt: "More payment methods",
    src: "/images/essentials/one-time-payment/Payment%20logo.png"
  },
  LOCAL_PAYMENT: {
    alt: "Local Payment",
    src: "/images/essentials/one-time-payment/bank-transfer-2.svg"
  }
};

export const CheckoutFeatures = ({scenarioLabel = "Scenario:", scenarioText = ""}) => {
  const [language, setLanguage] = useState("en");
  useEffect(() => {
    const pathname = window.location.pathname;
    if (pathname.startsWith("/zh/")) setLanguage("zh"); else if (pathname.startsWith("/ja/")) setLanguage("ja"); else setLanguage("en");
  }, []);
  const alt = {
    en: {
      checkout: "Hosted checkout: users are redirected to Waffo's secure checkout page to complete the initial signing payment",
      seamless: "Seamless handling for zero-amount authorization and first-period payment logic",
      customization: "Checkout customization: supports brand logo and payment page colors"
    },
    zh: {
      checkout: "托管收银台：用户跳转到 Waffo 安全收银台完成首次签约支付",
      seamless: "无缝处理零金额预授权和首期扣款逻辑",
      customization: "收银台品牌定制：支持品牌 Logo 和页面颜色配置"
    },
    ja: {
      checkout: "ホスト型Checkout: ユーザーはWaffoの安全なCheckoutページで初回契約決済を完了します",
      seamless: "ゼロ金額承認と初回決済ロジックをシームレスに処理します",
      customization: "Checkoutのブランドカスタマイズ: ロゴとページカラーに対応します"
    }
  };
  const copy = alt[language] || alt.en;
  return <div className="not-prose mt-4 flex flex-col gap-3">
      {scenarioText && <p className="mb-1 text-sm leading-6 text-slate-500 dark:text-slate-300">
          <span className="font-semibold text-slate-700 dark:text-slate-100">
            {scenarioLabel}
          </span>{" "}
          {scenarioText}
        </p>}

      <div className="overflow-hidden rounded-2xl border border-slate-200 bg-white shadow-sm dark:border-neutral-700 dark:bg-neutral-900">
        <img src="/docs/images/essentials/subscription-recurring/checkout-integration/panel-checkout.png?v=20260429-1618" alt={copy.checkout} className="my-0 block w-full" />
      </div>

      <div className="grid gap-3 md:grid-cols-2">
        <div className="overflow-hidden rounded-2xl border border-slate-200 bg-white shadow-sm dark:border-neutral-700 dark:bg-neutral-900">
          <img src="/docs/images/essentials/subscription-recurring/checkout-integration/panel-seamless.png?v=20260429-1618" alt={copy.seamless} className="my-0 block w-full" />
        </div>
        <div className="overflow-hidden rounded-2xl border border-slate-200 bg-white shadow-sm dark:border-neutral-700 dark:bg-neutral-900">
          <img src="/docs/images/essentials/subscription-recurring/checkout-integration/panel-customization.png?v=20260429-1618" alt={copy.customization} className="my-0 block w-full" />
        </div>
      </div>
    </div>;
};

export const SubscriptionModelsTable = () => {
  const getCurrentLanguage = () => {
    if (typeof window === "undefined") return "en";
    const pathname = window.location.pathname.replace(/^\/docs(?=\/|$)/, "");
    const firstSegment = pathname.split("/").filter(Boolean)[0];
    const htmlLanguage = document.documentElement.lang?.toLowerCase() || "";
    if (firstSegment === "zh" || htmlLanguage.startsWith("zh")) return "zh";
    if (firstSegment === "ja" || htmlLanguage.startsWith("ja")) return "ja";
    return "en";
  };
  const [isDark, setIsDark] = useState(false);
  const [language, setLanguage] = useState(getCurrentLanguage);
  useEffect(() => {
    const check = () => setIsDark(document.documentElement.classList.contains("dark"));
    check();
    const observer = new MutationObserver(check);
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class"]
    });
    return () => observer.disconnect();
  }, []);
  useEffect(() => {
    setLanguage(getCurrentLanguage());
  }, []);
  const copy = {
    en: {
      mechanism: "Mechanism",
      bestFor: "Best for",
      models: [{
        label: "A",
        name: "Service-First",
        tagline: "Prioritize service continuity; tolerate payment latency.",
        gradientFrom: "rgba(25,87,255,0.12)",
        badgeDarkBg: "#172554",
        badgeDarkBorder: "#1d4ed8",
        mechanism: 'If the current deduction fails, the service is not interrupted. The next deduction is created as planned; "concurrent billing cycles" (accumulated bills) are allowed.',
        bestFor: "Video streaming, SaaS software, and services focused on user retention."
      }, {
        label: "B",
        name: "Payment-First",
        tagline: 'Strictly "pay before service"; zero tolerance for arrears.',
        gradientFrom: "rgba(65,183,163,0.12)",
        badgeDarkBg: "#064e3b",
        badgeDarkBorder: "#047857",
        mechanism: "If the current deduction fails, service is suspended and future billing tasks pause until payment succeeds.",
        bestFor: "Physical subscription boxes, game items, and cost-sensitive businesses."
      }]
    },
    zh: {
      mechanism: "扣款机制",
      bestFor: "适用场景",
      models: [{
        label: "A",
        name: "服务优先型",
        tagline: "优先保障服务连续性；可容忍扣款延迟。",
        gradientFrom: "rgba(25,87,255,0.12)",
        badgeDarkBg: "#172554",
        badgeDarkBorder: "#1d4ed8",
        mechanism: "当期扣款失败时，服务不中断。下期扣款按原计划创建，并允许“多期账单并存”。",
        bestFor: "视频流媒体、SaaS 软件，以及更关注用户留存的服务。"
      }, {
        label: "B",
        name: "支付优先型",
        tagline: "严格遵循“先付款后服务”；零欠费容忍。",
        gradientFrom: "rgba(65,183,163,0.12)",
        badgeDarkBg: "#064e3b",
        badgeDarkBorder: "#047857",
        mechanism: "当前周期扣款失败时立即暂停服务，并停止生成后续扣款任务，直到支付成功。",
        bestFor: "实物订阅盒、游戏道具，以及成本敏感型业务。"
      }]
    },
    ja: {
      mechanism: "仕組み",
      bestFor: "適した用途",
      models: [{
        label: "A",
        name: "サービス優先型",
        tagline: "サービス継続を優先し、決済遅延を許容します。",
        gradientFrom: "rgba(25,87,255,0.12)",
        badgeDarkBg: "#172554",
        badgeDarkBorder: "#1d4ed8",
        mechanism: "当期の引き落としに失敗してもサービスは中断されません。次回の引き落としは予定どおり作成され、複数の請求が並存することを許容します。",
        bestFor: "動画配信、SaaS ソフトウェア、ユーザー維持を重視するサービス。"
      }, {
        label: "B",
        name: "決済優先型",
        tagline: "「支払い後にサービス提供」を厳格に適用し、未払いを許容しません。",
        gradientFrom: "rgba(65,183,163,0.12)",
        badgeDarkBg: "#064e3b",
        badgeDarkBorder: "#047857",
        mechanism: "当期の引き落としに失敗した場合、サービスを停止し、支払いが成功するまで後続の請求タスクも停止します。",
        bestFor: "物理的なサブスクリプションボックス、ゲームアイテム、コスト感度の高い事業。"
      }]
    }
  };
  const content = copy[language] || copy.en;
  return <div className="flex flex-col gap-6 w-full mt-2 md:flex-row">
      {content.models.map(m => <div key={m.label} className="waffo-hover-card subscription-model-card flex-1 flex flex-col rounded-xl border border-slate-200 dark:border-neutral-700 overflow-hidden" style={{
    background: `linear-gradient(to bottom, ${m.gradientFrom} 0%, rgba(255,255,255,0) 100%)`
  }}>
          <div className="flex flex-col gap-3 px-6 pt-6 pb-4">
            <div className="flex items-center gap-2">
              <div className="w-[42px] h-[42px] rounded-full border flex items-center justify-center text-white font-semibold text-base shrink-0" style={{
    backgroundColor: isDark ? m.badgeDarkBg : "#0f172a",
    borderColor: isDark ? m.badgeDarkBorder : "transparent"
  }}>
                {m.label}
              </div>
              <span className="text-slate-900 dark:text-slate-100 font-semibold text-lg">
                {m.name}
              </span>
            </div>
            <p className="text-slate-500 dark:text-slate-300 text-sm leading-5">{m.tagline}</p>
          </div>
          <div className="flex flex-col gap-4 mx-4 mb-6 px-5 py-4 rounded-xl border border-white dark:border-neutral-700 bg-white/80 dark:bg-neutral-900/80">
            <div className="flex flex-col gap-1">
              <p className="text-slate-900 dark:text-slate-100 font-semibold text-sm">{content.mechanism}</p>
              <p className="text-slate-500 dark:text-slate-300 text-sm leading-5">{m.mechanism}</p>
            </div>
            <div className="flex flex-col gap-1">
              <p className="text-slate-900 dark:text-slate-100 font-semibold text-sm">{content.bestFor}</p>
              <p className="text-slate-500 dark:text-slate-300 text-sm leading-5">{m.bestFor}</p>
            </div>
          </div>
        </div>)}
    </div>;
};

## 概要

継続決済シナリオ向けに、自動化された高成功率の課金ソリューションを提供します。「一度の承認、複数回の自動引き落とし」メカニズムを通じて、柔軟な課金サイクル設定とスマートリトライをサポートします。これにより、加盟店はサブスクリプション収益の持続的な成長を達成しながら、ユーザー体験を最適化できます。

<div className="flex gap-4 mt-2 mb-2">
  <a href="/docs/docs/ja/developer-docs/getting-started/overview" className="inline-flex items-center gap-2 px-6 py-2 rounded-lg text-white text-base font-medium no-underline bg-primary hover:opacity-90">
    連携を開始 →
  </a>

  <a href="mailto:support@waffo.com" className="inline-flex items-center px-4 py-2 rounded-lg border border-slate-200 bg-white text-slate-600 text-base font-medium no-underline hover:bg-slate-50 dark:border-neutral-700 dark:bg-neutral-800 dark:text-slate-300 dark:hover:bg-neutral-700">
    セールスに問い合わせる
  </a>
</div>

***

## サブスクリプション決済とは？

**サブスクリプション決済**（自動課金または継続課金とも呼ばれる）は、ユーザーが初回決済時に契約/承認を行い、システムが合意されたサイクル（例: 週次/月次/年次）に基づいて自動的に引き落としを開始する決済モデルです。

「決済アクション」を自動化することで、更新操作のフリクションを大幅に削減し、SaaSサービス、ストリーミングメンバーシップ、コンテンツマネタイズビジネスのコアインフラとして機能します。

## コア機能

<CardGroup cols={2}>
  <Card title="柔軟な課金サイクル" icon="calendar">
    標準（週次、月次、四半期、年次）およびカスタム日数間隔をサポートし、多様なビジネスニーズに対応します。
  </Card>

  <Card title="スマートリトライメカニズム" icon="rotate-right">
    設定可能な再試行戦略（例: 24h/48h間隔）を内蔵し、詳細な失敗コード分析を通じて成功率を最適化します。
  </Card>

  <Card title="フルライフサイクル管理" icon="clock">
    サブスクリプション作成、トライアル期間（無料/割引）、自動引き落とし、アップグレード/ダウングレード、キャンセルまで、完全な管理機能を提供します。
  </Card>

  <Card title="アカウントアップデーター" icon="arrows-rotate">
    VAU/ABUサービスと統合。ユーザーのカードが失効または再発行された際、カード情報を自動的に更新し、サブスクリプションの継続性を維持します。
  </Card>
</CardGroup>

***

## ユースケース

<CardGroup cols={2}>
  <Card title="ストリーミングサービス" icon="circle-play">
    動画・音楽プラットフォームの月次/年次自動更新。
  </Card>

  <Card title="SaaSソフトウェア" icon="desktop">
    オフィスツールや生産性ソフトウェアの定期サブスクリプション課金。
  </Card>

  <Card title="コンテンツマネタイゼーション" icon="book-open">
    ナレッジコラムやオンラインコースのメンバーシップサービス。
  </Card>

  <Card title="ゲームサブスクリプション" icon="gamepad">
    月間パス、シーズンパス、ゲームアイテムの自動更新。
  </Card>
</CardGroup>

***

## サポートされる決済手段

Waffoを通じて、「Credentials on File」と「Merchant Initiated Transactions（MIT）」をサポートする主流の決済手段にアクセスできます。

**銀行カード（クレジット/デビットカード）**

<div className="flex flex-wrap gap-2 p-4 border border-slate-200 dark:border-neutral-700 rounded-xl bg-gradient-to-t from-slate-50 to-white dark:from-neutral-900 dark:to-neutral-800 mb-4">
  <span className="inline-flex items-center justify-center w-[42px] h-7 border border-slate-200 dark:border-neutral-300 rounded bg-white dark:bg-white">
    <img src={PM.JCB.src} alt={PM.JCB.alt} style={{width:"auto", height:"100%", objectFit:"contain"}} />
  </span>

  <span className="inline-flex items-center justify-center w-[42px] h-7 border border-slate-200 dark:border-neutral-300 rounded bg-white dark:bg-white">
    <img src={PM.VISA.src} alt={PM.VISA.alt} style={{width:"auto", height:"100%", objectFit:"contain"}} />
  </span>

  <span className="inline-flex items-center justify-center w-[42px] h-7 border border-slate-200 dark:border-neutral-300 rounded bg-white dark:bg-white">
    <img src={PM.MASTERCARD.src} alt={PM.MASTERCARD.alt} style={{width:"auto", height:"100%", objectFit:"contain"}} />
  </span>
</div>

銀行カードの主要セキュリティ機能：

* **トークナイゼーションセキュリティ** — 初回決済時にトークンが作成されます。以降の引き落としはMIT（Merchant Initiated Transaction）モードを使用し、CVVの再入力は不要です。
* **3DSスマート認証** — 初回契約時に3DS認証を必須とすることで合法的な承認を保証し、以降の自動引き落としは免除してセキュリティと体験のバランスを取ります。
* **自動更新** — VAU（Visa Account Updater）とABU（Automatic Billing Updater）をサポートします。

**デジタルウォレット**

<div className="flex flex-wrap gap-2 p-4 border border-slate-200 dark:border-neutral-700 rounded-xl bg-gradient-to-t from-slate-50 to-white dark:from-neutral-900 dark:to-neutral-800 mb-4">
  <span className="inline-flex items-center justify-center w-[42px] h-7 border border-slate-200 dark:border-neutral-300 rounded bg-white dark:bg-white">
    <img src={PM.APPLE_PAY.src} alt={PM.APPLE_PAY.alt} style={{width:"auto", height:"100%", objectFit:"contain"}} />
  </span>

  <span className="inline-flex items-center justify-center w-[42px] h-7 border border-slate-200 dark:border-neutral-300 rounded bg-white dark:bg-white">
    <img src={PM.GOOGLE_PAY.src} alt={PM.GOOGLE_PAY.alt} style={{width:"auto", height:"100%", objectFit:"contain"}} />
  </span>
</div>

* **ネイティブ体験** — デバイスの生体認証を利用した初回承認で、フリクションのないユーザー体験を提供します。
* **トークン状態の認識** — トークンのステータス変更（例: 更新、停止、復元）に関するリアルタイム通知を受信し、サブスクリプションの継続性を維持します。

**ローカル決済手段**

<div className="flex flex-wrap gap-2 p-4 border border-slate-200 dark:border-neutral-700 rounded-xl bg-gradient-to-t from-slate-50 to-white dark:from-neutral-900 dark:to-neutral-800 mb-4">
  <span className="inline-flex items-center justify-center w-[42px] h-7 border border-slate-200 dark:border-neutral-300 rounded bg-white dark:bg-white">
    <img src={PM.PAYPAY.src} alt={PM.PAYPAY.alt} style={{width:"auto", height:"100%", objectFit:"contain"}} />
  </span>

  <span className="inline-flex items-center justify-center w-[42px] h-7 border border-slate-200 dark:border-neutral-300 rounded bg-white dark:bg-white">
    <img src={PM.PIX.src} alt={PM.PIX.alt} style={{width:"auto", height:"100%", objectFit:"contain"}} />
  </span>

  <span className="inline-flex items-center justify-center w-[42px] h-7 border border-slate-200 dark:border-neutral-300 rounded bg-white dark:bg-white">
    <img src={PM.ZALOPAY.src} alt={PM.ZALOPAY.alt} style={{width:"auto", height:"100%", objectFit:"contain"}} />
  </span>

  <span className="inline-flex items-center justify-center w-[42px] h-7 border border-slate-200 dark:border-neutral-300 rounded bg-white dark:bg-white">
    <img src={PM.DANA.src} alt={PM.DANA.alt} style={{width:"auto", height:"100%", objectFit:"contain"}} />
  </span>
</div>

サブスクリプションのバインディングと自動引き落とし機能をサポートし、ローカルユーザーの習慣に適合します。

[サポートされる決済手段の完全なリストを見る →](/docs/ja/essentials/payment-methods)

***

## サブスクリプションモデルと体験

Waffoサブスクリプション決済は、さまざまな商業戦略に適応する柔軟なビジネスモデル設定を提供します。

### コアビジネスモデル

ダッシュボードまたはAPI経由でサブスクリプションモデルを選択できます。

<SubscriptionModelsTable />

***

## トライアルとプロモーション設定

<div className="bg-slate-50 dark:bg-neutral-900 border-l-4 border-slate-400 dark:border-blue-500 px-6 py-4 mb-3 rounded-r-lg">
  <p className="text-slate-900 dark:text-slate-100 font-medium mb-1 mt-0">無料トライアル</p>
  <p className="text-slate-600 dark:text-slate-300 text-sm my-0">カードの有効性確認後に即時取り消しされる0金額事前オーソリをサポートし、参入障壁を下げます。</p>
</div>

<div className="bg-slate-50 dark:bg-neutral-900 border-l-4 border-slate-400 dark:border-blue-500 px-6 py-4 rounded-r-lg">
  <p className="text-slate-900 dark:text-slate-100 font-medium mb-1 mt-0">割引トライアル</p>
  <p className="text-slate-600 dark:text-slate-300 text-sm my-0">最初のN期間に特別価格を設定でき、その後は自動的に元の価格に戻ります。</p>
</div>

***

## 引き落としと再試行ロジック

システムは課金フローを自動処理し、成功を最大化し、手動介入を最小化します。

**課金フロー**

<Steps>
  <Step title="期日検出">
    システムは課金サイクルの期日を検出し、引き落としタスクを準備します。
  </Step>

  <Step title="MIT注文の生成">
    保存された決済クレデンシャルを使用して、Merchant Initiated Transaction注文が作成されます。
  </Step>

  <Step title="引き落としの開始">
    引き落としが決済ネットワークに送信されて処理されます。
  </Step>

  <Step title="成功通知／失敗時の再試行">
    成功時には確認通知が送信されます。失敗時には再試行戦略が発動します。
  </Step>
</Steps>

<Warning>
  **失敗処理** — デフォルト戦略では失敗後24時間で再試行し、さらに48時間後に再度試行します（パラメータ設定可能）。Eメールによる自動決済失敗通知の発動をサポートし、ユーザーに決済手段の更新を促します。
</Warning>

***

## 連携

ビジネスシステムにサブスクリプション機能をシームレスに組み込むための複数の連携方法を提供します。

### ホスト型Checkout

<CheckoutFeatures scenarioLabel="シナリオ:" scenarioText="開発リソースが限られており、サブスクリプション機能を迅速に立ち上げる必要があるチーム。" />

### API連携

<CardGroup cols={1}>
  <Card title="最適な用途" icon="code">
    深いUIカスタマイズや特定のビジネスロジックを必要とする大企業。
  </Card>
</CardGroup>

サブスクリプション管理のための主要APIは以下のとおりです。

| エンドポイント                            | 説明                        |
| ---------------------------------- | ------------------------- |
| `POST /api/v1/subscription/create` | サブスクリプション注文の作成、契約開始。      |
| `POST /api/v1/subscription/cancel` | サブスクリプションのキャンセル。          |
| `POST /api/v1/subscription/change` | プランのアップグレード/ダウングレードをサポート。 |

`POST /api/v1/subscription/create` を呼び出すときは、すべてのサブスクリプションで `subscriptionManagementUrl` を指定してください。このURLは、認証済みのサブスクリプション管理ページを指す必要があります。

フロントエンドインタラクションフローを完全にコントロール。Webhookを使用して後続のロジックを処理します。

[サブスクリプション決済APIドキュメントを見る →](/docs/api-reference/ja/introduction)

***

## セキュリティとコンプライアンス

Waffoはグローバルな金融データセキュリティ基準に従い、継続課金の安全性を確保します。

<CardGroup cols={3}>
  <Card title="トークン化ストレージ" icon="shield-check">
    ユーザーのカード番号は暗号化して保存されます。すべての継続引き落としはトークンに基づくため、データ漏洩のリスクを削減します。
  </Card>

  <Card title="コンプライアンス準拠の取引タグ付け" icon="badge-check">
    カードスキームの規定に厳密に従い、CIT（Customer Initiated）とMIT（Merchant Initiated）の取引タグを区別し、引き落としがコンプライアンス準拠であり、成功率が期待どおりであることを確保します。
  </Card>

  <Card title="リスクコントロール" icon="shield-exclamation">
    高頻度のトライアル濫用や異常な高額サブスクリプションをリアルタイムで遮断する、内蔵のリスクルール。
  </Card>
</CardGroup>

***

## よくあるご質問

<AccordionGroup>
  <Accordion title="0金額事前オーソリとは何ですか？">
    「無料トライアル」シナリオでは、決済手段の有効性を検証する必要があります。0金額事前オーソリ（Verify）を開始します。特定の銀行がこれをサポートしない場合、システムは自動的に少額（例: 1単位）のオーソリに降格し、即座にボイド/リバーサルして、ユーザーのカードが本物で有効であることを確認します。
  </Accordion>

  <Accordion title="決済失敗の再試行メカニズムはどのように機能しますか？">
    デフォルト戦略では、システムは1回目の失敗後24時間で自動的に再試行し、2回目の失敗後さらに48時間で再試行します。3回目の失敗後、サブスクリプションはフリーズされ、サービスが停止されます。ダッシュボードで最大再試行回数と時間間隔をカスタマイズできます。
  </Accordion>

  <Accordion title="カードの変更（失効、再発行など）はどのように処理されますか？">
    システムはVisa Account UpdaterとMastercard Automatic Billing Updaterを統合しています。ユーザーのカードが失効または再発行/紛失された場合、カードネットワークが新しいカード情報を自動的に当社に同期します。これにより、サブスクリプション課金がカード失効によって中断されることがなく、ユーザーによる手動介入は不要です。
  </Accordion>
</AccordionGroup>

***

ヘルプが必要ですか？[サポートに連絡する](mailto:support@waffo.com)
