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

# Accept Payments with Stripe Checkout

> Build a checkout page with Payment Intents API

export const DownloadAndOpenButtons = ({downloadUrl, mainAppUrl = "https://sampleapp.ai", className = "", gitUrl}) => {
  const [hasCopied, setHasCopied] = React.useState(false);
  const [showCommand, setShowCommand] = React.useState(false);
  const npxCommand = React.useMemo(() => {
    let apiPath = downloadUrl;
    if (apiPath.startsWith("http://") || apiPath.startsWith("https://")) {
      try {
        const url = new URL(apiPath);
        apiPath = url.pathname;
      } catch (e) {
        console.error("Invalid URL:", apiPath);
      }
    }
    if (apiPath.startsWith("/public/")) {
      apiPath = apiPath.slice(("/public/").length);
    }
    if (apiPath.startsWith("/")) {
      apiPath = apiPath.slice(1);
    }
    if (apiPath.endsWith(".zip")) {
      apiPath = apiPath.slice(0, -4);
    }
    return `npx sampleappai add "${mainAppUrl}/api/code/static/${apiPath}"`;
  }, [downloadUrl, mainAppUrl]);
  const handleDownload = () => {
    window.open(downloadUrl, "_blank");
  };
  const handleCopyCommand = async () => {
    try {
      await navigator.clipboard.writeText(npxCommand);
      setHasCopied(true);
      setTimeout(() => setHasCopied(false), 2000);
    } catch (err) {
      const textArea = document.createElement("textarea");
      textArea.value = npxCommand;
      document.body.appendChild(textArea);
      textArea.select();
      try {
        document.execCommand("copy");
        setHasCopied(true);
        setTimeout(() => setHasCopied(false), 2000);
      } catch (err) {
        console.error("Failed to copy:", err);
      }
      document.body.removeChild(textArea);
    }
  };
  const handleOpenVSCode = () => {
    try {
      window.location.href = `vscode://vscode.git/clone?url=${gitUrl}`;
    } catch {}
  };
  return <div className={`flex flex-col gap-3 ${className}`}>
      <div className="flex items-center gap-2">
        {}
        <button type="button" className="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md text-white transition-all hover:opacity-90 active:scale-[0.98] bg-primary dark:bg-primary-light" onClick={handleDownload}>
          <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
          </svg>
          Download example
        </button>

        {}
        <button type="button" className="inline-flex items-center h-8 gap-1.5 px-3 py-0.5 text-xs font-medium rounded-md border transition-all hover:bg-zinc-100 dark:hover:bg-zinc-800 active:scale-[0.98] bg-white dark:bg-zinc-900 border-zinc-300 dark:border-zinc-700 text-zinc-900 dark:text-zinc-100" onClick={() => handleOpenVSCode()}>
          <img src="/assets/vscode.png" alt="VS Code" className="w-3.5 h-3.5" />
          Integrate in VS Code
        </button>
      </div>

      {}
      {showCommand && <div className="p-4 border border-zinc-300 dark:border-zinc-700 rounded-lg bg-zinc-50 dark:bg-zinc-900/50">
          <div className="flex flex-col gap-3">
            {}
            <div className="flex flex-col gap-2">
              <div className="flex items-center gap-2">
                <div className="flex-shrink-0 w-5 h-5 rounded-full flex items-center justify-center text-[10px] font-bold text-white" style={{
    backgroundColor: themeColor
  }}>
                  1
                </div>
                <p className="text-sm font-medium text-zinc-900 dark:text-zinc-100">
                  Copy this command
                </p>
              </div>
              <div className="flex items-center gap-2 overflow-hidden">
                <code className="flex-1 bg-white dark:bg-zinc-800 px-3 py-2.5 rounded-md text-xs font-mono truncate block max-w-[calc(100%-3rem)] border border-zinc-200 dark:border-zinc-700 text-zinc-900 dark:text-zinc-100">
                  {npxCommand}
                </code>
                <button type="button" onClick={handleCopyCommand} className="flex-shrink-0 p-2 rounded-md hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors border border-zinc-300 dark:border-zinc-600" title="Copy command">
                  {hasCopied ? <svg className="w-4 h-4 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
                    </svg> : <svg className="w-4 h-4 text-zinc-600 dark:text-zinc-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
                    </svg>}
                </button>
              </div>
            </div>

            {}
            <div className="flex flex-col gap-2">
              <div className="flex items-center gap-2">
                <div className="flex-shrink-0 w-5 h-5 rounded-full flex items-center justify-center text-[10px] font-bold text-white" style={{
    backgroundColor: themeColor
  }}>
                  2
                </div>
                <p className="text-sm font-medium text-zinc-900 dark:text-zinc-100">
                  Open VSCode and paste in terminal
                </p>
              </div>
              <button type="button" onClick={handleOpenVSCode} className="w-full inline-flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-md text-white transition-all hover:opacity-90 active:scale-[0.99]" style={{
    backgroundColor: themeColor
  }}>
                <svg className="w-4 h-4" width="20" height="20" viewBox="0 0 20 20" fill="none">
                  <path d="M13.3333 0L5 3.33333V16.6667L13.3333 20V0Z" fill="currentColor" />
                  <path d="M13.3333 0L18.3333 3.75V16.25L13.3333 20V0Z" fill="currentColor" opacity="0.8" />
                </svg>
                Open VSCode
              </button>
            </div>
          </div>
        </div>}
    </div>;
};

export const FrameworkGuide = ({framework, label, children}) => {
  return children;
};

export const Architecture = ({value, label, children}) => {
  return children;
};

export const iframeState = {
  listeners: [],
  params: {},
  subscribe: fn => {
    iframeState.listeners.push(fn);
    return () => {
      iframeState.listeners = iframeState.listeners.filter(l => l !== fn);
    };
  },
  setParams: params => {
    iframeState.params = params;
    iframeState.listeners.forEach(fn => fn(params));
  }
};

export const CodeFocusSection = ({docs = "mintlify", themeColor, linesStart, linesEnd, activeFilePath, title, description, children}) => {
  const sectionRef = React.useRef(null);
  const hasTriggeredRef = React.useRef(false);
  const [isActive, setIsActive] = React.useState(false);
  const useProse = docs === "mintlify";
  const getParams = React.useCallback(() => {
    const params = {};
    if (docs) params.docs = docs;
    if (docs === "custom" && themeColor) params.theme = themeColor;
    if (linesStart !== undefined) params.linesStart = linesStart;
    if (linesEnd !== undefined) params.linesEnd = linesEnd;
    if (activeFilePath) params.activeFilePath = activeFilePath;
    return params;
  }, [docs, themeColor, linesStart, linesEnd, activeFilePath]);
  const handleFocus = React.useCallback(() => {
    iframeState.setParams(getParams());
    setIsActive(true);
  }, [getParams]);
  React.useEffect(() => {
    const checkActive = params => {
      const myParams = getParams();
      const isMatch = params.activeFilePath === myParams.activeFilePath && params.linesStart === myParams.linesStart && params.linesEnd === myParams.linesEnd;
      setIsActive(isMatch);
      if (params.platform !== undefined || params.framework !== undefined || params.activeFilePath !== myParams.activeFilePath) {
        hasTriggeredRef.current = false;
      }
    };
    checkActive(iframeState.params);
    return iframeState.subscribe(checkActive);
  }, [getParams]);
  React.useEffect(() => {
    const element = sectionRef.current;
    if (!element) return;
    const observer = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        if (entry.isIntersecting && !hasTriggeredRef.current) {
          hasTriggeredRef.current = true;
          handleFocus();
        } else if (!entry.isIntersecting) {
          hasTriggeredRef.current = false;
        }
      });
    }, {
      threshold: 0,
      rootMargin: "-40% 0px -40% 0px"
    });
    observer.observe(element);
    return () => observer.disconnect();
  }, [handleFocus]);
  return <div ref={sectionRef} onClick={handleFocus} className="relative py-6 transition-colors cursor-pointer" style={{
    marginLeft: "-1.5rem",
    marginRight: "-1.5rem",
    paddingLeft: "1.5rem",
    paddingRight: "1.5rem"
  }}>
      <div className="absolute top-0 h-px" style={{
    backgroundColor: "rgba(128,128,128,0.2)",
    left: "-2rem",
    right: "-2rem"
  }} />
      {isActive && <div className={`absolute -left-2 top-0 bottom-0 w-1 ${useProse ? "bg-primary dark:bg-primary-light" : ""}`} style={!useProse && themeColor ? {
    backgroundColor: themeColor
  } : undefined} />}
      {title && <div className="flex items-center gap-2 mb-2">
          <h4 className={`text-base font-semibold m-0 ${useProse && isActive ? "text-primary dark:text-primary-light" : ""}`} style={!useProse && isActive && themeColor ? {
    color: themeColor
  } : undefined}>
            {title}
          </h4>
        </div>}
      {description && <p className="text-sm text-gray-500 dark:text-gray-400 mt-1 mb-0">
          {description}
        </p>}
      {children && <div className="mt-3">{children}</div>}
    </div>;
};

export const SideBySideLayout = ({previewSrc, children}) => {
  const iframeRef = React.useRef(null);
  const pendingParams = React.useRef(null);
  const iframeReady = React.useRef(false);
  const baseUrlRef = React.useRef(previewSrc);
  const architectures = React.useMemo(() => {
    const derived = [];
    React.Children.forEach(children, child => {
      if (child?.type === Architecture) {
        const archValue = child.props.value;
        const archLabel = child.props.label;
        const frameworks = [];
        React.Children.forEach(child.props.children, frameworkChild => {
          if (frameworkChild?.type === FrameworkGuide) {
            frameworks.push({
              value: frameworkChild.props.framework,
              label: frameworkChild.props.label || frameworkChild.props.framework
            });
          }
        });
        derived.push({
          value: archValue,
          label: archLabel,
          frameworks
        });
      }
    });
    return derived;
  }, [children]);
  const SettingsNavInternal = () => {
    const parseFrameworkValue = (archValue, fwValue, fwLabel) => {
      const archPrefix = archValue.toLowerCase().split(" ")[0];
      const archPrefixMap = {
        javascript: "js",
        ios: "ios",
        android: "ad"
      };
      const prefix = archPrefixMap[archPrefix] || archPrefix;
      let remaining = fwValue;
      if (fwValue.startsWith(prefix + "-")) {
        remaining = fwValue.slice(prefix.length + 1);
      }
      const labelParts = fwLabel.split(" + ");
      if (!fwLabel.includes(" + ")) {
        return {
          frontend: remaining,
          frontendLabel: fwLabel,
          backend: null,
          backendLabel: null,
          isFullStack: true
        };
      }
      const parts = remaining.split("-");
      if (parts.length >= 2) {
        return {
          frontend: parts[0],
          frontendLabel: labelParts[0] || parts[0],
          backend: parts.slice(1).join("-"),
          backendLabel: labelParts[1] || parts.slice(1).join("-"),
          isFullStack: false
        };
      }
      return {
        frontend: remaining,
        frontendLabel: fwLabel,
        backend: null,
        backendLabel: null,
        isFullStack: true
      };
    };
    const [selections, setSelections] = React.useState(() => {
      const defaults = {};
      if (architectures && architectures.length > 0) {
        const firstArch = architectures[0];
        defaults.platform = firstArch.value;
        if (firstArch.frameworks && firstArch.frameworks.length > 0) {
          const firstFw = firstArch.frameworks[0];
          const parsed = parseFrameworkValue(firstArch.value, firstFw.value, firstFw.label);
          defaults.client = parsed.frontend;
          defaults.server = parsed.backend;
          defaults.framework = firstFw.value;
        }
      }
      return defaults;
    });
    const getAvailableOptions = React.useMemo(() => {
      const selectedArch = architectures?.find(arch => arch.value === selections.platform);
      const frameworks = selectedArch?.frameworks || [];
      const frontends = new Map();
      const backends = new Map();
      const fullStackFrameworks = [];
      frameworks.forEach(fw => {
        const parsed = parseFrameworkValue(selectedArch?.value || "", fw.value, fw.label);
        if (parsed.isFullStack) {
          fullStackFrameworks.push({
            value: parsed.frontend,
            label: parsed.frontendLabel,
            fullFrameworkValue: fw.value
          });
        } else {
          if (!frontends.has(parsed.frontend)) {
            frontends.set(parsed.frontend, {
              value: parsed.frontend,
              label: parsed.frontendLabel
            });
          }
          if (parsed.backend && !backends.has(parsed.backend)) {
            backends.set(parsed.backend, {
              value: parsed.backend,
              label: parsed.backendLabel
            });
          }
        }
      });
      fullStackFrameworks.forEach(fs => {
        if (!frontends.has(fs.value)) {
          frontends.set(fs.value, {
            value: fs.value,
            label: fs.label,
            isFullStack: true,
            fullFrameworkValue: fs.fullFrameworkValue
          });
        }
      });
      return {
        frontends: Array.from(frontends.values()),
        backends: Array.from(backends.values()),
        fullStackFrameworks
      };
    }, [architectures, selections.platform]);
    const isFullStackSelected = React.useMemo(() => {
      const frontend = getAvailableOptions.frontends.find(f => f.value === selections.client);
      return frontend?.isFullStack || false;
    }, [getAvailableOptions.frontends, selections.client]);
    const sections = [{
      id: "platform",
      label: "Architecture:",
      options: architectures || []
    }, {
      id: "client",
      label: "Frontend:",
      options: getAvailableOptions.frontends
    }, ...isFullStackSelected ? [] : [{
      id: "server",
      label: "Backend:",
      options: getAvailableOptions.backends
    }]];
    React.useEffect(() => {
      if (selections.platform || selections.framework) {
        iframeState.setParams({
          ...iframeState.params,
          ...selections
        });
      }
    }, []);
    const handleSelect = (sectionId, value) => {
      let newSelections = {
        ...selections,
        [sectionId]: value
      };
      const getArchPrefix = archValue => {
        const archPrefix = archValue.toLowerCase().split(" ")[0];
        const archPrefixMap = {
          javascript: "js",
          ios: "ios",
          android: "ad"
        };
        return archPrefixMap[archPrefix] || archPrefix;
      };
      const getBackendsForArch = archValue => {
        const arch = architectures?.find(a => a.value === archValue);
        const backends = new Map();
        arch?.frameworks?.forEach(fw => {
          const parsed = parseFrameworkValue(arch.value, fw.value, fw.label);
          if (!parsed.isFullStack && parsed.backend) {
            backends.set(parsed.backend, parsed.backendLabel);
          }
        });
        return Array.from(backends.keys());
      };
      if (sectionId === "platform") {
        const newArch = architectures?.find(arch => arch.value === value);
        if (newArch?.frameworks && newArch.frameworks.length > 0) {
          const firstFw = newArch.frameworks[0];
          const parsed = parseFrameworkValue(newArch.value, firstFw.value, firstFw.label);
          newSelections.client = parsed.frontend;
          newSelections.server = parsed.backend;
          newSelections.framework = firstFw.value;
        }
      }
      if (sectionId === "client") {
        const selectedArch = architectures?.find(arch => arch.value === newSelections.platform);
        const frameworks = selectedArch?.frameworks || [];
        const fullStackFw = frameworks.find(fw => {
          const parsed = parseFrameworkValue(selectedArch?.value || "", fw.value, fw.label);
          return parsed.isFullStack && parsed.frontend === value;
        });
        if (fullStackFw) {
          newSelections.server = null;
          newSelections.framework = fullStackFw.value;
        } else {
          const prefix = getArchPrefix(newSelections.platform);
          let server = newSelections.server;
          if (!server) {
            const availableBackends = getBackendsForArch(newSelections.platform);
            server = availableBackends[0] || null;
            newSelections.server = server;
          }
          if (server) {
            newSelections.framework = `${prefix}-${value}-${server}`;
          }
        }
      }
      if (sectionId === "server") {
        const prefix = getArchPrefix(newSelections.platform);
        const client = newSelections.client;
        newSelections.framework = `${prefix}-${client}-${value}`;
      }
      setSelections(newSelections);
      iframeState.setParams({
        ...iframeState.params,
        ...newSelections
      });
    };
    return <div className="w-full sticky top-0 z-50 lg:-mx-8 px-4 lg:px-8 py-6 backdrop-blur-md">
        <div className="flex flex-wrap items-center justify-between">
          <div className="flex flex-wrap items-center" style={{
      marginLeft: "-24px",
      marginTop: "-24px"
    }}>
            {sections.map(section => <div key={section.id} className="flex items-center flex-wrap" style={{
      marginTop: "24px",
      marginLeft: "24px"
    }}>
                <span className="text-sm font-semibold text-gray-700 dark:text-gray-300 whitespace-nowrap mr-3">
                  {section.label}
                </span>

                {}
                <fieldset className="hidden 2xl:block border-0 p-0 m-0">
                  <legend className="sr-only">{section.label}</legend>
                  <div className="flex items-center gap-2">
                    {section.options.map(option => {
      const isSelected = selections[section.id] === option.value;
      return <div key={option.value} className="relative">
                          <input type="radio" id={`${section.id}-${option.value}`} name={section.id} value={option.value} checked={isSelected} onChange={() => handleSelect(section.id, option.value)} className="sr-only" />
                          <label htmlFor={`${section.id}-${option.value}`} className={`inline-flex items-center px-3 py-1.5 text-xs font-medium rounded-md border transition-all cursor-pointer active:scale-[0.98] ${isSelected ? "bg-white dark:bg-zinc-900 border-primary dark:border-primary-light text-primary dark:text-primary-light hover:bg-zinc-100 dark:hover:bg-zinc-800" : "bg-white dark:bg-zinc-900 border-zinc-300 dark:border-zinc-700 text-zinc-900 dark:text-zinc-100 hover:bg-zinc-100 dark:hover:bg-zinc-800"}`}>
                            {option.label}
                          </label>
                        </div>;
    })}
                  </div>
                </fieldset>

                {}
                <div className="block 2xl:hidden relative">
                  <select value={selections[section.id]} onChange={e => handleSelect(section.id, e.target.value)} className="appearance-none bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-md px-3 py-1.5 pr-8 text-xs font-medium text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-primary dark:focus:ring-primary-light focus:border-transparent transition-all hover:bg-zinc-100 dark:hover:bg-zinc-800">
                    {section.options.map(option => <option key={option.value} value={option.value}>
                        {option.label}
                      </option>)}
                  </select>
                  <svg aria-hidden="true" width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" className="absolute right-2 top-1/2 -translate-y-1/2 pointer-events-none text-zinc-400">
                    <path fillRule="evenodd" clipRule="evenodd" d="M2.35 9.915a.875.875 0 0 1 1.235-.065L8 13.823l4.415-3.973a.875.875 0 0 1 1.17 1.3l-5 4.5a.873.873 0 0 1-1.17 0l-5-4.5a.875.875 0 0 1-.065-1.235ZM7.415.35a.873.873 0 0 1 1.17 0l5 4.5a.875.875 0 1 1-1.17 1.3L8 2.177 3.585 6.15a.875.875 0 0 1-1.17-1.3l5-4.5Z" fill="currentColor" />
                  </svg>
                </div>
              </div>)}
          </div>
        </div>
      </div>;
  };
  const getCurrentColor = () => {
    const temp = document.createElement("div");
    temp.className = document.documentElement.classList.contains("dark") ? "dark:bg-primary-light" : "bg-primary";
    document.body.appendChild(temp);
    const bgColor = getComputedStyle(temp).backgroundColor;
    document.body.removeChild(temp);
    return bgColor;
  };
  function rgbToHex(rgb) {
    const match = rgb.match(/\d+/g);
    if (!match) return null;
    const [r, g, b] = match.map(Number);
    return "#" + [r, g, b].map(x => x.toString(16).padStart(2, "0")).join("");
  }
  const getCurrentColorInHexadecimal = () => {
    return "%23" + rgbToHex(getCurrentColor()).split("#")[1];
  };
  const updateIframeTheme = React.useCallback(() => {
    if (iframeRef.current) {
      const currentParams = iframeState.params;
      let newSrc = baseUrlRef.current + "&theme=" + getCurrentColorInHexadecimal();
      if (currentParams.iframeUrl) {
        newSrc += "&iframeUrl=" + encodeURIComponent(currentParams.iframeUrl);
      }
      iframeRef.current.src = newSrc;
    }
  }, []);
  React.useEffect(() => {
    const observer = new MutationObserver(mutations => {
      mutations.forEach(mutation => {
        if (mutation.attributeName === "class") {
          updateIframeTheme();
        }
      });
    });
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class"]
    });
    return () => observer.disconnect();
  }, [updateIframeTheme]);
  React.useEffect(() => {
    let lastFramework = iframeState.params.framework;
    let lastFilePath = iframeState.params.activeFilePath;
    let debounceTimer = null;
    const handleParamsChange = params => {
      if (params.framework && params.framework !== lastFramework) {
        lastFramework = params.framework;
        if (iframeRef.current) {
          const url = new URL(iframeRef.current.src);
          url.searchParams.set("framework", params.framework);
          iframeRef.current.src = url.toString();
          return;
        }
      }
      if (debounceTimer) {
        clearTimeout(debounceTimer);
      }
      const fileChanged = params.activeFilePath && params.activeFilePath !== lastFilePath;
      if (fileChanged) {
        lastFilePath = params.activeFilePath;
      }
      const delay = fileChanged ? 150 : 0;
      debounceTimer = setTimeout(() => {
        const message = {
          type: "UPDATE_VIEW",
          ...params
        };
        if (iframeRef.current?.contentWindow) {
          iframeRef.current.contentWindow.postMessage(message, "*");
        }
      }, delay);
    };
    const unsubscribe = iframeState.subscribe(handleParamsChange);
    return () => {
      if (debounceTimer) clearTimeout(debounceTimer);
      unsubscribe();
    };
  }, []);
  const ActiveContent = () => {
    const [currentState, setCurrentState] = React.useState(() => {
      const params = iframeState.params;
      return {
        platform: params.platform || architectures[0]?.value,
        framework: params.framework || architectures[0]?.frameworks[0]?.value
      };
    });
    const [currentPageId, setCurrentPageId] = React.useState("1");
    React.useEffect(() => {
      const handleUpdate = params => {
        if (params.platform !== undefined || params.framework !== undefined) {
          setCurrentState(prev => ({
            platform: params.platform ?? prev.platform,
            framework: params.framework ?? prev.framework
          }));
        }
      };
      return iframeState.subscribe(handleUpdate);
    }, []);
    let matchedContent = null;
    React.Children.forEach(children, child => {
      if (child?.type === Architecture && child.props.value === currentState.platform) {
        React.Children.forEach(child.props.children, frameworkChild => {
          if (frameworkChild?.type === FrameworkGuide && frameworkChild.props.framework === currentState.framework) {
            matchedContent = frameworkChild.props.children;
          }
        });
      }
    });
    const isPageComponent = child => {
      if (child?.props?.["data-page-id"]) return true;
      if (child?.type?.name === "Page") return true;
      if (typeof child?.type === "function" && child?.props?.id && child?.props?.title) {
        return true;
      }
      return false;
    };
    const pages = React.useMemo(() => {
      const extracted = [];
      React.Children.forEach(matchedContent, child => {
        if (isPageComponent(child)) {
          let verificationSteps = null;
          const stepsData = child.props["data-page-verification-steps"] || child.props.verificationSteps;
          if (stepsData) {
            try {
              verificationSteps = typeof stepsData === "string" ? JSON.parse(stepsData) : stepsData;
            } catch (e) {
              console.warn("Failed to parse verification steps:", e);
            }
          }
          extracted.push({
            id: child.props["data-page-id"] || child.props.id,
            title: child.props["data-page-title"] || child.props.title,
            content: child.props.children,
            verificationSteps
          });
        }
      });
      return extracted;
    }, [matchedContent]);
    React.useEffect(() => {
      if (pages.length > 0 && !pages.find(p => p.id === currentPageId)) {
        setCurrentPageId(pages[0].id);
      }
    }, [pages, currentPageId]);
    if (pages.length === 0) {
      return <>{matchedContent}</>;
    }
    if (pages.length === 1) {
      const currentPage = pages[0];
      return <>{currentPage?.content}</>;
    }
    const currentPageIndex = pages.findIndex(p => p.id === currentPageId);
    const currentPage = pages[currentPageIndex];
    const nextPage = currentPageIndex < pages.length - 1 ? pages[currentPageIndex + 1] : null;
    const [showStepsPopup, setShowStepsPopup] = React.useState(false);
    const [showVerificationPopup, setShowVerificationPopup] = React.useState(false);
    const [verificationSteps, setVerificationSteps] = React.useState([]);
    const [currentVerificationIndex, setCurrentVerificationIndex] = React.useState(0);
    const [verificationComplete, setVerificationComplete] = React.useState(false);
    const getVerificationStepsForPage = pageId => {
      const page = pages.find(p => p.id === pageId);
      if (page?.verificationSteps && page.verificationSteps.length > 0) {
        return page.verificationSteps;
      }
      const defaultSteps = [{
        id: 1,
        label: "Checking configuration"
      }, {
        id: 2,
        label: "Validating setup"
      }, {
        id: 3,
        label: "Verifying connection"
      }, {
        id: 4,
        label: "Ready to continue"
      }];
      return defaultSteps;
    };
    const goToPage = pageId => {
      setCurrentPageId(pageId);
      setShowStepsPopup(false);
      window.scrollTo({
        top: 0,
        behavior: "smooth"
      });
    };
    const handleNextClick = () => {
      if (!nextPage) return;
      const steps = getVerificationStepsForPage(currentPage.id);
      setVerificationSteps(steps);
      setCurrentVerificationIndex(0);
      setVerificationComplete(false);
      setShowVerificationPopup(true);
      steps.forEach((_, index) => {
        setTimeout(() => {
          setCurrentVerificationIndex(index);
          if (index === steps.length - 1) {
            setTimeout(() => {
              setVerificationComplete(true);
            }, 600);
          }
        }, (index + 1) * 800);
      });
    };
    const handleVerificationComplete = () => {
      setShowVerificationPopup(false);
      if (nextPage) {
        goToPage(nextPage.id);
      }
    };
    const barContainerRef = React.useRef(null);
    React.useEffect(() => {
      const handleClickOutside = event => {
        if (barContainerRef.current && !barContainerRef.current.contains(event.target) && (showStepsPopup || showVerificationPopup)) {
          if (showVerificationPopup && !verificationComplete) {
            return;
          }
          setShowStepsPopup(false);
          if (verificationComplete) {
            setShowVerificationPopup(false);
          }
        }
      };
      if (showStepsPopup || showVerificationPopup) {
        document.addEventListener("mousedown", handleClickOutside);
        return () => {
          document.removeEventListener("mousedown", handleClickOutside);
        };
      }
    }, [showStepsPopup, showVerificationPopup, verificationComplete]);
    return <div className="page-container relative">
        {}
        <div className="page-content pb-24">{currentPage?.content}</div>

        {}
        <div className="sticky bottom-4 z-40" ref={barContainerRef}>
          <div className="relative">
            {}
            <div className="bg-white dark:bg-zinc-900 border border-gray-200 dark:border-zinc-700 shadow-lg rounded-xl px-4 py-3">
              <div className="flex items-center justify-between gap-4">
                {}
                <button onClick={() => setShowStepsPopup(!showStepsPopup)} className="flex items-center gap-3 px-3 py-2 rounded-lg bg-gray-100 dark:bg-zinc-800 hover:bg-gray-200 dark:hover:bg-zinc-700 transition-all">
                  <div className="flex items-center gap-2">
                    <div className="w-6 h-6 rounded-full bg-primary dark:bg-primary-light text-white text-xs font-bold flex items-center justify-center">
                      {currentPageIndex + 1}
                    </div>
                    <span className="text-sm font-medium text-gray-700 dark:text-gray-300">
                      {currentPage?.title}
                    </span>
                  </div>
                  <svg className={`w-4 h-4 text-gray-400 transition-transform ${showStepsPopup ? "rotate-180" : ""}`} fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                    <path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
                  </svg>
                </button>

                {}
                {nextPage ? <button onClick={handleNextClick} className="flex items-center gap-2 px-5 py-2 rounded-lg bg-primary dark:bg-primary-light text-white font-medium hover:opacity-90 transition-all">
                    <span>Verify</span>
                    <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                      <path strokeLinecap="round" strokeLinejoin="round" d="M9 5l7 7-7 7" />
                    </svg>
                  </button> : <div className="flex items-center gap-2 px-5 py-2 rounded-lg bg-green-500 text-white font-medium">
                    <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                      <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
                    </svg>
                    <span>Complete</span>
                  </div>}
              </div>
            </div>

            {}
            {showStepsPopup && <div className="absolute bottom-full left-0 right-0 mb-2 z-50">
                <div className="bg-white dark:bg-zinc-900 border border-gray-200 dark:border-zinc-700 shadow-2xl rounded-xl overflow-hidden animate-expand-up">
                  {}
                  <div className="flex items-center justify-between px-3 py-2 border-b border-gray-200 dark:border-zinc-700 bg-gray-50 dark:bg-zinc-800/50">
                    <div className="flex items-center gap-2">
                      <div className="w-5 h-5 rounded-full bg-primary dark:bg-primary-light text-white text-xs font-bold flex items-center justify-center leading-none">
                        {pages.length}
                      </div>
                      <span className="text-sm font-semibold text-gray-900 dark:text-white leading-none">
                        Steps
                      </span>
                    </div>
                    <button onClick={() => setShowStepsPopup(false)} className="p-1 rounded-md hover:bg-gray-200 dark:hover:bg-zinc-700 transition-colors flex-shrink-0">
                      <svg className="w-4 h-4 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                        <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
                      </svg>
                    </button>
                  </div>

                  {}
                  <div className="p-3 space-y-1 max-h-80 overflow-y-auto">
                    {pages.map((page, index) => {
      const isCompleted = index < currentPageIndex;
      const isCurrent = page.id === currentPageId;
      const isDisabled = index > currentPageIndex;
      return <div key={page.id} className="relative group">
                          <button onClick={() => !isDisabled && goToPage(page.id)} disabled={isDisabled} className={`w-full flex items-center gap-3 p-2.5 rounded-lg text-left transition-all ${isCurrent ? "bg-primary/10 dark:bg-primary-light/10 border border-primary/30 dark:border-primary-light/30" : isDisabled ? "opacity-50 cursor-not-allowed" : "hover:bg-gray-100 dark:hover:bg-zinc-800"}`}>
                            {}
                            <div className={`flex-shrink-0 w-7 h-7 rounded-full flex items-center justify-center text-xs font-bold transition-all ${isCompleted ? "bg-primary dark:bg-primary-light text-white" : isCurrent ? "bg-primary dark:bg-primary-light text-white" : isDisabled ? "bg-gray-100 dark:bg-zinc-800 text-gray-400 dark:text-gray-600" : "bg-gray-200 dark:bg-zinc-700 text-gray-500 dark:text-gray-400"}`}>
                              {isCompleted ? <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={3}>
                                  <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
                                </svg> : index + 1}
                            </div>
                            {}
                            <span className={`text-sm font-medium ${isCurrent ? "text-primary dark:text-primary-light" : isCompleted ? "text-gray-500 dark:text-gray-400" : isDisabled ? "text-gray-400 dark:text-gray-600" : "text-gray-700 dark:text-gray-300"}`}>
                              {page.title}
                            </span>
                          </button>
                          {}
                          {isDisabled && <div className="absolute left-0 bottom-full mb-2 w-64 px-3 py-2 bg-gray-900 dark:bg-gray-700 text-white text-xs rounded-lg shadow-lg opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none z-50">
                              Please complete all steps in this guide and press
                              verify
                              <div className="absolute top-full left-4 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-gray-900 dark:border-t-gray-700"></div>
                            </div>}
                        </div>;
    })}
                  </div>
                </div>
              </div>}

            {}
            {showVerificationPopup && <div className="absolute bottom-full left-0 right-0 mb-2 z-50">
                <div className="bg-white dark:bg-zinc-900 border border-gray-200 dark:border-zinc-700 shadow-2xl rounded-xl overflow-hidden animate-expand-up">
                  {}
                  <div className="flex items-center justify-between px-3 py-2 border-b border-gray-200 dark:border-zinc-700 bg-gray-50 dark:bg-zinc-800/50">
                    <div className="flex items-center gap-2">
                      <div className="w-5 h-5 rounded-full bg-primary dark:bg-primary-light text-white text-xs font-bold flex items-center justify-center leading-none">
                        {verificationSteps.length}
                      </div>
                      <span className="text-sm font-semibold text-gray-900 dark:text-white leading-none">
                        {verificationComplete ? "Verification Complete" : "Verifying..."}
                      </span>
                    </div>
                    {verificationComplete && <button onClick={() => setShowVerificationPopup(false)} className="p-1 rounded-md hover:bg-gray-200 dark:hover:bg-zinc-700 transition-colors flex-shrink-0">
                        <svg className="w-4 h-4 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                          <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
                        </svg>
                      </button>}
                  </div>

                  {}
                  <div className="p-3 space-y-2">
                    {verificationSteps.map((step, index) => {
      const isChecked = index <= currentVerificationIndex;
      const isActive = index === currentVerificationIndex && !verificationComplete;
      return <div key={step.id} className={`flex items-center gap-3 p-2 rounded-lg transition-all duration-300 ${isActive ? "bg-primary/5 dark:bg-primary-light/5" : ""}`}>
                          {}
                          <div className={`flex-shrink-0 w-6 h-6 rounded-md border-2 flex items-center justify-center transition-all duration-300 ${isChecked ? "bg-primary dark:bg-primary-light border-primary dark:border-primary-light" : "border-gray-300 dark:border-zinc-600"}`}>
                            {isChecked && <svg className="w-4 h-4 text-white animate-check" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={3}>
                                <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
                              </svg>}
                          </div>
                          {}
                          <span className={`text-sm font-medium transition-all duration-300 ${isChecked ? "text-gray-900 dark:text-white" : "text-gray-400 dark:text-gray-500"}`}>
                            {step.label}
                          </span>
                          {}
                          {isActive && <div className="ml-auto">
                              <svg className="w-4 h-4 text-primary dark:text-primary-light animate-spin" fill="none" viewBox="0 0 24 24">
                                <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
                                <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" />
                              </svg>
                            </div>}
                        </div>;
    })}
                  </div>

                  {}
                  {verificationComplete && <div className="px-3 pb-3">
                      <button onClick={handleVerificationComplete} className="w-full flex items-center justify-center gap-2 px-4 py-2.5 rounded-lg bg-primary dark:bg-primary-light text-white font-medium hover:opacity-90 transition-all text-sm">
                        <span>Continue to {nextPage?.title}</span>
                        <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                          <path strokeLinecap="round" strokeLinejoin="round" d="M9 5l7 7-7 7" />
                        </svg>
                      </button>
                    </div>}
                </div>
              </div>}
          </div>
        </div>

        {}
        <style>{`
          @keyframes expand-up {
            from {
              transform: translateY(8px) scale(0.98);
              opacity: 0;
            }
            to {
              transform: translateY(0) scale(1);
              opacity: 1;
            }
          }
          .animate-expand-up {
            animation: expand-up 0.2s ease-out;
          }
          @keyframes check {
            from {
              transform: scale(0);
            }
            to {
              transform: scale(1);
            }
          }
          .animate-check {
            animation: check 0.2s ease-out;
          }
        `}</style>
      </div>;
  };
  return <div className="mx-auto px-4 lg:px-8 flex flex-col">
      <SettingsNavInternal />

      <div className="rounded-2xl shadow-sm flex-1">
        <div className="grid gap-8 lg:gap-10 items-start" style={{
    gridTemplateColumns: "minmax(0, 0.8fr) minmax(0, 1.2fr)"
  }}>
          <div className="prose prose-gray dark:prose-invert max-w-none pr-2">
            <ActiveContent />
          </div>
          <div className="sticky top-20">
            <div style={{
    borderRadius: "0.5rem",
    overflow: "hidden",
    background: "#020617",
    height: "calc(100vh - 180px)"
  }}>
              <iframe ref={iframeRef} src={(() => {
    const src = previewSrc + "&theme=" + getCurrentColorInHexadecimal() + (iframeState.params.iframeUrl ? "&iframeUrl=" + encodeURIComponent(iframeState.params.iframeUrl) : "");
    return src;
  })()} title="App preview" style={{
    width: "100%",
    height: "calc(100vh - 180px)",
    border: "0"
  }} allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
            </div>
          </div>
        </div>
      </div>
    </div>;
};

<SideBySideLayout previewSrc="https://stripe-sandbox.sampleapp.ai/accept-payments-with-stripe-checkout?framework=js-html-ruby&isFrame=true">
  <Architecture value="JavaScript SDK" label="JavaScript SDK">
    <FrameworkGuide framework="js-html-ruby" label="HTML + Ruby">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-checkout-prebuilt-subscription-ruby/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-checkout-prebuilt-subscription-ruby" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="server.rb" linesStart={2} linesEnd={4} title="Install the Stripe Ruby library">
        Install the Stripe ruby gem and require it in your code. Alternatively, if you're starting from scratch and need a Gemfile, download the project files using the link in the code editor.

        **Terminal:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        gem install stripe
        ```

        **Bundler (add to Gemfile):**

        ```ruby theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        gem 'stripe'
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={82} linesEnd={103} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={89} linesEnd={91} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout page on the client

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={9} linesEnd={9} title="Load Stripe.js">
        Use Stripe.js to remain PCI compliant by ensuring that payment details are sent directly to Stripe without hitting your server. Always load Stripe.js from `js.stripe.com` to remain compliant. Don't include the script in a bundle or host it yourself.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={14} linesEnd={24} title="Define the payment form">
        Add one empty placeholder `div` to your checkout form for each Element that you'll mount. Stripe inserts an iframe into each `div` to securely collect the customer's email address and payment information.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={2} linesEnd={2} title="Initialize Stripe.js">
        Initialize Stripe.js with your publishable API key. You'll use Stripe.js to create the Payment Element and complete the payment on the client.

        **Note:** This is a public sample test API key. Don't submit any personally identifiable information in requests made with this key.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={15} linesEnd={35} title="Fetch a PaymentIntent">
        Immediately make a request to the endpoint on your server to create a new PaymentIntent as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={27} linesEnd={27} title="Initialize Stripe Elements">
        Initialize the Stripe Elements UI library with the client secret. Elements manages the UI components you need to collect payment details.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={33} linesEnd={34} title="Create the PaymentElement">
        Create a `PaymentElement` and mount it to the placeholder `<div>` in your payment form. This embeds an iframe with a dynamic form that displays configured payment method types available from the PaymentIntent, allowing your customer to select a payment method. The form automatically collects the associated payment details for the selected payment method type.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={37} linesEnd={62} title="Handle the submit event">
        Listen to the form's submit event to know when to confirm the payment through the Stripe API.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={41} linesEnd={48} title="Complete the payment">
        Call `confirmPayment` with the Element instance and a `return_url` to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for 3D Secure authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={50} linesEnd={59} title="Handle errors">
        If there are any immediate errors (for example, your customer's card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/complete.js" linesStart={72} linesEnd={86} title="Show a payment status message">
        When Stripe redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by Stripe.js. Use this to retrieve the PaymentIntent status update and determine what to show to your customer.
      </CodeFocusSection>

      ### ❹ Handle post-payment events

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Use a webhook">
        Stripe sends multiple events during the payment process and after the payment is complete. Create an event destination for a webhook endpoint to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow. Stripe recommends handling the `payment_intent.succeeded`, `payment_intent.processing`, and `payment_intent.payment_failed` events.

        Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.
      </CodeFocusSection>

      ### ❺ Test the integration

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Run the application">
        Run your Ruby server and go to `localhost:4242/checkout.html`.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        ruby server.rb
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.rb" linesStart={79} linesEnd={86} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={92} linesEnd={98} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Send an email receipt

      Stripe can send an email receipt to your customer using your brand logo and colour theme, which are configurable in the Dashboard.

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={15} linesEnd={15} title="Collect the customer's email address">
        Add an input field to your payment form to collect the email address.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={46} linesEnd={46} title="Provide the email address to Stripe">
        Pass the provided email address as the `receipt_email` value. Stripe sends an email receipt when the payment succeeds in live mode (but won't send one in a sandbox).
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.rb" linesStart={70} linesEnd={78} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={84} linesEnd={85} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={41} linesEnd={64} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Collect billing address details">
        By default, the Payment Element only collects the necessary billing address details. To collect a customer's full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="js-html-nodejs" label="HTML + Node.js">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-checkout-prebuilt-subscription-nodejs/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-checkout-prebuilt-subscription-nodejs" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="server.js" linesStart={3} linesEnd={4} title="Install the Stripe Node library">
        Install the package and import it in your code. Alternatively, if you're starting from scratch and need a package.json file, download the project files using the Download link in the code editor.

        **npm:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm install --save stripe
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={86} linesEnd={108} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={92} linesEnd={95} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout page on the client

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={10} linesEnd={15} title="Load Stripe.js">
        Use Stripe.js to remain PCI compliant by ensuring that payment details are sent directly to Stripe without hitting your server. Always load Stripe.js from `js.stripe.com` to remain compliant. Don't include the script in a bundle or host it yourself.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={20} linesEnd={25} title="Define the payment form">
        Add one empty placeholder `div` to your checkout form for each Element that you'll mount. Stripe inserts an iframe into each `div` to securely collect the customer's email address and payment information.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={1} linesEnd={3} title="Initialize Stripe.js">
        Initialize Stripe.js with your publishable API key. You'll use Stripe.js to create the Payment Element and complete the payment on the client.

        **Note:** This is a public sample test API key. Don't submit any personally identifiable information in requests made with this key.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={5} linesEnd={15} title="Fetch a PaymentIntent">
        Immediately make a request to the endpoint on your server to create a new PaymentIntent as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={17} linesEnd={25} title="Initialize Stripe Elements">
        Initialize the Stripe Elements UI library with the client secret. Elements manages the UI components you need to collect payment details.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={27} linesEnd={35} title="Create the PaymentElement">
        Create a `PaymentElement` and mount it to the placeholder `<div>` in your payment form. This embeds an iframe with a dynamic form that displays configured payment method types available from the PaymentIntent, allowing your customer to select a payment method. The form automatically collects the associated payment details for the selected payment method type.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={52} linesEnd={60} title="Handle the submit event">
        Listen to the form's submit event to know when to confirm the payment through the Stripe API.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={62} linesEnd={75} title="Complete the payment">
        Call `confirmPayment` with the Element instance and a `return_url` to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for 3D Secure authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={77} linesEnd={85} title="Handle errors">
        If there are any immediate errors (for example, your customer's card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/complete.js" linesStart={1} linesEnd={20} title="Show a payment status message">
        When Stripe redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by Stripe.js. Use this to retrieve the PaymentIntent status update and determine what to show to your customer.
      </CodeFocusSection>

      ### ❹ Handle post-payment events

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Use a webhook">
        Stripe sends multiple events during the payment process and after the payment is complete. Create an event destination for a webhook endpoint to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow. Stripe recommends handling the `payment_intent.succeeded`, `payment_intent.processing`, and `payment_intent.payment_failed` events.

        Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.
      </CodeFocusSection>

      ### ❺ Test the integration

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Run the application">
        Run your Node server and go to `localhost:4242/checkout.html`.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm start
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.js" linesStart={88} linesEnd={88} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={94} linesEnd={100} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Send an email receipt

      Stripe can send an email receipt to your customer using your brand logo and colour theme, which are configurable in the Dashboard.

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={15} linesEnd={15} title="Collect the customer's email address">
        Add an input field to your payment form to collect the email address.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={46} linesEnd={46} title="Provide the email address to Stripe">
        Pass the provided email address as the `receipt_email` value. Stripe sends an email receipt when the payment succeeds in live mode (but won't send one in a sandbox).
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.js" linesStart={68} linesEnd={78} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={86} linesEnd={87} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={42} linesEnd={64} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={111} title="Collect billing address details">
        By default, the Payment Element only collects the necessary billing address details. To collect a customer's full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={111} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={111} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={111} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="js-html-php" label="HTML + PHP">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-checkout-prebuilt-subscription-php/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-checkout-prebuilt-subscription-php" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="public/create.php" linesStart={6} linesEnd={6} title="Install the Stripe PHP library">
        Install the library with composer and initialize with your secret API key. Alternatively, if you're starting from scratch and need a composer.json file, download the files using the link in the code editor.

        **Composer:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        composer require stripe/stripe-php
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={63} linesEnd={84} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={69} linesEnd={72} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout page on the client

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={9} linesEnd={10} title="Load Stripe.js">
        Use Stripe.js to remain PCI compliant by ensuring that payment details are sent directly to Stripe without hitting your server. Always load Stripe.js from `js.stripe.com` to remain compliant. Don't include the script in a bundle or host it yourself.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={14} linesEnd={22} title="Define the payment form">
        Add one empty placeholder `div` to your checkout form for each Element that you'll mount. Stripe inserts an iframe into each `div` to securely collect the customer's email address and payment information.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={1} linesEnd={2} title="Initialize Stripe.js">
        Initialize Stripe.js with your publishable API key. You'll use Stripe.js to create the Payment Element and complete the payment on the client.

        **Note:** This is a public sample test API key. Don't submit any personally identifiable information in requests made with this key.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={16} linesEnd={22} title="Fetch a PaymentIntent">
        Immediately make a request to the endpoint on your server to create a new PaymentIntent as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={24} linesEnd={27} title="Initialize Stripe Elements">
        Initialize the Stripe Elements UI library with the client secret. Elements manages the UI components you need to collect payment details.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={29} linesEnd={34} title="Create the PaymentElement">
        Create a `PaymentElement` and mount it to the placeholder `<div>` in your payment form. This embeds an iframe with a dynamic form that displays configured payment method types available from the PaymentIntent, allowing your customer to select a payment method. The form automatically collects the associated payment details for the selected payment method type.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={37} linesEnd={39} title="Handle the submit event">
        Listen to the form's submit event to know when to confirm the payment through the Stripe API.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={41} linesEnd={48} title="Complete the payment">
        Call `confirmPayment` with the Element instance and a `return_url` to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for 3D Secure authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={50} linesEnd={61} title="Handle errors">
        If there are any immediate errors (for example, your customer's card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/complete.js" linesStart={22} linesEnd={86} title="Show a payment status message">
        When Stripe redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by Stripe.js. Use this to retrieve the PaymentIntent status update and determine what to show to your customer.
      </CodeFocusSection>

      ### ❹ Handle post-payment events

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={91} title="Use a webhook">
        Stripe sends multiple events during the payment process and after the payment is complete. Create an event destination for a webhook endpoint to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow. Stripe recommends handling the `payment_intent.succeeded`, `payment_intent.processing`, and `payment_intent.payment_failed` events.

        Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.
      </CodeFocusSection>

      ### ❺ Test the integration

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={91} title="Run the application">
        Run your PHP server and go to `localhost:4242/checkout.html`.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        php -S 127.0.0.1:4242 --docroot=public
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={91} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={91} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="public/create.php" linesStart={8} linesEnd={25} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={74} linesEnd={77} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Send an email receipt

      Stripe can send an email receipt to your customer using your brand logo and colour theme, which are configurable in the Dashboard.

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={15} linesEnd={15} title="Collect the customer's email address">
        Add an input field to your payment form to collect the email address.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={46} linesEnd={46} title="Provide the email address to Stripe">
        Pass the provided email address as the `receipt_email` value. Stripe sends an email receipt when the payment succeeds in live mode (but won't send one in a sandbox).
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="public/create.php" linesStart={49} linesEnd={59} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={65} linesEnd={66} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="charge.php" linesStart={14} linesEnd={28} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={41} title="Collect billing address details">
        By default, the Payment Element only collects the necessary billing address details. To collect a customer's full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={41} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={41} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={41} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="js-html-python" label="HTML + Python">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-checkout-prebuilt-subscription/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-checkout-prebuilt-subscription" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="server.py" linesStart={7} linesEnd={10} title="Install the Stripe Python package">
        Install the Stripe package and import it in your code. Alternatively, if you're starting from scratch and need a requirements.txt file, download the project files using the link in the code editor.

        **pip:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        pip3 install stripe
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={90} linesEnd={117} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={102} linesEnd={104} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout page on the client

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={9} linesEnd={9} title="Load Stripe.js">
        Use Stripe.js to remain PCI compliant by ensuring that payment details are sent directly to Stripe without hitting your server. Always load Stripe.js from `js.stripe.com` to remain compliant. Don't include the script in a bundle or host it yourself.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={14} linesEnd={24} title="Define the payment form">
        Add one empty placeholder `div` to your checkout form for each Element that you'll mount. Stripe inserts an iframe into each `div` to securely collect the customer's email address and payment information.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={2} linesEnd={2} title="Initialize Stripe.js">
        Initialize Stripe.js with your publishable API key. You'll use Stripe.js to create the Payment Element and complete the payment on the client.

        **Note:** This is a public sample test API key. Don't submit any personally identifiable information in requests made with this key.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={15} linesEnd={35} title="Fetch a PaymentIntent">
        Immediately make a request to the endpoint on your server to create a new PaymentIntent as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={27} linesEnd={27} title="Initialize Stripe Elements">
        Initialize the Stripe Elements UI library with the client secret. Elements manages the UI components you need to collect payment details.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={33} linesEnd={34} title="Create the PaymentElement">
        Create a `PaymentElement` and mount it to the placeholder `<div>` in your payment form. This embeds an iframe with a dynamic form that displays configured payment method types available from the PaymentIntent, allowing your customer to select a payment method. The form automatically collects the associated payment details for the selected payment method type.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={37} linesEnd={62} title="Handle the submit event">
        Listen to the form's submit event to know when to confirm the payment through the Stripe API.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={41} linesEnd={48} title="Complete the payment">
        Call `confirmPayment` with the Element instance and a `return_url` to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for 3D Secure authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={50} linesEnd={59} title="Handle errors">
        If there are any immediate errors (for example, your customer's card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/complete.js" linesStart={72} linesEnd={86} title="Show a payment status message">
        When Stripe redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by Stripe.js. Use this to retrieve the PaymentIntent status update and determine what to show to your customer.
      </CodeFocusSection>

      ### ❹ Handle post-payment events

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Use a webhook">
        Stripe sends multiple events during the payment process and after the payment is complete. Create an event destination for a webhook endpoint to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow. Stripe recommends handling the `payment_intent.succeeded`, `payment_intent.processing`, and `payment_intent.payment_failed` events.

        Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.
      </CodeFocusSection>

      ### ❺ Test the integration

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Run the application">
        Run your Python server and go to `localhost:4242/checkout.html`.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        python3 -m flask run --port=4242
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.py" linesStart={92} linesEnd={99} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={105} linesEnd={111} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Send an email receipt

      Stripe can send an email receipt to your customer using your brand logo and colour theme, which are configurable in the Dashboard.

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={15} linesEnd={15} title="Collect the customer's email address">
        Add an input field to your payment form to collect the email address.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={46} linesEnd={46} title="Provide the email address to Stripe">
        Pass the provided email address as the `receipt_email` value. Stripe sends an email receipt when the payment succeeds in live mode (but won't send one in a sandbox).
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.py" linesStart={80} linesEnd={89} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={97} linesEnd={98} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={54} linesEnd={75} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Collect billing address details">
        By default, the Payment Element only collects the necessary billing address details. To collect a customer's full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="js-html-go" label="HTML + Go">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-checkout-prebuilt-subscription-go/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-checkout-prebuilt-subscription-go" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="server.go" linesStart={17} linesEnd={19} title="Set up your server">
        Add the dependency to your build and import the library. Alternatively, if you're starting from scratch and need a go.mod file, download the project files using the link in the code editor.

        **Go:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        go get -u github.com/stripe/stripe-go/v84
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={144} linesEnd={177} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={150} linesEnd={153} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout page on the client

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={9} linesEnd={9} title="Load Stripe.js">
        Use Stripe.js to remain PCI compliant by ensuring that payment details are sent directly to Stripe without hitting your server. Always load Stripe.js from `js.stripe.com` to remain compliant. Don't include the script in a bundle or host it yourself.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={14} linesEnd={24} title="Define the payment form">
        Add one empty placeholder `div` to your checkout form for each Element that you'll mount. Stripe inserts an iframe into each `div` to securely collect the customer's email address and payment information.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={2} linesEnd={2} title="Initialize Stripe.js">
        Initialize Stripe.js with your publishable API key. You'll use Stripe.js to create the Payment Element and complete the payment on the client.

        **Note:** This is a public sample test API key. Don't submit any personally identifiable information in requests made with this key.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={15} linesEnd={35} title="Fetch a PaymentIntent">
        Immediately make a request to the endpoint on your server to create a new PaymentIntent as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={27} linesEnd={27} title="Initialize Stripe Elements">
        Initialize the Stripe Elements UI library with the client secret. Elements manages the UI components you need to collect payment details.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={33} linesEnd={34} title="Create the PaymentElement">
        Create a `PaymentElement` and mount it to the placeholder `<div>` in your payment form. This embeds an iframe with a dynamic form that displays configured payment method types available from the PaymentIntent, allowing your customer to select a payment method. The form automatically collects the associated payment details for the selected payment method type.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={37} linesEnd={62} title="Handle the submit event">
        Listen to the form's submit event to know when to confirm the payment through the Stripe API.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={41} linesEnd={48} title="Complete the payment">
        Call `confirmPayment` with the Element instance and a `return_url` to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for 3D Secure authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={50} linesEnd={59} title="Handle errors">
        If there are any immediate errors (for example, your customer's card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/complete.js" linesStart={72} linesEnd={86} title="Show a payment status message">
        When Stripe redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by Stripe.js. Use this to retrieve the PaymentIntent status update and determine what to show to your customer.
      </CodeFocusSection>

      ### ❹ Handle post-payment events

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={192} title="Use a webhook">
        Stripe sends multiple events during the payment process and after the payment is complete. Create an event destination for a webhook endpoint to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow. Stripe recommends handling the `payment_intent.succeeded`, `payment_intent.processing`, and `payment_intent.payment_failed` events.

        Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.
      </CodeFocusSection>

      ### ❺ Test the integration

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={192} title="Run the application">
        Run your Go server and go to `localhost:4242/checkout.html`.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        go run server.go
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={192} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={192} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.go" linesStart={148} linesEnd={148} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={156} linesEnd={163} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Send an email receipt

      Stripe can send an email receipt to your customer using your brand logo and colour theme, which are configurable in the Dashboard.

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={15} linesEnd={15} title="Collect the customer's email address">
        Add an input field to your payment form to collect the email address.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={46} linesEnd={46} title="Provide the email address to Stripe">
        Pass the provided email address as the `receipt_email` value. Stripe sends an email receipt when the payment succeeds in live mode (but won't send one in a sandbox).
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.go" linesStart={11} linesEnd={12} title="Import additional Stripe resources">
        Import the Stripe customer and paymentmethod packages. Use these packages to store information about your customer.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={126} linesEnd={139} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={146} linesEnd={147} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={74} linesEnd={109} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={192} title="Collect billing address details">
        By default, the Payment Element only collects the necessary billing address details. To collect a customer's full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={192} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={192} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={192} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="js-html-net" label="HTML + .NET">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-checkout-prebuilt-subscription-net/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-checkout-prebuilt-subscription-net" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="Server.cs" linesStart={34} linesEnd={56} title="Install the Stripe.net library">
        Install the package with .NET or NuGet. Alternatively, if you're starting from scratch, download the files which contains a configured .csproj file.

        **dotnet:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        dotnet add package Stripe.net
        ```

        **NuGet:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        Install-Package Stripe.net
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={82} linesEnd={99} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={88} linesEnd={92} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout page on the client

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={9} linesEnd={9} title="Load Stripe.js">
        Use Stripe.js to remain PCI compliant by ensuring that payment details are sent directly to Stripe without hitting your server. Always load Stripe.js from `js.stripe.com` to remain compliant. Don't include the script in a bundle or host it yourself.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={14} linesEnd={24} title="Define the payment form">
        Add one empty placeholder `div` to your checkout form for each Element that you'll mount. Stripe inserts an iframe into each `div` to securely collect the customer's email address and payment information.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={2} linesEnd={2} title="Initialize Stripe.js">
        Initialize Stripe.js with your publishable API key. You'll use Stripe.js to create the Payment Element and complete the payment on the client.

        **Note:** This is a public sample test API key. Don't submit any personally identifiable information in requests made with this key.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={15} linesEnd={35} title="Fetch a PaymentIntent">
        Immediately make a request to the endpoint on your server to create a new PaymentIntent as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={27} linesEnd={27} title="Initialize Stripe Elements">
        Initialize the Stripe Elements UI library with the client secret. Elements manages the UI components you need to collect payment details.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={33} linesEnd={34} title="Create the PaymentElement">
        Create a `PaymentElement` and mount it to the placeholder `<div>` in your payment form. This embeds an iframe with a dynamic form that displays configured payment method types available from the PaymentIntent, allowing your customer to select a payment method. The form automatically collects the associated payment details for the selected payment method type.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={37} linesEnd={62} title="Handle the submit event">
        Listen to the form's submit event to know when to confirm the payment through the Stripe API.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={41} linesEnd={48} title="Complete the payment">
        Call `confirmPayment` with the Element instance and a `return_url` to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for 3D Secure authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={50} linesEnd={59} title="Handle errors">
        If there are any immediate errors (for example, your customer's card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/complete.js" linesStart={72} linesEnd={86} title="Show a payment status message">
        When Stripe redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by Stripe.js. Use this to retrieve the PaymentIntent status update and determine what to show to your customer.
      </CodeFocusSection>

      ### ❹ Handle post-payment events

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={203} title="Use a webhook">
        Stripe sends multiple events during the payment process and after the payment is complete. Create an event destination for a webhook endpoint to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow. Stripe recommends handling the `payment_intent.succeeded`, `payment_intent.processing`, and `payment_intent.payment_failed` events.

        Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.
      </CodeFocusSection>

      ### ❺ Test the integration

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={203} title="Run the application">
        Run your ASP.NET MVC server and go to `localhost:4242/checkout.html`.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        dotnet run
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={203} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={203} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="Server.cs" linesStart={102} linesEnd={147} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={93} linesEnd={96} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Send an email receipt

      Stripe can send an email receipt to your customer using your brand logo and colour theme, which are configurable in the Dashboard.

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={15} linesEnd={15} title="Collect the customer's email address">
        Add an input field to your payment form to collect the email address.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={46} linesEnd={46} title="Provide the email address to Stripe">
        Pass the provided email address as the `receipt_email` value. Stripe sends an email receipt when the payment succeeds in live mode (but won't send one in a sandbox).
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="Server.cs" linesStart={60} linesEnd={78} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={84} linesEnd={85} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={149} linesEnd={187} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={203} title="Collect billing address details">
        By default, the Payment Element only collects the necessary billing address details. To collect a customer's full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={203} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={203} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={203} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="js-html-java" label="HTML + Java">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-checkout-prebuilt-subscription-java/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-checkout-prebuilt-subscription-java" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={137} linesEnd={142} title="Install the Stripe Java library">
        Add the dependency to your build and import the library. Alternatively, if you're starting from scratch and need a sample pom.xml file (for Maven), download the project files using the link in the code editor.

        **Maven:**

        ```xml theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        <dependency>
          <groupId>com.stripe</groupId>
          <artifactId>stripe-java</artifactId>
          <version>{VERSION}</version>
        </dependency>
        ```

        **Gradle:**

        ```gradle theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation "com.stripe:stripe-java:{VERSION}"
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={170} linesEnd={210} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={181} linesEnd={187} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout page on the client

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={9} linesEnd={9} title="Load Stripe.js">
        Use Stripe.js to remain PCI compliant by ensuring that payment details are sent directly to Stripe without hitting your server. Always load Stripe.js from `js.stripe.com` to remain compliant. Don't include the script in a bundle or host it yourself.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={14} linesEnd={24} title="Define the payment form">
        Add one empty placeholder `div` to your checkout form for each Element that you'll mount. Stripe inserts an iframe into each `div` to securely collect the customer's email address and payment information.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={2} linesEnd={2} title="Initialize Stripe.js">
        Initialize Stripe.js with your publishable API key. You'll use Stripe.js to create the Payment Element and complete the payment on the client.

        **Note:** This is a public sample test API key. Don't submit any personally identifiable information in requests made with this key.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={15} linesEnd={35} title="Fetch a PaymentIntent">
        Immediately make a request to the endpoint on your server to create a new PaymentIntent as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={27} linesEnd={27} title="Initialize Stripe Elements">
        Initialize the Stripe Elements UI library with the client secret. Elements manages the UI components you need to collect payment details.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={33} linesEnd={34} title="Create the PaymentElement">
        Create a `PaymentElement` and mount it to the placeholder `<div>` in your payment form. This embeds an iframe with a dynamic form that displays configured payment method types available from the PaymentIntent, allowing your customer to select a payment method. The form automatically collects the associated payment details for the selected payment method type.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={37} linesEnd={62} title="Handle the submit event">
        Listen to the form's submit event to know when to confirm the payment through the Stripe API.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={41} linesEnd={48} title="Complete the payment">
        Call `confirmPayment` with the Element instance and a `return_url` to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for 3D Secure authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={50} linesEnd={59} title="Handle errors">
        If there are any immediate errors (for example, your customer's card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/complete.js" linesStart={72} linesEnd={86} title="Show a payment status message">
        When Stripe redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by Stripe.js. Use this to retrieve the PaymentIntent status update and determine what to show to your customer.
      </CodeFocusSection>

      ### ❹ Handle post-payment events

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={1} linesEnd={213} title="Use a webhook">
        Stripe sends multiple events during the payment process and after the payment is complete. Create an event destination for a webhook endpoint to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow. Stripe recommends handling the `payment_intent.succeeded`, `payment_intent.processing`, and `payment_intent.payment_failed` events.

        Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.
      </CodeFocusSection>

      ### ❺ Test the integration

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={1} linesEnd={213} title="Run the application">
        Run your server and go to `localhost:4242/checkout.html`.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        java -cp target/sample-jar-with-dependencies.jar com.stripe.sample.Server
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={1} linesEnd={213} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={1} linesEnd={213} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={172} linesEnd={179} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={188} linesEnd={203} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Send an email receipt

      Stripe can send an email receipt to your customer using your brand logo and colour theme, which are configurable in the Dashboard.

      <CodeFocusSection activeFilePath="public/checkout.html" linesStart={15} linesEnd={15} title="Collect the customer's email address">
        Add an input field to your payment form to collect the email address.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/checkout.js" linesStart={46} linesEnd={46} title="Provide the email address to Stripe">
        Pass the provided email address as the `receipt_email` value. Stripe sends an email receipt when the payment succeeds in live mode (but won't send one in a sandbox).
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={25} linesEnd={27} title="Import additional Stripe resources">
        Import the Stripe PaymentMethod and Customer models. Use these models to store information about your Customer.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={146} linesEnd={169} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={177} linesEnd={178} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={111} linesEnd={134} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={1} linesEnd={213} title="Collect billing address details">
        By default, the Payment Element only collects the necessary billing address details. To collect a customer's full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={1} linesEnd={213} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={1} linesEnd={213} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={1} linesEnd={213} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="js-react-ruby" label="React + Ruby">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-js-react-ruby/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-js-react-ruby" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="Gemfile" linesStart={1} linesEnd={4} title="Install the Stripe Ruby library">
        Install the Stripe ruby gem and require it in your code. Alternatively, if you're starting from scratch and need a Gemfile, download the project files using the link in the code editor.

        **Terminal:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        gem install stripe
        ```

        **Bundler (add to Gemfile):**

        ```ruby theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        gem 'stripe'
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={67} linesEnd={104} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={88} linesEnd={91} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout page on the client

      <CodeFocusSection activeFilePath="package.json" linesStart={5} linesEnd={11} title="Add Stripe to your React app">
        Use the Stripe.js and the Stripe Elements UI library to stay PCI compliant by ensuring that payment details go directly to Stripe and never reach your server.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm install --save @stripe/react-stripe-js @stripe/stripe-js
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={14} linesEnd={17} title="Load Stripe.js">
        Call `loadStripe()` with your Stripe publishable API key to configure the Stripe library.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={22} linesEnd={31} title="Fetch a PaymentIntent">
        Immediately make a request to the endpoint on your server to create a new PaymentIntent as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={39} linesEnd={52} title="Initialize Stripe Elements">
        Pass the resulting promise from `loadStripe` to the Elements provider. This allows the child components to access the Stripe service with the Elements consumer. Additionally, pass the client secret as an option to the Elements provider.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={12} linesEnd={15} title="Set up the state">
        Initialize some state to keep track of the payment, show errors, and manage the user interface.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={8} linesEnd={10} title="Store a reference to Stripe">
        Access the Stripe library in your CheckoutForm component by using the `useStripe()` and `useElements()` hooks. If you need to access Elements with a class component, use the ElementsConsumer instead.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={55} linesEnd={73} title="Add the PaymentElement">
        Add PaymentElement to your payment form. It embeds an iframe with a dynamic form that collects payment details for a variety of payment methods. Your customer can pick a payment method type, and the form automatically collects all necessary payments details for their selection.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={33} linesEnd={37} title="(Optional) Style the Payment Element">
        Customise the Payment Element UI by creating an Appearance object and passing it as an option to the Elements provider. Use your company's colour scheme and font to make it match with the rest of your checkout page.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={17} linesEnd={49} title="Complete the payment">
        When your customer clicks the pay button, call `confirmPayment` with the PaymentElement and pass a `return_url` to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for 3D Secure authentication or redirects the customer to an authentication page, depending on the payment method.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={42} linesEnd={46} title="Handle errors">
        If there are any immediate errors (for example, your customer's card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CompletePage.jsx" linesStart={47} linesEnd={105} title="Show a payment status message">
        When Stripe redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by Stripe.js. Use this to retrieve the PaymentIntent status update and determine what to show to your customer.
      </CodeFocusSection>

      ### ❹ Handle post-payment events

      <CodeFocusSection activeFilePath="server.rb" linesStart={67} linesEnd={104} title="Use a webhook">
        Stripe sends multiple events during the payment process and after the payment is complete. Create an event destination for a webhook endpoint to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow. Stripe recommends handling the `payment_intent.succeeded`, `payment_intent.processing`, and `payment_intent.payment_failed` events.

        Listen for these events rather than waiting for a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response.
      </CodeFocusSection>

      ### ❺ Test the integration

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={8} title="Run the server application">
        Run the React app and the server. Go to localhost:3000/checkout to see your checkout page.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        ruby server.rb
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="package.json" linesStart={15} linesEnd={19} title="Run the application">
        Run the React app and go to localhost:3000/checkout.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm start
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={1} linesEnd={75} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.rb" linesStart={9} linesEnd={24} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={92} linesEnd={98} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Send an email receipt

      Stripe can send an email receipt to your customer using your brand logo and colour theme, which are configurable in the Dashboard.

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={57} linesEnd={63} title="Collect the customer's email address">
        Add an input field to your payment form to collect the email address.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={12} linesEnd={12} title="Add email to the state">
        Add a variable to keep track of the email the customer enters.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={28} linesEnd={35} title="Provide the email address to Stripe">
        Pass the provided email address as the `receipt_email` value. Stripe sends an email receipt when the payment succeeds in live mode (but won't send one in a sandbox).
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.rb" linesStart={72} linesEnd={78} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={83} linesEnd={86} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={41} linesEnd={64} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Collect billing address details">
        By default, the Payment Element only collects the necessary billing address details. To collect a customer's full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="js-react-nodejs" label="React + Node.js">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-js-react-nodejs/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-js-react-nodejs" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={4} title="Install the Stripe Node library">
        Install the package and import it in your code. Alternatively, if you're starting from scratch and need a package.json file, download the project files using the Download link in the code editor.

        **npm:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm install --save stripe
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={66} linesEnd={106} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={91} linesEnd={93} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout page on the client

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={1} linesEnd={3} title="Add Stripe to your React app">
        Use the Stripe.js and the Stripe Elements UI library to stay PCI compliant by ensuring that payment details go directly to Stripe and never reach your server.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm install --save @stripe/react-stripe-js @stripe/stripe-js
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={14} linesEnd={17} title="Load Stripe.js">
        Call `loadStripe()` with your Stripe publishable API key to configure the Stripe library.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={22} linesEnd={31} title="Fetch a PaymentIntent">
        Immediately make a request to the endpoint on your server to create a new PaymentIntent as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={39} linesEnd={51} title="Initialize Stripe Elements">
        Pass the resulting promise from `loadStripe` to the Elements provider. This allows the child components to access the Stripe service with the Elements consumer. Additionally, pass the client secret as an option to the Elements provider.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={12} linesEnd={15} title="Set up the state">
        Initialize some state to keep track of the payment, show errors, and manage the user interface.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={8} linesEnd={10} title="Store a reference to Stripe">
        Access the Stripe library in your CheckoutForm component by using the `useStripe()` and `useElements()` hooks. If you need to access Elements with a class component, use the ElementsConsumer instead.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={55} linesEnd={74} title="Add the PaymentElement">
        Add `PaymentElement` to your payment form. It embeds an iframe with a dynamic form that collects payment details for a variety of payment methods. Your customer can pick a payment method type, and the form automatically collects all necessary payments details for their selection.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={33} linesEnd={37} title="(Optional) Style the Payment Element">
        Customise the Payment Element UI by creating an `Appearance` object and passing it as an option to the Elements provider. Use your company's colour scheme and font to make it match with the rest of your checkout page. Use custom fonts (for example, from Google Fonts) by initialising Elements with a font set.

        **Make sure to open the preview on the right to see your changes live.**
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={28} linesEnd={35} title="Complete the payment">
        When your customer clicks the pay button, call `confirmPayment` with the PaymentElement and pass a `return_url` to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for 3D Secure authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={37} linesEnd={48} title="Handle errors">
        If there are any immediate errors (for example, your customer's card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CompletePage.jsx" linesStart={47} linesEnd={104} title="Show a payment status message">
        When Stripe redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by Stripe.js. Use this to retrieve the PaymentIntent status update and determine what to show to your customer.
      </CodeFocusSection>

      ### ❹ Handle post-payment events

      <CodeFocusSection activeFilePath="server.js" linesStart={66} linesEnd={106} title="Use a webhook">
        Stripe sends multiple events during the payment process and after the payment is complete. Create an event destination for a webhook endpoint to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow. Stripe recommends handling the `payment_intent.succeeded`, `payment_intent.processing`, and `payment_intent.payment_failed` events.

        Listen for these events rather than waiting for a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.
      </CodeFocusSection>

      ### ❺ Test the integration

      <CodeFocusSection activeFilePath="server.js" linesStart={110} linesEnd={110} title="Run the application">
        Run the React app and the server. Go to localhost:3000/checkout to see your checkout page.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm start
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.js" linesStart={9} linesEnd={26} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={94} linesEnd={100} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Send an email receipt

      Stripe can send an email receipt to your customer using your brand logo and colour theme, which are configurable in the Dashboard.

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={57} linesEnd={63} title="Collect the customer's email address">
        Add an input field to your payment form to collect the email address.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={12} linesEnd={12} title="Add email to the state">
        Add a variable to keep track of the email the customer enters.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={28} linesEnd={35} title="Provide the email address to Stripe">
        Pass the provided email address as the `receipt_email` value. Stripe sends an email receipt when the payment succeeds in live mode (but won't send one in a sandbox).
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.js" linesStart={70} linesEnd={78} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={86} linesEnd={87} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={42} linesEnd={64} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={1} linesEnd={75} title="Collect billing address details">
        By default, the Payment Element only collects the necessary billing address details. To collect a customer's full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="js-react-php" label="React + PHP">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-js-react-php/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-js-react-php" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="composer.json" linesStart={1} linesEnd={7} title="Install the Stripe PHP library">
        Install the library with composer and initialize with your secret API key. Alternatively, if you're starting from scratch and need a composer.json file, download the files using the link in the code editor.

        **Composer:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        composer require stripe/stripe-php
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={64} linesEnd={80} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={70} linesEnd={72} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout page on the client

      <CodeFocusSection activeFilePath="package.json" linesStart={5} linesEnd={7} title="Add Stripe to your React app">
        Use the Stripe.js and the Stripe Elements UI library to stay PCI compliant by ensuring that payment details go directly to Stripe and never reach your server.

        **npm:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm install --save @stripe/react-stripe-js @stripe/stripe-js
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={14} linesEnd={17} title="Load Stripe.js">
        Call `loadStripe()` with your Stripe publishable API key to configure the Stripe library.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={22} linesEnd={31} title="Fetch a PaymentIntent">
        Immediately make a request to the endpoint on your server to create a new PaymentIntent as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={39} linesEnd={49} title="Initialize Stripe Elements">
        Pass the resulting promise from `loadStripe` to the Elements provider. This allows the child components to access the Stripe service with the Elements consumer. Additionally, pass the client secret as an option to the Elements provider.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={12} linesEnd={15} title="Set up the state">
        Initialize some state to keep track of the payment, show errors, and manage the user interface.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={8} linesEnd={10} title="Store a reference to Stripe">
        Access the Stripe library in your CheckoutForm component by using the `useStripe()` and `useElements()` hooks. If you need to access Elements with a class component, use the ElementsConsumer instead.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={55} linesEnd={73} title="Add the PaymentElement">
        Add `PaymentElement` to your payment form. It embeds an iframe with a dynamic form that collects payment details for a variety of payment methods. Your customer can pick a payment method type, and the form automatically collects all necessary payments details for their selection.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={33} linesEnd={37} title="(Optional) Style the Payment Element">
        Customise the Payment Element UI by creating an Appearance object and passing it as an option to the Elements provider. Use your company's colour scheme and font to make it match with the rest of your checkout page. Use custom fonts (for example, from Google Fonts) by initialising Elements with a font set.

        **Note:** Parts of the preview demo might not match your actual checkout page. The above settings represent only a subset of the Appearance object's variables and the Appearance object only controls certain attributes of Stripe Elements. You're responsible for styling the rest of your checkout page.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={28} linesEnd={35} title="Complete the payment">
        When your customer clicks the pay button, call `confirmPayment` with the PaymentElement and pass a `return_url` to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for 3D Secure authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={42} linesEnd={48} title="Handle errors">
        If there are any immediate errors (for example, your customer's card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CompletePage.jsx" linesStart={53} linesEnd={74} title="Show a payment status message">
        When Stripe redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by Stripe.js. Use this to retrieve the PaymentIntent status update and determine what to show to your customer.
      </CodeFocusSection>

      ### ❹ Handle post-payment events

      <CodeFocusSection activeFilePath="public/create.php" linesStart={42} linesEnd={90} title="Use a webhook">
        Stripe sends multiple events during the payment process and after the payment is complete. Create an event destination for a webhook endpoint to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow. Stripe recommends handling the `payment_intent.succeeded`, `payment_intent.processing`, and `payment_intent.payment_failed` events.

        Listen for these events rather than waiting for a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.
      </CodeFocusSection>

      ### ❺ Test the integration

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={92} title="Run the server application">
        Run the React app and the server. Go to `localhost:3000/checkout` to see your checkout page.

        **Terminal:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        php -S 127.0.0.1:4242 --docroot=public
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={1} linesEnd={53} title="Run the application">
        Run the React app and go to `localhost:3000/checkout`.

        **Terminal:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm start
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={1} linesEnd={75} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CompletePage.jsx" linesStart={76} linesEnd={105} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="public/create.php" linesStart={8} linesEnd={25} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={73} linesEnd={79} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Send an email receipt

      Stripe can send an email receipt to your customer using your brand logo and colour theme, which are configurable in the Dashboard.

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={57} linesEnd={63} title="Collect the customer's email address">
        Add an input field to your payment form to collect the email address.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={12} linesEnd={12} title="Add email to the state">
        Add a variable to keep track of the email the customer enters.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={30} linesEnd={34} title="Provide the email address to Stripe">
        Pass the provided email address as the `receipt_email` value. Stripe sends an email receipt when the payment succeeds in live mode (but won't send one in a sandbox).
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="public/create.php" linesStart={49} linesEnd={59} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={65} linesEnd={66} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="charge.php" linesStart={21} linesEnd={28} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      ### Next steps

      #### Collect billing address details

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={65} linesEnd={65} title="Collect billing address details">
        By default, the Payment Element only collects the necessary billing address details. To collect a customer's full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={92} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={92} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={92} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="js-react-python" label="React + Python">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-js-react-python/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-js-react-python" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="server.py" linesStart={5} linesEnd={7} title="Install the Stripe Python package">
        Install the Stripe package and import it in your code. Alternatively, if you're starting from scratch and need a requirements.txt file, download the project files using the link in the code editor.

        **pip:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        pip3 install stripe
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={78} linesEnd={117} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={101} linesEnd={104} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout page on the client

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={1} linesEnd={12} title="Add Stripe to your React app">
        Use the Stripe.js and the Stripe Elements UI library to stay PCI compliant by ensuring that payment details go directly to Stripe and never reach your server.

        **npm:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm install --save @stripe/react-stripe-js @stripe/stripe-js
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={14} linesEnd={17} title="Load Stripe.js">
        Call `loadStripe()` with your Stripe publishable API key to configure the Stripe library.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={22} linesEnd={31} title="Fetch a PaymentIntent">
        Immediately make a request to the endpoint on your server to create a new PaymentIntent as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={39} linesEnd={52} title="Initialize Stripe Elements">
        Pass the resulting promise from `loadStripe` to the Elements provider. This allows the child components to access the Stripe service with the Elements consumer. Additionally, pass the client secret as an option to the Elements provider.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={12} linesEnd={15} title="Set up the state">
        Initialize some state to keep track of the payment, show errors, and manage the user interface.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={8} linesEnd={10} title="Store a reference to Stripe">
        Access the Stripe library in your CheckoutForm component by using the `useStripe()` and `useElements()` hooks. If you need to access Elements with a class component, use the ElementsConsumer instead.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={55} linesEnd={73} title="Add the PaymentElement">
        Add `PaymentElement` to your payment form. It embeds an iframe with a dynamic form that collects payment details for a variety of payment methods. Your customer can pick a payment method type, and the form automatically collects all necessary payments details for their selection.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={33} linesEnd={37} title="(Optional) Style the Payment Element">
        Customise the Payment Element UI by creating an Appearance object and passing it as an option to the Elements provider. Use your company's colour scheme and font to make it match with the rest of your checkout page. Use custom fonts (for example, from Google Fonts) by initialising Elements with a font set.

        **Note:** Parts of the preview demo might not match your actual checkout page. The above settings represent only a subset of the Appearance object's variables and the Appearance object only controls certain attributes of Stripe Elements. You're responsible for styling the rest of your checkout page.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={17} linesEnd={35} title="Complete the payment">
        When your customer clicks the pay button, call `confirmPayment` with the PaymentElement and pass a `return_url` to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for 3D Secure authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={42} linesEnd={48} title="Handle errors">
        If there are any immediate errors (for example, your customer's card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CompletePage.jsx" linesStart={47} linesEnd={104} title="Show a payment status message">
        When Stripe redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by Stripe.js. Use this to retrieve the PaymentIntent status update and determine what to show to your customer.
      </CodeFocusSection>

      ### ❹ Handle post-payment events

      <CodeFocusSection activeFilePath="server.py" linesStart={78} linesEnd={117} title="Use a webhook">
        Stripe sends multiple events during the payment process and after the payment is complete. Create an event destination for a webhook endpoint to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow. Stripe recommends handling the `payment_intent.succeeded`, `payment_intent.processing`, and `payment_intent.payment_failed` events.

        Listen for these events rather than waiting for a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.
      </CodeFocusSection>

      ### ❺ Test the integration

      <CodeFocusSection activeFilePath="server.py" linesStart={119} linesEnd={120} title="Run the server application">
        Run the React app and the server. Go to `localhost:3000/checkout` to see your checkout page.

        **Terminal:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        python3 -m flask run --port=4242
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/index.js" linesStart={1} linesEnd={10} title="Run the application">
        Run the React app and go to `localhost:3000/checkout`.

        **Terminal:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm start
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.py" linesStart={18} linesEnd={34} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={105} linesEnd={111} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Send email receipts

      Stripe can send an email receipt to your customer using your brand logo and colour theme, which are configurable in the Dashboard.

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={57} linesEnd={63} title="Collect the customer's email address">
        Add an input field to your payment form to collect the email address.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={12} linesEnd={12} title="Add email to the state">
        Add a variable to keep track of the email the customer enters.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={28} linesEnd={35} title="Provide the email address to Stripe">
        Pass the provided email address as the `receipt_email` value. Stripe sends an email receipt when the payment succeeds in live mode (but won't send one in a sandbox).
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.py" linesStart={82} linesEnd={88} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={96} linesEnd={98} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={54} linesEnd={76} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Collect billing address details">
        By default, the Payment Element only collects the necessary billing address details. To collect a customer's full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="js-react-go" label="React + Go">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-js-react-go/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-js-react-go" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="go.mod" linesStart={1} linesEnd={6} title="Set up your server">
        Add the dependency to your build and import the library. Alternatively, if you're starting from scratch and need a go.mod file, download the project files using the link in the code editor.

        **Go:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        go get -u github.com/stripe/stripe-go/v84
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={111} linesEnd={178} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={150} linesEnd={154} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout page on the client

      <CodeFocusSection activeFilePath="package.json" linesStart={5} linesEnd={11} title="Add Stripe to your React app">
        Use the Stripe.js and the Stripe Elements UI library to stay PCI compliant by ensuring that payment details go directly to Stripe and never reach your server.

        **npm:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm install --save @stripe/react-stripe-js @stripe/stripe-js
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={1} linesEnd={17} title="Load Stripe.js">
        Call `loadStripe()` with your Stripe publishable API key to configure the Stripe library.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={22} linesEnd={31} title="Fetch a PaymentIntent">
        Immediately make a request to the endpoint on your server to create a new PaymentIntent as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={39} linesEnd={52} title="Initialize Stripe Elements">
        Pass the resulting promise from `loadStripe` to the Elements provider. This allows the child components to access the Stripe service with the Elements consumer. Additionally, pass the client secret as an option to the Elements provider.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={12} linesEnd={15} title="Set up the state">
        Initialize some state to keep track of the payment, show errors, and manage the user interface.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={8} linesEnd={10} title="Store a reference to Stripe">
        Access the Stripe library in your CheckoutForm component by using the `useStripe()` and `useElements()` hooks. If you need to access Elements with a class component, use the ElementsConsumer instead.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={55} linesEnd={73} title="Add the PaymentElement">
        Add `PaymentElement` to your payment form. It embeds an iframe with a dynamic form that collects payment details for a variety of payment methods. Your customer can pick a payment method type, and the form automatically collects all necessary payments details for their selection.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={33} linesEnd={37} title="(Optional) Style the Payment Element">
        Customise the Payment Element UI by creating an Appearance object and passing it as an option to the Elements provider. Use your company's colour scheme and font to make it match with the rest of your checkout page. Use custom fonts (for example, from Google Fonts) by initialising Elements with a font set.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={28} linesEnd={35} title="Complete the payment">
        When your customer clicks the pay button, call `confirmPayment` with the PaymentElement and pass a `return_url` to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for 3D Secure authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they're redirected to the return\_url.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={42} linesEnd={48} title="Handle errors">
        If there are any immediate errors (for example, your customer's card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CompletePage.jsx" linesStart={47} linesEnd={104} title="Show a payment status message">
        When Stripe redirects the customer to the return\_url, the `payment_intent_client_secret` query parameter is appended by Stripe.js. Use this to retrieve the PaymentIntent status update and determine what to show to your customer.
      </CodeFocusSection>

      ### ❹ Handle post-payment events

      <CodeFocusSection activeFilePath="server.go" linesStart={111} linesEnd={178} title="Use a webhook">
        Stripe sends multiple events during the payment process and after the payment is complete. Create an event destination for a webhook endpoint to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow.

        Stripe recommends handling the `payment_intent.succeeded`, `payment_intent.processing`, and `payment_intent.payment_failed` events.

        Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.
      </CodeFocusSection>

      ### ❺ Test the integration

      <CodeFocusSection activeFilePath="server.go" linesStart={19} linesEnd={28} title="Run the server application">
        Run the React app and the server. Go to localhost:3000/checkout to see your checkout page.

        **Run the server:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        go run server.go
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="package.json" linesStart={15} linesEnd={19} title="Run the application">
        Run the React app and go to localhost:3000/checkout.

        **Run the client:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm start
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={192} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={192} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.go" linesStart={35} linesEnd={58} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={156} linesEnd={162} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Send an email receipt

      Stripe can send an email receipt to your customer using your brand logo and colour theme, which are configurable in the Dashboard.

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={57} linesEnd={63} title="Collect the customer's email address">
        Add an input field to your payment form to collect the email address.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={12} linesEnd={12} title="Add email to the state">
        Add a variable to keep track of the email the customer enters.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={28} linesEnd={35} title="Provide the email address to Stripe">
        Pass the provided email address as the `receipt_email` value. Stripe sends an email receipt when the payment succeeds in live mode (but won't send one in a sandbox).
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.go" linesStart={11} linesEnd={14} title="Import additional Stripe resources">
        Import the Stripe customer and paymentmethod packages. Use these packages to store information about your customer.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={128} linesEnd={139} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={145} linesEnd={154} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={74} linesEnd={109} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="README.md" linesStart={1} linesEnd={1} title="Collect billing address details">
        By default, the Payment Element only collects the necessary billing address details. To collect a customer's full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="README.md" linesStart={1} linesEnd={1} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="README.md" linesStart={1} linesEnd={1} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="README.md" linesStart={1} linesEnd={1} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="js-react-net" label="React + .NET">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-js-react-net/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-js-react-net" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="Server.cs" linesStart={29} linesEnd={36} title="Install the Stripe.net library">
        Install the package with .NET or NuGet. Alternatively, if you're starting from scratch, download the files which contains a configured .csproj file.

        **dotnet:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        dotnet add package Stripe.net
        ```

        **NuGet:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        Install-Package Stripe.net
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={82} linesEnd={100} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={88} linesEnd={92} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout page on the client

      <CodeFocusSection activeFilePath="package.json" linesStart={5} linesEnd={7} title="Add Stripe to your React app">
        Use the Stripe.js and the Stripe Elements UI library to stay PCI compliant by ensuring that payment details go directly to Stripe and never reach your server.

        **npm:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm install --save @stripe/react-stripe-js @stripe/stripe-js
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={14} linesEnd={17} title="Load Stripe.js">
        Call `loadStripe()` with your Stripe publishable API key to configure the Stripe library.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={22} linesEnd={31} title="Fetch a PaymentIntent">
        Immediately make a request to the endpoint on your server to create a new PaymentIntent as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={39} linesEnd={49} title="Initialize Stripe Elements">
        Pass the resulting promise from `loadStripe` to the Elements provider. This allows the child components to access the Stripe service with the Elements consumer. Additionally, pass the client secret as an option to the Elements provider.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={12} linesEnd={15} title="Set up the state">
        Initialize some state to keep track of the payment, show errors, and manage the user interface.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={8} linesEnd={10} title="Store a reference to Stripe">
        Access the Stripe library in your CheckoutForm component by using the `useStripe()` and `useElements()` hooks. If you need to access Elements with a class component, use the `ElementsConsumer` instead.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={55} linesEnd={73} title="Add the PaymentElement">
        Add `PaymentElement` to your payment form. It embeds an iframe with a dynamic form that collects payment details for a variety of payment methods. Your customer can pick a payment method type, and the form automatically collects all necessary payments details for their selection.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={33} linesEnd={37} title="(Optional) Style the Payment Element">
        Customise the Payment Element UI by creating an Appearance object and passing it as an option to the Elements provider. Use your company's colour scheme and font to make it match with the rest of your checkout page. Use custom fonts (for example, from Google Fonts) by initialising Elements with a font set.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={17} linesEnd={35} title="Complete the payment">
        When your customer clicks the pay button, call `confirmPayment` with the PaymentElement and pass a `return_url` to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for 3D Secure authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={42} linesEnd={48} title="Handle errors">
        If there are any immediate errors (for example, your customer's card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CompletePage.jsx" linesStart={53} linesEnd={74} title="Show a payment status message">
        When Stripe redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by Stripe.js. Use this to retrieve the PaymentIntent status update and determine what to show to your customer.
      </CodeFocusSection>

      ### ❹ Handle post-payment events

      <CodeFocusSection activeFilePath="Server.cs" linesStart={47} linesEnd={56} title="Use a webhook">
        Stripe sends multiple events during the payment process and after the payment is complete. Create an event destination for a webhook endpoint to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow. Stripe recommends handling the `payment_intent.succeeded`, `payment_intent.processing`, and `payment_intent.payment_failed` events.

        Listen for these events rather than waiting for a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.
      </CodeFocusSection>

      ### ❺ Test the integration

      <CodeFocusSection activeFilePath="Server.cs" linesStart={18} linesEnd={26} title="Run the server application">
        Run the React app and the server. Go to localhost:3000/checkout to see your checkout page.

        **dotnet:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        dotnet run
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="package.json" linesStart={15} linesEnd={16} title="Run the application">
        Run the React app and go to localhost:3000/checkout.

        **npm:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm start
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={1} linesEnd={6} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CompletePage.jsx" linesStart={76} linesEnd={103} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="Server.cs" linesStart={111} linesEnd={136} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={93} linesEnd={97} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Send email receipts

      Stripe can send an email receipt to your customer using your brand logo and colour theme, which are configurable in the Dashboard.

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={57} linesEnd={63} title="Collect the customer's email address">
        Add an input field to your payment form to collect the email address.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={12} linesEnd={12} title="Add email to the state">
        Add a variable to keep track of the email the customer enters.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={28} linesEnd={35} title="Provide the email address to Stripe">
        Pass the provided email address as the `receipt_email` value. Stripe sends an email receipt when the payment succeeds in live mode (but won't send one in a sandbox).
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="Server.cs" linesStart={62} linesEnd={78} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={84} linesEnd={85} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={149} linesEnd={187} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={51} linesEnd={53} title="Collect billing address details">
        By default, the Payment Element only collects the necessary billing address details. To collect a customer's full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={27} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={27} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={47} linesEnd={56} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="js-react-java" label="React + Java">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="/guardian/stripe-sandbox/stripe-accept-payments-with-stripe-checkout-js-react-java.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-js-react-java" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="pom.xml" linesStart={33} linesEnd={39} title="Install the Stripe Java library">
        Add the dependency to your build and import the library. Alternatively, if you're starting from scratch and need a sample pom.xml file (for Maven), download the project files using the link in the code editor.

        **Maven:**

        ```xml theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        <dependency>
          <groupId>com.stripe</groupId>
          <artifactId>stripe-java</artifactId>
          <version>{VERSION}</version>
        </dependency>
        ```

        **Gradle:**

        ```gradle theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation "com.stripe:stripe-java:{VERSION}"
        ```

        Add the following dependency to your POM and replace {VERSION} with the version number you want to use.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={144} linesEnd={211} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={182} linesEnd={187} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout page on the client

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={1} linesEnd={3} title="Add Stripe to your React app">
        Use the Stripe.js and the Stripe Elements UI library to stay PCI compliant by ensuring that payment details go directly to Stripe and never reach your server.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm install --save @stripe/react-stripe-js @stripe/stripe-js
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={14} linesEnd={17} title="Load Stripe.js">
        Call `loadStripe()` with your Stripe publishable API key to configure the Stripe library.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={22} linesEnd={31} title="Fetch a PaymentIntent">
        Immediately make a request to the endpoint on your server to create a new PaymentIntent as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={39} linesEnd={52} title="Initialize Stripe Elements">
        Pass the resulting promise from `loadStripe` to the Elements provider. This allows the child components to access the Stripe service with the Elements consumer. Additionally, pass the client secret as an option to the Elements provider.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={12} linesEnd={15} title="Set up the state">
        Initialize some state to keep track of the payment, show errors, and manage the user interface.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={8} linesEnd={10} title="Store a reference to Stripe">
        Access the Stripe library in your CheckoutForm component by using the `useStripe()` and `useElements()` hooks. If you need to access Elements with a class component, use the `ElementsConsumer` instead.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={55} linesEnd={73} title="Add the PaymentElement">
        Add `PaymentElement` to your payment form. It embeds an iframe with a dynamic form that collects payment details for a variety of payment methods. Your customer can pick a payment method type, and the form automatically collects all necessary payments details for their selection.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={33} linesEnd={37} title="(Optional) Style the Payment Element">
        Customise the Payment Element UI by creating an `Appearance` object and passing it as an option to the Elements provider. Use your company's colour scheme and font to make it match with the rest of your checkout page. Use custom fonts (for example, from Google Fonts) by initialising Elements with a font set.

        Make sure to open the preview on the right to see your changes live.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={28} linesEnd={35} title="Complete the payment">
        When your customer clicks the pay button, call `confirmPayment` with the PaymentElement and pass a `return_url` to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for 3D Secure authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={42} linesEnd={48} title="Handle errors">
        If there are any immediate errors (for example, your customer's card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CompletePage.jsx" linesStart={53} linesEnd={74} title="Show a payment status message">
        When Stripe redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by Stripe.js. Use this to retrieve the PaymentIntent status update and determine what to show to your customer.
      </CodeFocusSection>

      ### ❹ Handle post-payment events

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={144} linesEnd={211} title="Use a webhook">
        Stripe sends multiple events during the payment process and after the payment is complete. Create an event destination for a webhook endpoint to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow. Stripe recommends handling the `payment_intent.succeeded`, `payment_intent.processing`, and `payment_intent.payment_failed` events.

        Listen for these events rather than waiting for a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.
      </CodeFocusSection>

      ### ❺ Test the integration

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={137} linesEnd={142} title="Run the server application">
        Run the React app and the server. Go to localhost:3000/checkout to see your checkout page.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        java -cp target/sample-jar-with-dependencies.jar com.stripe.sample.Server
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/App.jsx" linesStart={1} linesEnd={53} title="Run the application">
        Run the React app and go to localhost:3000/checkout.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm start
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={137} linesEnd={138} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={1} linesEnd={40} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={75} linesEnd={95} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={188} linesEnd={203} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Send an email receipt

      Stripe can send an email receipt to your customer using your brand logo and colour theme, which are configurable in the Dashboard.

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={57} linesEnd={63} title="Collect the customer's email address">
        Add an input field to your payment form to collect the email address.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={12} linesEnd={12} title="Add email to the state">
        Add a variable to keep track of the email the customer enters.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={30} linesEnd={34} title="Provide the email address to Stripe">
        Pass the provided email address as the `receipt_email` value. Stripe sends an email receipt when the payment succeeds in live mode (but won't send one in a sandbox).
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={23} linesEnd={27} title="Import additional Stripe resources">
        Import the Stripe PaymentMethod and Customer models. Use these models to store information about your Customer.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={148} linesEnd={169} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={177} linesEnd={178} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details. Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={111} linesEnd={134} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="src/CheckoutForm.jsx" linesStart={1} linesEnd={75} title="Collect billing address details">
        By default, the Payment Element only collects the necessary billing address details. To collect a customer's full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={1} linesEnd={40} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={1} linesEnd={40} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={1} linesEnd={40} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="js-nextjs" label="Next.js">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="/guardian/stripe-sandbox/stripe-accept-payments-with-stripe-checkout-js-nextjs.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-js-nextjs" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="package.json" linesStart={8} linesEnd={17} title="Install the Stripe libraries">
        Install the packages and import them in your code. Alternatively, if you're starting from scratch and need a package.json file, download the project files using the link in the code editor.

        **Install the libraries:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm install --save stripe @stripe/stripe-js next
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="app/page.jsx" linesStart={76} linesEnd={88} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="app/page.jsx" linesStart={81} linesEnd={84} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout page on the client

      <CodeFocusSection activeFilePath="package.json" linesStart={8} linesEnd={10} title="Add Stripe to your React app">
        Use the Stripe.js and the Stripe Elements UI library to stay PCI compliant by ensuring that payment details go directly to Stripe and never reach your server.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm install --save @stripe/react-stripe-js @stripe/stripe-js
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="components/checkout.jsx" linesStart={14} linesEnd={15} title="Load Stripe.js">
        Call `loadStripe()` with your Stripe publishable API key to configure the Stripe library.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="components/checkout.jsx" linesStart={85} linesEnd={93} title="Initialize Stripe Elements">
        Pass the resulting promise from `loadStripe` to the Elements provider. This allows the child components to access the Stripe service through the Elements consumer. Additionally, pass the client secret as an option to the Elements provider.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="components/checkout.jsx" linesStart={21} linesEnd={24} title="Set up the state">
        Initialize some state to keep track of the payment, show errors, and manage the user interface.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="components/checkout.jsx" linesStart={18} linesEnd={19} title="Store a reference to Stripe">
        Access the Stripe library in your CheckoutForm component by using the `useStripe()` and `useElements()` hooks. If you need to access Elements through a class component, use the ElementsConsumer instead.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="components/checkout.jsx" linesStart={64} linesEnd={82} title="Add the PaymentElement">
        Add the PaymentElement to your payment form. It embeds an iframe with a dynamic form that collects payment details for a variety of payment methods. Your customer can pick a payment method type, and the form automatically collects all necessary payments details for their selection.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="components/checkout.jsx" linesStart={86} linesEnd={88} title="(Optional) Style the Payment Element">
        Customise the Payment Element UI by creating an Appearance object and passing it as an option to the Elements provider. Use your company's colour scheme and font to make it match with the rest of your checkout page. Use custom fonts (for example, from Google Fonts) by initialising Elements with a font set.

        Make sure to open the preview on the right to see your changes live.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="components/checkout.jsx" linesStart={37} linesEnd={44} title="Complete the payment">
        When your customer clicks the pay button, call `confirmPayment` with the PaymentElement and pass a `return_url` to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for 3D Secure authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="components/checkout.jsx" linesStart={46} linesEnd={57} title="Handle errors">
        If there are any immediate errors (for example, your customer's card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="app/success/page.jsx" linesStart={45} linesEnd={84} title="Show a payment status message">
        When Stripe redirects the customer to the `return_url`, the `payment_intent` query parameter is appended by Stripe.js. Use this to retrieve the PaymentIntent status update and determine what to show to your customer.
      </CodeFocusSection>

      ### ❹ Handle post-payment events

      <CodeFocusSection activeFilePath="app/api/webhooks/route.js" linesStart={1} linesEnd={50} title="Use a webhook">
        Stripe sends multiple events during the payment process and after the payment is complete. Create an event destination for a webhook endpoint to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow. Stripe recommends handling the `payment_intent.succeeded`, `payment_intent.processing`, and `payment_intent.payment_failed` events.

        Listen for these events rather than waiting for a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.
      </CodeFocusSection>

      ### ❺ Test the integration

      <CodeFocusSection activeFilePath="package.json" linesStart={3} linesEnd={6} title="Run the application">
        Run the Next.js app. Go to localhost:3000 to see your checkout page.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm run dev
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="app/page.jsx" linesStart={1} linesEnd={95} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="app/page.jsx" linesStart={1} linesEnd={95} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="app/page.jsx" linesStart={5} linesEnd={22} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="app/page.jsx" linesStart={85} linesEnd={87} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Send an email receipt

      Stripe can send an email receipt to your customer using your brand logo and colour theme, which are configurable in the Dashboard.

      <CodeFocusSection activeFilePath="components/checkout.jsx" linesStart={66} linesEnd={72} title="Collect the customer's email address">
        Add an input field to your payment form to collect the email address.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="components/checkout.jsx" linesStart={21} linesEnd={21} title="Add email to the state">
        Add a variable to keep track of the email the customer enters.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="components/checkout.jsx" linesStart={42} linesEnd={42} title="Provide the email address to Stripe">
        Pass the provided email address as the `receipt_email` value. Stripe sends an email receipt when the payment succeeds in live mode (but won't send one in a sandbox).
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="app/page.jsx" linesStart={67} linesEnd={67} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="app/page.jsx" linesStart={77} linesEnd={78} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="app/page.jsx" linesStart={42} linesEnd={64} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="app/page.jsx" linesStart={1} linesEnd={95} title="Collect billing address details">
        By default, the Payment Element only collects the necessary billing address details. To collect a customer's full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="app/page.jsx" linesStart={1} linesEnd={95} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="app/page.jsx" linesStart={1} linesEnd={95} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="app/api/webhooks/route.js" linesStart={1} linesEnd={50} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>
  </Architecture>

  <Architecture value="iOS SDK" label="iOS SDK">
    <FrameworkGuide framework="ios-swift-ruby" label="Swift + Ruby">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ios-swift-ruby-minimal/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ios-swift-ruby-minimal" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={4} title="Install the Stripe Ruby library">
        Install the Stripe ruby gem and require it in your code. Alternatively, if you're starting from scratch and need a Gemfile, download the project files using the link in the code editor.

        **Terminal:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        gem install stripe
        ```

        **Bundler (add to Gemfile):**

        ```ruby theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        gem 'stripe'
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={67} linesEnd={104} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={88} linesEnd={91} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={1} linesEnd={2} title="Install the SDK">
        The Stripe iOS SDK is open source, fully documented, and compatible with apps supporting iOS 13 or above. Import the Stripe SDK into your checkout screen's View Controller.

        **Swift Package Manager:**

        In Xcode, select File > Add Package Dependencies… and enter `https://github.com/stripe/stripe-ios-spm` as the repository URL. Select the latest version number from our releases page, and add the StripePaymentSheet module to your app's target.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={42} linesEnd={44} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={66} linesEnd={102} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={112} linesEnd={134} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the `PaymentSheet.Configuration` struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={135} linesEnd={145} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.rb" linesStart={9} linesEnd={24} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={92} linesEnd={98} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={118} linesEnd={121} title="Enable delayed payment methods">
        Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={122} linesEnd={125} title="Enable Apple Pay">
        To enable Apple Pay, provide your Apple Pay Merchant ID and your Stripe account's country code.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={121} linesEnd={121} title="Use a custom primary button color">
        Consider using a custom color for the primary button that better matches your brand or app's visual identity.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/Info.plist" linesStart={1} linesEnd={1} title="Enable card scanning">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry. To enable card scanning, set `NSCameraUsageDescription` in your application's Info.plist, and provide a reason for accessing the camera (for example, "To scan cards").

        **Note:** Card scanning is only supported on devices running iOS 13 or higher.
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.rb" linesStart={72} linesEnd={78} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={83} linesEnd={86} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={41} linesEnd={64} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect shipping or billing addresses

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={147} linesEnd={160} title="Collect local and international addresses">
        Collect local and international shipping or billing addresses from your customers.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ios-swift-nodejs" label="Swift + Node.js">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ios-swift-nodejs/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ios-swift-nodejs" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="server.js" linesStart={3} linesEnd={4} title="Install the Stripe Node library">
        Install the package and import it in your code. Alternatively, if you're starting from scratch and need a package.json file, download the project files using the Download link in the code editor.

        **npm:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm install --save stripe
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={66} linesEnd={106} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={91} linesEnd={93} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={1} linesEnd={2} title="Install the SDK">
        The Stripe iOS SDK is open source, fully documented, and compatible with apps supporting iOS 13 or above. Import the Stripe SDK into your checkout screen's View Controller.

        **Swift Package Manager:**

        In Xcode, select File > Add Package Dependencies… and enter `https://github.com/stripe/stripe-ios-spm` as the repository URL. Select the latest version number from our releases page, and add the StripePaymentSheet module to your app's target.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={42} linesEnd={44} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={66} linesEnd={102} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={112} linesEnd={134} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the `PaymentSheet.Configuration` struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={135} linesEnd={145} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.js" linesStart={9} linesEnd={26} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={94} linesEnd={100} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={120} linesEnd={120} title="Enable delayed payment methods">
        Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={122} linesEnd={125} title="Enable Apple Pay">
        To enable Apple Pay, provide your Apple Pay Merchant ID and your Stripe account's country code.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={121} linesEnd={121} title="Customise the primary button colour">
        Consider using a custom color for the primary button that better matches your brand or app's visual identity.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/Info.plist" linesStart={1} linesEnd={8} title="Enable card scanning">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry. To enable card scanning, set `NSCameraUsageDescription` in your application's Info.plist, and provide a reason for accessing the camera (for example, "To scan cards").

        **Note:** Card scanning is only supported on devices running iOS 13 or higher.
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.js" linesStart={70} linesEnd={78} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={86} linesEnd={87} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={42} linesEnd={64} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect shipping or billing addresses

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={9} linesEnd={17} title="Collect local and international addresses">
        Collect local and international shipping or billing addresses from your customers.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ios-swift-php" label="Swift + PHP">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ios-swift-php/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ios-swift-php" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="public/create.php" linesStart={3} linesEnd={6} title="Install the Stripe PHP library">
        Install the library with composer and initialize with your secret API key. Alternatively, if you're starting from scratch and need a composer.json file, download the files using the link in the code editor.

        **Composer:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        composer require stripe/stripe-php
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={64} linesEnd={80} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={69} linesEnd={72} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={1} linesEnd={2} title="Install the SDK">
        The Stripe iOS SDK is open source, fully documented, and compatible with apps supporting iOS 13 or above. Import the Stripe SDK into your checkout screen's View Controller.

        **Swift Package Manager:**

        In Xcode, select File > Add Package Dependencies… and enter `https://github.com/stripe/stripe-ios-spm` as the repository URL. Select the latest version number from our releases page, and add the StripePaymentSheet module to your app's target.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={42} linesEnd={44} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={66} linesEnd={102} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={112} linesEnd={134} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the `PaymentSheet.Configuration` struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={135} linesEnd={145} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={91} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={91} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="public/create.php" linesStart={8} linesEnd={25} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={73} linesEnd={79} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={118} linesEnd={121} title="Enable delayed payment methods">
        Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={122} linesEnd={125} title="Enable Apple Pay">
        To enable Apple Pay, provide your Apple Pay Merchant ID and your Stripe account's country code.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={121} linesEnd={121} title="Use a custom primary button color">
        Consider using a custom color for the primary button that better matches your brand or app's visual identity.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/Info.plist" linesStart={6} linesEnd={7} title="Enable card scanning">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry. To enable card scanning, set `NSCameraUsageDescription` in your application's Info.plist, and provide a reason for accessing the camera (for example, "To scan cards").

        Note: Card scanning is only supported on devices running iOS 13 or higher.
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="public/create.php" linesStart={49} linesEnd={59} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={65} linesEnd={66} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="charge.php" linesStart={14} linesEnd={28} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect shipping or billing addresses

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={147} linesEnd={160} title="Collect local and international addresses">
        Collect local and international shipping or billing addresses from your customers.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={91} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={91} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={91} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ios-swift-python" label="Swift + Python">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ios-swift-python/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ios-swift-python" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="server.py" linesStart={5} linesEnd={7} title="Install the Stripe Python package">
        Install the Stripe package and import it in your code. Alternatively, if you're starting from scratch and need a requirements.txt file, download the project files using the link in the code editor.

        **pip:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        pip3 install stripe
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={78} linesEnd={117} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={101} linesEnd={104} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={1} linesEnd={2} title="Install the SDK">
        The Stripe iOS SDK is open source, fully documented, and compatible with apps supporting iOS 13 or above. Import the Stripe SDK into your checkout screen's View Controller.

        **Swift Package Manager:**

        In Xcode, select File > Add Package Dependencies… and enter `https://github.com/stripe/stripe-ios-spm` as the repository URL. Select the latest version number from our releases page, and add the StripePaymentSheet module to your app's target.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={42} linesEnd={44} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={66} linesEnd={102} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={112} linesEnd={145} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the `PaymentSheet.Configuration` struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={135} linesEnd={144} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Run the application">
        Run your Python server and go to your iOS simulator or device.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        python3 -m flask run --port=4242
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.py" linesStart={18} linesEnd={34} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={105} linesEnd={111} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Delayed payment methods

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={118} linesEnd={120} title="Enable delayed payment methods">
        Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      #### Apple Pay

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={122} linesEnd={125} title="Enable Apple Pay">
        To enable Apple Pay, provide your Apple Pay Merchant ID and your Stripe account's country code.
      </CodeFocusSection>

      #### Custom primary button color

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={121} linesEnd={121} title="Customize the primary button">
        Consider using a custom color for the primary button that better matches your brand or app's visual identity.
      </CodeFocusSection>

      #### Card scanning

      <CodeFocusSection activeFilePath="ios/Info.plist" linesStart={1} linesEnd={9} title="Enable card scanning">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry. To enable card scanning, set `NSCameraUsageDescription` in your application's Info.plist, and provide a reason for accessing the camera (for example, "To scan cards").

        Note: Card scanning is only supported on devices running iOS 13 or higher.
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.py" linesStart={82} linesEnd={88} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={96} linesEnd={98} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={54} linesEnd={76} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect shipping or billing addresses

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={9} linesEnd={17} title="Configure Address Element">
        Collect local and international shipping or billing addresses from your customers.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ios-swift-go" label="Swift + Go">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ios-swift-go/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ios-swift-go" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={6} title="Set up your server">
        Add the dependency to your build and import the library. Alternatively, if you're starting from scratch and need a go.mod file, download the project files using the link in the code editor.

        **Go:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        go get -u github.com/stripe/stripe-go/v84
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={144} linesEnd={177} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={150} linesEnd={153} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={1} linesEnd={2} title="Install the SDK">
        The Stripe iOS SDK is open source, fully documented, and compatible with apps supporting iOS 13 or above. Import the Stripe SDK into your checkout screen's View Controller.

        In Xcode, select File > Add Package Dependencies... and enter [https://github.com/stripe/stripe-ios-spm](https://github.com/stripe/stripe-ios-spm) as the repository URL. Select the latest version number from our releases page, and add the StripePaymentSheet module to your app's target.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={42} linesEnd={44} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={66} linesEnd={102} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={112} linesEnd={145} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the PaymentSheet.Configuration struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={135} linesEnd={144} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={192} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={192} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.go" linesStart={35} linesEnd={58} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={156} linesEnd={162} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Payment customization options

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={120} linesEnd={120} title="Enable delayed payment methods">
        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={122} linesEnd={125} title="Enable Apple Pay">
        Configure Apple Pay by setting the merchant ID and country code in the PaymentSheet configuration.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={121} linesEnd={121} title="Custom primary button color">
        Set a custom color for the primary button in the PaymentSheet configuration.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/Info.plist" linesStart={1} linesEnd={9} title="Enable card scanning">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry. To enable card scanning, set NSCameraUsageDescription in your application's Info.plist, and provide a reason for accessing the camera (for example, "To scan cards").

        **Note:** Card scanning is only supported on devices running iOS 13 or higher.
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.go" linesStart={11} linesEnd={14} title="Import additional Stripe resources">
        Import the Stripe customer and paymentmethod packages. Use these packages to store information about your customer.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={128} linesEnd={139} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={145} linesEnd={154} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={74} linesEnd={109} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={127} linesEnd={129} title="Collect shipping or billing addresses">
        Configure the shipping details in the PaymentSheet configuration to collect addresses from your customers.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={192} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={192} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={192} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ios-swift-net" label="Swift + .NET">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ios-swift-net/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ios-swift-net" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="Server.cs" linesStart={29} linesEnd={36} title="Install the Stripe.net library">
        Install the package with .NET or NuGet. Alternatively, if you're starting from scratch, download the files which contains a configured .csproj file.

        **dotnet:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        dotnet add package Stripe.net
        ```

        **NuGet:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        Install-Package Stripe.net
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={82} linesEnd={99} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={88} linesEnd={92} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={1} linesEnd={2} title="Install the SDK">
        The Stripe iOS SDK is open source, fully documented, and compatible with apps supporting iOS 13 or above. Import the Stripe SDK into your checkout screen's View Controller.

        In Xcode, select File > Add Package Dependencies... and enter [https://github.com/stripe/stripe-ios-spm](https://github.com/stripe/stripe-ios-spm) as the repository URL. Select the latest version number from our releases page, and add the StripePaymentSheet module to your app's target.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={42} linesEnd={44} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={66} linesEnd={102} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={112} linesEnd={134} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the PaymentSheet.Configuration struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={135} linesEnd={145} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={27} title="Run the application">
        Run your ASP.NET MVC server.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        dotnet run
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={27} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={27} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="Server.cs" linesStart={111} linesEnd={136} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={93} linesEnd={97} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Payment customization options

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={120} linesEnd={120} title="Enable delayed payment methods">
        Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={122} linesEnd={125} title="Enable Apple Pay">
        To enable Apple Pay, provide your Apple Pay Merchant ID and your Stripe account's country code.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={121} linesEnd={121} title="Use a custom primary button color">
        Consider using a custom color for the primary button that better matches your brand or app's visual identity.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/Info.plist" linesStart={1} linesEnd={9} title="Enable card scanning">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry. To enable card scanning, set NSCameraUsageDescription in your application's Info.plist, and provide a reason for accessing the camera (for example, "To scan cards").

        **Note:** Card scanning is only supported on devices running iOS 13 or higher.
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="Server.cs" linesStart={62} linesEnd={78} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={84} linesEnd={85} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={149} linesEnd={187} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="ios/CheckoutViewController.swift" linesStart={127} linesEnd={129} title="Collect local and international shipping or billing addresses">
        Collect local and international shipping or billing addresses from your customers.
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={27} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={27} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={27} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>
  </Architecture>

  <Architecture value="Android SDK" label="Android SDK">
    <FrameworkGuide framework="ad-kotlin-ruby" label="Kotlin + Ruby">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-kotlin-ruby/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-kotlin-ruby" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="Gemfile" linesStart={1} linesEnd={4} title="Install the Stripe Ruby library">
        Install the Stripe ruby gem and require it in your code. Alternatively, if you're starting from scratch and need a Gemfile, download the project files using the link in the code editor.

        **Terminal:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        gem install stripe
        ```

        **Bundler (add to Gemfile):**

        ```ruby theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        gem 'stripe'
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={67} linesEnd={104} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={88} linesEnd={91} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={1} linesEnd={38} title="Install the SDK">
        The Stripe Android SDK is open source and fully documented and compatible with devices running Android 5.0 (API level 21) and above.

        To install the SDK, add stripe-android to the dependencies block of your build.gradle file:

        **build.gradle (Groovy):**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripe-android:22.6.1'
        ```

        **Note:** For details on the latest SDK release and past versions, see the Releases page on GitHub.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/MyApp.kt" linesStart={1} linesEnd={14} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={183} linesEnd={225} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={244} linesEnd={273} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the `PaymentSheet.Configuration` struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={69} linesEnd={77} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={183} linesEnd={225} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.rb" linesStart={9} linesEnd={24} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={92} linesEnd={98} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Enable delayed payment methods

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={249} linesEnd={251} title="Enable delayed payment methods">
        Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      #### Enable Google Pay

      <CodeFocusSection activeFilePath="android/AndroidManifest.xml" linesStart={1} linesEnd={6} title="Enable Google Pay API">
        To use Google Pay, first enable the Google Pay API in your AndroidManifest.xml.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={263} linesEnd={268} title="Configure Google Pay">
        Enable Google Pay by passing a `PaymentSheet.GooglePayConfiguration` object with the Google Pay environment (production or test) and the country code of your business when initializing `PaymentSheet.Configuration`.
      </CodeFocusSection>

      #### Customize the primary button color

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={252} linesEnd={262} title="Customize button appearance">
        Consider using a custom color for the primary button that better matches your brand or app's visual identity.
      </CodeFocusSection>

      #### Enable card scanning

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={1} linesEnd={38} title="Add card scanning dependency">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry. To enable card scanning, add stripecardscan to the dependencies block of your app/build.gradle file:

        **build.gradle (Groovy):**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripecardscan:22.6.1'
        ```
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.rb" linesStart={72} linesEnd={78} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={83} linesEnd={86} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={41} linesEnd={64} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect shipping or billing addresses

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={44} linesEnd={53} title="Configure Address Element">
        Collect local and international shipping or billing addresses from your customers.

        If you use the Address Element, you can optionally use the Google Places SDK to fetch address autocomplete suggestions. To enable autocomplete suggestions, add places to the dependency block of your app/build.gradle file:

        **build.gradle (Groovy):**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.google.android.libraries.places:places:2.6.0'
        ```
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ad-kotlin-nodejs" label="Kotlin + Node.js">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-kotlin-nodejs/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-kotlin-nodejs" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={4} title="Install the Stripe Node library">
        Install the package and import it in your code. Alternatively, if you're starting from scratch and need a package.json file, download the project files using the Download link in the code editor.

        **npm:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm install --save stripe
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={66} linesEnd={106} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={91} linesEnd={93} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={21} linesEnd={29} title="Install the SDK">
        The Stripe Android SDK is open source and fully documented and compatible with devices running Android 5.0 (API level 21) and above.

        To install the SDK, add stripe-android to the dependencies block of your build.gradle file:

        **build.gradle (Groovy):**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripe-android:22.6.1'
        ```

        **Note:** For details on the latest SDK release and past versions, see the Releases page on GitHub.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/MyApp.kt" linesStart={6} linesEnd={13} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={103} linesEnd={109} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={244} linesEnd={272} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the `PaymentSheet.Configuration` struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={69} linesEnd={77} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.js" linesStart={9} linesEnd={26} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={94} linesEnd={100} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Enable delayed payment methods

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={251} linesEnd={251} title="Enable delayed payment methods">
        Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      #### Enable Google Pay

      <CodeFocusSection activeFilePath="android/AndroidManifest.xml" linesStart={1} linesEnd={6} title="Enable Google Pay in AndroidManifest">
        To use Google Pay, first enable the Google Pay API in your AndroidManifest.xml.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={263} linesEnd={268} title="Configure Google Pay">
        Enable Google Pay by passing a `PaymentSheet.GooglePayConfiguration` object with the Google Pay environment (production or test) and the country code of your business when initializing `PaymentSheet.Configuration`.
      </CodeFocusSection>

      #### Customize the primary button

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={252} linesEnd={262} title="Customize the primary button color">
        Consider using a custom color for the primary button that better matches your brand or app's visual identity.
      </CodeFocusSection>

      #### Enable card scanning

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={21} linesEnd={29} title="Enable card scanning">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry. To enable card scanning, add stripecardscan to the dependencies block of your app/build.gradle file:

        **build.gradle (Groovy):**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripecardscan:22.6.1'
        ```
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.js" linesStart={70} linesEnd={78} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={86} linesEnd={87} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={42} linesEnd={64} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect shipping or billing addresses

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={44} linesEnd={53} title="Configure Address Element">
        Collect local and international shipping or billing addresses from your customers.

        If you use the Address Element, you can optionally use the Google Places SDK to fetch address autocomplete suggestions. To enable autocomplete suggestions, add places to the dependency block of your app/build.gradle file:

        **build.gradle (Groovy):**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.google.android.libraries.places:places:2.6.0'
        ```
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ad-kotlin-php" label="Kotlin + PHP">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-kotlin-php/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-kotlin-php" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="composer.json" linesStart={1} linesEnd={6} title="Install the Stripe PHP library">
        Install the library with composer and initialize with your secret API key. Alternatively, if you're starting from scratch and need a composer.json file, download the files using the link in the code editor.

        **Composer:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        composer require stripe/stripe-php
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={64} linesEnd={80} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={69} linesEnd={72} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={21} linesEnd={23} title="Install the SDK">
        The Stripe Android SDK is open source and fully documented and compatible with devices running Android 5.0 (API level 21) and above.

        To install the SDK, add stripe-android to the dependencies block of your build.gradle file:

        **build.gradle:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripe-android:22.6.1'
        ```

        **Note:** For details on the latest SDK release and past versions, see the Releases page on GitHub.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/MyApp.kt" linesStart={1} linesEnd={13} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={103} linesEnd={109} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={244} linesEnd={272} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the PaymentSheet.Configuration struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={69} linesEnd={77} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={183} linesEnd={225} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={82} linesEnd={86} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="public/create.php" linesStart={8} linesEnd={25} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={73} linesEnd={79} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Enable delayed payment methods

      Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

      If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={251} linesEnd={251} title="Enable delayed payment methods">
        Set `allowsDelayedPaymentMethods` to true to enable delayed payment methods.
      </CodeFocusSection>

      #### Enable Google Pay

      To use Google Pay, first enable the Google Pay API in your AndroidManifest.xml.

      <CodeFocusSection activeFilePath="android/AndroidManifest.xml" linesStart={1} linesEnd={5} title="Enable Google Pay in AndroidManifest">
        Add the Google Pay API meta-data to your AndroidManifest.xml file.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={263} linesEnd={268} title="Configure Google Pay">
        Enable Google Pay by passing a PaymentSheet.GooglePayConfiguration object with the Google Pay environment (production or test) and the country code of your business when initializing PaymentSheet.Configuration.
      </CodeFocusSection>

      #### Customize the primary button

      Consider using a custom color for the primary button that better matches your brand or app's visual identity.

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={252} linesEnd={262} title="Customize appearance">
        Customize the Payment Sheet appearance by configuring colors, fonts, and other visual properties.
      </CodeFocusSection>

      #### Enable card scanning

      Card scanning can help increase your conversion rate by removing the friction of manual card entry. To enable card scanning, add stripecardscan to the dependencies block of your app/build.gradle file:

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={21} linesEnd={23} title="Add card scanning dependency">
        **build.gradle:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripecardscan:22.6.1'
        ```
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="public/create.php" linesStart={49} linesEnd={59} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={65} linesEnd={66} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="charge.php" linesStart={21} linesEnd={28} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect local and international addresses

      Collect local and international shipping or billing addresses from your customers.

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={44} linesEnd={53} title="Configure Address Element">
        If you use the Address Element, you can optionally use the Google Places SDK to fetch address autocomplete suggestions. To enable autocomplete suggestions, add places to the dependency block of your app/build.gradle file:

        **build.gradle:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.google.android.libraries.places:places:2.6.0'
        ```
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={91} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={91} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={91} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ad-kotlin-python" label="Kotlin + Python">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-kotlin-python/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-kotlin-python" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="server.py" linesStart={5} linesEnd={7} title="Install the Stripe Python package">
        Install the Stripe package and import it in your code. Alternatively, if you're starting from scratch and need a requirements.txt file, download the project files using the link in the code editor.

        **pip:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        pip3 install stripe
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={78} linesEnd={117} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={101} linesEnd={104} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="android/build.gradle" linesStart={1} linesEnd={1} title="Install the SDK">
        The Stripe Android SDK is open source and fully documented and compatible with devices running Android 5.0 (API level 21) and above.

        To install the SDK, add stripe-android to the dependencies block of your build.gradle file:

        **build.gradle:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripe-android:22.6.1'
        ```

        **Note:** For details on the latest SDK release and past versions, see the Releases page on GitHub.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/MyApp.kt" linesStart={6} linesEnd={14} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={103} linesEnd={109} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={244} linesEnd={273} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the PaymentSheet.Configuration struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={69} linesEnd={77} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Run the application">
        Run your Python server and go to your Android simulator or device.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        python3 -m flask run --port=4242
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.py" linesStart={18} linesEnd={34} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={105} linesEnd={111} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Enable delayed payment methods

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={251} linesEnd={251} title="Enable delayed payment methods">
        Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      #### Enable Google Pay

      <CodeFocusSection activeFilePath="android/AndroidManifest.xml" linesStart={1} linesEnd={6} title="Enable Google Pay in AndroidManifest">
        To use Google Pay, first enable the Google Pay API in your AndroidManifest.xml.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={263} linesEnd={268} title="Configure Google Pay">
        Enable Google Pay by passing a PaymentSheet.GooglePayConfiguration object with the Google Pay environment (production or test) and the country code of your business when initializing PaymentSheet.Configuration.
      </CodeFocusSection>

      #### Customize appearance

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={252} linesEnd={262} title="Customize primary button color">
        Consider using a custom color for the primary button that better matches your brand or app's visual identity.
      </CodeFocusSection>

      #### Enable card scanning

      <CodeFocusSection activeFilePath="android/build.gradle" linesStart={1} linesEnd={1} title="Add card scanning dependency">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry. To enable card scanning, add stripecardscan to the dependencies block of your app/build.gradle file:

        **build.gradle:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripecardscan:22.6.1'
        ```
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.py" linesStart={82} linesEnd={88} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={96} linesEnd={98} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details. Learn more about the most effective way to apply setup\_future\_usage. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={54} linesEnd={76} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect shipping or billing addresses

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={44} linesEnd={53} title="Configure Address Element">
        Collect local and international shipping or billing addresses from your customers.

        If you use the Address Element, you can optionally use the Google Places SDK to fetch address autocomplete suggestions. To enable autocomplete suggestions, add places to the dependency block of your app/build.gradle file:

        **build.gradle:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.google.android.libraries.places:places:2.6.0'
        ```
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ad-kotlin-go" label="Kotlin + Go">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-kotlin-go/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-kotlin-go" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="go.mod" linesStart={1} linesEnd={6} title="Set up your server">
        Add the dependency to your build and import the library. Alternatively, if you're starting from scratch and need a go.mod file, download the project files using the link in the code editor.

        **Go:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        go get -u github.com/stripe/stripe-go/v84
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={111} linesEnd={178} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={150} linesEnd={154} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={1} linesEnd={38} title="Install the SDK">
        The Stripe Android SDK is open source and fully documented and compatible with devices running Android 5.0 (API level 21) and above.

        **To install the SDK, add stripe-android to the dependencies block of your build.gradle file:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripe-android:22.6.1'
        ```

        **Note:** For details on the latest SDK release and past versions, see the Releases page on GitHub.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/MyApp.kt" linesStart={1} linesEnd={14} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={103} linesEnd={109} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={244} linesEnd={273} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the PaymentSheet.Configuration struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={69} linesEnd={77} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="server.go" linesStart={19} linesEnd={28} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={28} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.go" linesStart={35} linesEnd={58} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={156} linesEnd={162} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Enable delayed payment methods

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={249} linesEnd={251} title="Enable delayed payment methods">
        Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      #### Enable Google Pay

      <CodeFocusSection activeFilePath="android/AndroidManifest.xml" linesStart={1} linesEnd={6} title="Enable Google Pay API">
        To use Google Pay, first enable the Google Pay API in your AndroidManifest.xml.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={263} linesEnd={268} title="Configure Google Pay">
        Enable Google Pay by passing a PaymentSheet.GooglePayConfiguration object with the Google Pay environment (production or test) and the country code of your business when initializing PaymentSheet.Configuration.
      </CodeFocusSection>

      #### Customize appearance

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={252} linesEnd={262} title="Customize primary button color">
        Consider using a custom color for the primary button that better matches your brand or app's visual identity.
      </CodeFocusSection>

      #### Enable card scanning

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={1} linesEnd={38} title="Enable card scanning">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry.

        **To enable card scanning, add stripecardscan to the dependencies block of your app/build.gradle file:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripecardscan:22.6.1'
        ```
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.go" linesStart={9} linesEnd={14} title="Import additional Stripe resources">
        Import the Stripe customer and paymentmethod packages. Use these packages to store information about your customer.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={126} linesEnd={139} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={144} linesEnd={154} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={74} linesEnd={109} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect shipping or billing addresses

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={44} linesEnd={53} title="Collect shipping or billing addresses">
        Collect local and international shipping or billing addresses from your customers.

        **If you use the Address Element, you can optionally use the Google Places SDK to fetch address autocomplete suggestions. To enable autocomplete suggestions, add places to the dependency block of your app/build.gradle file:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.google.android.libraries.places:places:2.6.0'
        ```
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="README.md" linesStart={1} linesEnd={1} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="README.md" linesStart={1} linesEnd={1} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="README.md" linesStart={1} linesEnd={1} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ad-kotlin-net" label="Kotlin + .NET">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-kotlin-net/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-kotlin-net" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="Server.cs" linesStart={29} linesEnd={36} title="Install the Stripe.net library">
        Install the package with .NET or NuGet. Alternatively, if you're starting from scratch, download the files which contains a configured .csproj file.

        **dotnet:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        dotnet add package Stripe.net
        ```

        **NuGet:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        Install-Package Stripe.net
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={82} linesEnd={100} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={88} linesEnd={92} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={21} linesEnd={29} title="Install the SDK">
        The Stripe Android SDK is open source and fully documented and compatible with devices running Android 5.0 (API level 21) and above.

        **To install the SDK, add stripe-android to the dependencies block of your build.gradle file:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripe-android:22.6.1'
        ```

        **Note:** For details on the latest SDK release and past versions, see the Releases page on GitHub.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/MyApp.kt" linesStart={6} linesEnd={14} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={103} linesEnd={109} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={244} linesEnd={273} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the PaymentSheet.Configuration struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={69} linesEnd={77} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={183} linesEnd={225} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={18} linesEnd={26} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="Server.cs" linesStart={111} linesEnd={136} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={93} linesEnd={97} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Enable delayed payment methods

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={249} linesEnd={262} title="Enable delayed payment methods">
        Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      #### Enable Google Pay

      <CodeFocusSection activeFilePath="android/AndroidManifest.xml" linesStart={1} linesEnd={6} title="Enable Google Pay API">
        To use Google Pay, first enable the Google Pay API in your AndroidManifest.xml.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={263} linesEnd={268} title="Configure Google Pay">
        Enable Google Pay by passing a PaymentSheet.GooglePayConfiguration object with the Google Pay environment (production or test) and the country code of your business when initializing PaymentSheet.Configuration.
      </CodeFocusSection>

      #### Customize appearance

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={252} linesEnd={261} title="Customize primary button">
        Consider using a custom color for the primary button that better matches your brand or app's visual identity.
      </CodeFocusSection>

      #### Enable card scanning

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={39} linesEnd={61} title="Enable card scanning">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry.

        **To enable card scanning, add stripecardscan to the dependencies block of your app/build.gradle file:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripecardscan:22.6.1'
        ```
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="Server.cs" linesStart={62} linesEnd={78} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={84} linesEnd={85} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={149} linesEnd={187} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect shipping or billing addresses

      <CodeFocusSection activeFilePath="android/CheckoutActivity.kt" linesStart={44} linesEnd={53} title="Configure Address Element">
        Collect local and international shipping or billing addresses from your customers.

        **If you use the Address Element, you can optionally use the Google Places SDK to fetch address autocomplete suggestions. To enable autocomplete suggestions, add places to the dependency block of your app/build.gradle file:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.google.android.libraries.places:places:2.6.0'
        ```
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={27} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={27} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={47} linesEnd={56} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ad-java-ruby" label="Java + Ruby">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-java-ruby/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-java-ruby" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="Gemfile" linesStart={1} linesEnd={4} title="Install the Stripe Ruby library">
        Install the Stripe ruby gem and require it in your code. Alternatively, if you're starting from scratch and need a Gemfile, download the project files using the link in the code editor.

        **Terminal:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        gem install stripe
        ```

        **Bundler (add to Gemfile):**

        ```ruby theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        gem 'stripe'
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={67} linesEnd={104} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={88} linesEnd={91} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={1} linesEnd={25} title="Install the SDK">
        The Stripe Android SDK is open source and fully documented and compatible with devices running Android 5.0 (API level 21) and above.

        To install the SDK, add stripe-android to the dependencies block of your build.gradle file:

        **build.gradle (Groovy):**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripe-android:22.6.1'
        ```

        **Note:** For details on the latest SDK release and past versions, see the Releases page on GitHub.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/MyApp.java" linesStart={1} linesEnd={15} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={89} linesEnd={128} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={142} linesEnd={154} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the `PaymentSheet.Configuration` struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={166} linesEnd={177} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={89} linesEnd={128} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.rb" linesStart={9} linesEnd={24} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={92} linesEnd={98} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Enable delayed payment methods

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={143} linesEnd={144} title="Enable delayed payment methods">
        Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      #### Enable Google Pay

      <CodeFocusSection activeFilePath="android/AndroidManifest.xml" linesStart={1} linesEnd={6} title="Enable Google Pay API">
        To use Google Pay, first enable the Google Pay API in your AndroidManifest.xml.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={147} linesEnd={149} title="Configure Google Pay">
        Enable Google Pay by passing a `PaymentSheet.GooglePayConfiguration` object with the Google Pay environment (production or test) and the country code of your business when initializing `PaymentSheet.Configuration`.
      </CodeFocusSection>

      #### Customize the primary button color

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={146} linesEnd={146} title="Customize button appearance">
        Consider using a custom color for the primary button that better matches your brand or app's visual identity.
      </CodeFocusSection>

      #### Enable card scanning

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={1} linesEnd={25} title="Add card scanning dependency">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry. To enable card scanning, add stripecardscan to the dependencies block of your app/build.gradle file:

        **build.gradle (Groovy):**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripecardscan:22.6.1'
        ```
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.rb" linesStart={72} linesEnd={78} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={83} linesEnd={86} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={41} linesEnd={64} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect shipping or billing addresses

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={41} linesEnd={51} title="Configure Address Element">
        Collect local and international shipping or billing addresses from your customers.

        If you use the Address Element, you can optionally use the Google Places SDK to fetch address autocomplete suggestions. To enable autocomplete suggestions, add places to the dependency block of your app/build.gradle file:

        **build.gradle (Groovy):**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.google.android.libraries.places:places:2.6.0'
        ```
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.rb" linesStart={1} linesEnd={104} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ad-java-nodejs" label="Java + Node.js">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-java-nodejs/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-java-nodejs" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={4} title="Install the Stripe Node library">
        Install the package and import it in your code. Alternatively, if you're starting from scratch and need a package.json file, download the project files using the Download link in the code editor.

        **npm:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        npm install --save stripe
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={66} linesEnd={106} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={91} linesEnd={93} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={1} linesEnd={25} title="Install the SDK">
        The Stripe Android SDK is open source and fully documented and compatible with devices running Android 5.0 (API level 21) and above.

        To install the SDK, add stripe-android to the dependencies block of your build.gradle file:

        **build.gradle (Groovy):**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripe-android:22.6.1'
        ```

        **Note:** For details on the latest SDK release and past versions, see the Releases page on GitHub.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/MyApp.java" linesStart={6} linesEnd={14} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={102} linesEnd={127} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={142} linesEnd={154} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the `PaymentSheet.Configuration` struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={166} linesEnd={177} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.js" linesStart={9} linesEnd={26} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={94} linesEnd={100} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Enable delayed payment methods

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={144} linesEnd={144} title="Enable delayed payment methods">
        Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      #### Enable Google Pay

      <CodeFocusSection activeFilePath="android/AndroidManifest.xml" linesStart={1} linesEnd={6} title="Enable Google Pay in AndroidManifest">
        To use Google Pay, first enable the Google Pay API in your AndroidManifest.xml.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={147} linesEnd={149} title="Configure Google Pay">
        Enable Google Pay by passing a `PaymentSheet.GooglePayConfiguration` object with the Google Pay environment (production or test) and the country code of your business when initializing `PaymentSheet.Configuration`.
      </CodeFocusSection>

      #### Customize the primary button

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={143} linesEnd={150} title="Customize the primary button color">
        Consider using a custom color for the primary button that better matches your brand or app's visual identity.
      </CodeFocusSection>

      #### Enable card scanning

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={1} linesEnd={25} title="Enable card scanning">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry. To enable card scanning, add stripecardscan to the dependencies block of your app/build.gradle file:

        **build.gradle (Groovy):**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripecardscan:22.6.1'
        ```
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.js" linesStart={70} linesEnd={78} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={86} linesEnd={87} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={42} linesEnd={64} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect shipping or billing addresses

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={41} linesEnd={51} title="Configure Address Element">
        Collect local and international shipping or billing addresses from your customers.

        If you use the Address Element, you can optionally use the Google Places SDK to fetch address autocomplete suggestions. To enable autocomplete suggestions, add places to the dependency block of your app/build.gradle file:

        **build.gradle (Groovy):**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.google.android.libraries.places:places:2.6.0'
        ```
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.js" linesStart={1} linesEnd={110} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ad-java-php" label="Java + PHP">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-java-php/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-java-php" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="composer.json" linesStart={1} linesEnd={6} title="Install the Stripe PHP library">
        Install the library with composer and initialize with your secret API key. Alternatively, if you're starting from scratch and need a composer.json file, download the files using the link in the code editor.

        **Composer:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        composer require stripe/stripe-php
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={64} linesEnd={80} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={69} linesEnd={72} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={21} linesEnd={23} title="Install the SDK">
        The Stripe Android SDK is open source and fully documented and compatible with devices running Android 5.0 (API level 21) and above.

        To install the SDK, add stripe-android to the dependencies block of your build.gradle file:

        **build.gradle:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripe-android:22.6.1'
        ```

        **Note:** For details on the latest SDK release and past versions, see the Releases page on GitHub.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/MyApp.java" linesStart={1} linesEnd={13} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={103} linesEnd={109} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={244} linesEnd={272} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the PaymentSheet.Configuration struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={69} linesEnd={77} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={183} linesEnd={225} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={82} linesEnd={86} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="public/create.php" linesStart={8} linesEnd={25} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={73} linesEnd={79} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Enable delayed payment methods

      Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

      If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={251} linesEnd={251} title="Enable delayed payment methods">
        Set `allowsDelayedPaymentMethods` to true to enable delayed payment methods.
      </CodeFocusSection>

      #### Enable Google Pay

      To use Google Pay, first enable the Google Pay API in your AndroidManifest.xml.

      <CodeFocusSection activeFilePath="android/AndroidManifest.xml" linesStart={1} linesEnd={5} title="Enable Google Pay in AndroidManifest">
        Add the Google Pay API meta-data to your AndroidManifest.xml file.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={263} linesEnd={268} title="Configure Google Pay">
        Enable Google Pay by passing a PaymentSheet.GooglePayConfiguration object with the Google Pay environment (production or test) and the country code of your business when initializing PaymentSheet.Configuration.
      </CodeFocusSection>

      #### Customize the primary button

      Consider using a custom color for the primary button that better matches your brand or app's visual identity.

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={252} linesEnd={262} title="Customize appearance">
        Customize the Payment Sheet appearance by configuring colors, fonts, and other visual properties.
      </CodeFocusSection>

      #### Enable card scanning

      Card scanning can help increase your conversion rate by removing the friction of manual card entry. To enable card scanning, add stripecardscan to the dependencies block of your app/build.gradle file:

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={21} linesEnd={23} title="Add card scanning dependency">
        **build.gradle:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripecardscan:22.6.1'
        ```
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="public/create.php" linesStart={49} linesEnd={59} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={65} linesEnd={66} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="charge.php" linesStart={21} linesEnd={28} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect local and international addresses

      Collect local and international shipping or billing addresses from your customers.

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={44} linesEnd={53} title="Configure Address Element">
        If you use the Address Element, you can optionally use the Google Places SDK to fetch address autocomplete suggestions. To enable autocomplete suggestions, add places to the dependency block of your app/build.gradle file:

        **build.gradle:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.google.android.libraries.places:places:2.6.0'
        ```
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={91} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={91} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="public/create.php" linesStart={1} linesEnd={91} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ad-java-python" label="Java + Python">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-java-python/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-java-python" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="server.py" linesStart={5} linesEnd={7} title="Install the Stripe Python package">
        Install the Stripe package and import it in your code. Alternatively, if you're starting from scratch and need a requirements.txt file, download the project files using the link in the code editor.

        **pip:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        pip3 install stripe
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={78} linesEnd={117} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={101} linesEnd={104} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="android/build.gradle" linesStart={1} linesEnd={1} title="Install the SDK">
        The Stripe Android SDK is open source and fully documented and compatible with devices running Android 5.0 (API level 21) and above.

        To install the SDK, add stripe-android to the dependencies block of your build.gradle file:

        **build.gradle:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripe-android:22.6.1'
        ```

        **Note:** For details on the latest SDK release and past versions, see the Releases page on GitHub.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/MyApp.java" linesStart={6} linesEnd={14} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={103} linesEnd={109} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={244} linesEnd={273} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the PaymentSheet.Configuration struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={69} linesEnd={77} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Run the application">
        Run your Python server and go to your Android simulator or device.

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        python3 -m flask run --port=4242
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.py" linesStart={18} linesEnd={34} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={105} linesEnd={111} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Enable delayed payment methods

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={251} linesEnd={251} title="Enable delayed payment methods">
        Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      #### Enable Google Pay

      <CodeFocusSection activeFilePath="android/AndroidManifest.xml" linesStart={1} linesEnd={6} title="Enable Google Pay in AndroidManifest">
        To use Google Pay, first enable the Google Pay API in your AndroidManifest.xml.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={263} linesEnd={268} title="Configure Google Pay">
        Enable Google Pay by passing a PaymentSheet.GooglePayConfiguration object with the Google Pay environment (production or test) and the country code of your business when initializing PaymentSheet.Configuration.
      </CodeFocusSection>

      #### Customize appearance

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={252} linesEnd={262} title="Customize primary button color">
        Consider using a custom color for the primary button that better matches your brand or app's visual identity.
      </CodeFocusSection>

      #### Enable card scanning

      <CodeFocusSection activeFilePath="android/build.gradle" linesStart={1} linesEnd={1} title="Add card scanning dependency">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry. To enable card scanning, add stripecardscan to the dependencies block of your app/build.gradle file:

        **build.gradle:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripecardscan:22.6.1'
        ```
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.py" linesStart={82} linesEnd={88} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={96} linesEnd={98} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details. Learn more about the most effective way to apply setup\_future\_usage. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={54} linesEnd={76} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect shipping or billing addresses

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={44} linesEnd={53} title="Configure Address Element">
        Collect local and international shipping or billing addresses from your customers.

        If you use the Address Element, you can optionally use the Google Places SDK to fetch address autocomplete suggestions. To enable autocomplete suggestions, add places to the dependency block of your app/build.gradle file:

        **build.gradle:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.google.android.libraries.places:places:2.6.0'
        ```
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.py" linesStart={1} linesEnd={120} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ad-java-go" label="Java + Go">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-java-go/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-java-go" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="go.mod" linesStart={1} linesEnd={6} title="Set up your server">
        Add the dependency to your build and import the library. Alternatively, if you're starting from scratch and need a go.mod file, download the project files using the link in the code editor.

        **Go:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        go get -u github.com/stripe/stripe-go/v84
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={111} linesEnd={178} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={150} linesEnd={154} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={1} linesEnd={38} title="Install the SDK">
        The Stripe Android SDK is open source and fully documented and compatible with devices running Android 5.0 (API level 21) and above.

        **To install the SDK, add stripe-android to the dependencies block of your build.gradle file:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripe-android:22.6.1'
        ```

        **Note:** For details on the latest SDK release and past versions, see the Releases page on GitHub.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/MyApp.java" linesStart={1} linesEnd={14} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={103} linesEnd={109} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={244} linesEnd={273} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the PaymentSheet.Configuration struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={69} linesEnd={77} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="server.go" linesStart={19} linesEnd={28} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={1} linesEnd={28} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="server.go" linesStart={35} linesEnd={58} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={156} linesEnd={162} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Enable delayed payment methods

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={249} linesEnd={251} title="Enable delayed payment methods">
        Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      #### Enable Google Pay

      <CodeFocusSection activeFilePath="android/AndroidManifest.xml" linesStart={1} linesEnd={6} title="Enable Google Pay API">
        To use Google Pay, first enable the Google Pay API in your AndroidManifest.xml.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={263} linesEnd={268} title="Configure Google Pay">
        Enable Google Pay by passing a PaymentSheet.GooglePayConfiguration object with the Google Pay environment (production or test) and the country code of your business when initializing PaymentSheet.Configuration.
      </CodeFocusSection>

      #### Customize appearance

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={252} linesEnd={262} title="Customize primary button color">
        Consider using a custom color for the primary button that better matches your brand or app's visual identity.
      </CodeFocusSection>

      #### Enable card scanning

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={1} linesEnd={38} title="Enable card scanning">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry.

        **To enable card scanning, add stripecardscan to the dependencies block of your app/build.gradle file:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripecardscan:22.6.1'
        ```
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="server.go" linesStart={9} linesEnd={14} title="Import additional Stripe resources">
        Import the Stripe customer and paymentmethod packages. Use these packages to store information about your customer.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={126} linesEnd={139} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={144} linesEnd={154} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="server.go" linesStart={74} linesEnd={109} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect shipping or billing addresses

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={44} linesEnd={53} title="Collect shipping or billing addresses">
        Collect local and international shipping or billing addresses from your customers.

        **If you use the Address Element, you can optionally use the Google Places SDK to fetch address autocomplete suggestions. To enable autocomplete suggestions, add places to the dependency block of your app/build.gradle file:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.google.android.libraries.places:places:2.6.0'
        ```
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="README.md" linesStart={1} linesEnd={1} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="README.md" linesStart={1} linesEnd={1} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="README.md" linesStart={1} linesEnd={1} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ad-java-net" label="Java + .NET">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-java-net/archive/refs/heads/main.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-java-net" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="Server.cs" linesStart={29} linesEnd={36} title="Install the Stripe.net library">
        Install the package with .NET or NuGet. Alternatively, if you're starting from scratch, download the files which contains a configured .csproj file.

        **dotnet:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        dotnet add package Stripe.net
        ```

        **NuGet:**

        ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        Install-Package Stripe.net
        ```
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={82} linesEnd={100} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={88} linesEnd={92} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={21} linesEnd={29} title="Install the SDK">
        The Stripe Android SDK is open source and fully documented and compatible with devices running Android 5.0 (API level 21) and above.

        **To install the SDK, add stripe-android to the dependencies block of your build.gradle file:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripe-android:22.6.1'
        ```

        **Note:** For details on the latest SDK release and past versions, see the Releases page on GitHub.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/MyApp.java" linesStart={6} linesEnd={14} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={103} linesEnd={109} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={244} linesEnd={273} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the PaymentSheet.Configuration struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={69} linesEnd={77} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={183} linesEnd={225} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={18} linesEnd={26} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="Server.cs" linesStart={111} linesEnd={136} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={93} linesEnd={97} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Enable delayed payment methods

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={249} linesEnd={262} title="Enable delayed payment methods">
        Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      #### Enable Google Pay

      <CodeFocusSection activeFilePath="android/AndroidManifest.xml" linesStart={1} linesEnd={6} title="Enable Google Pay API">
        To use Google Pay, first enable the Google Pay API in your AndroidManifest.xml.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={263} linesEnd={268} title="Configure Google Pay">
        Enable Google Pay by passing a PaymentSheet.GooglePayConfiguration object with the Google Pay environment (production or test) and the country code of your business when initializing PaymentSheet.Configuration.
      </CodeFocusSection>

      #### Customize appearance

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={252} linesEnd={261} title="Customize primary button">
        Consider using a custom color for the primary button that better matches your brand or app's visual identity.
      </CodeFocusSection>

      #### Enable card scanning

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={39} linesEnd={61} title="Enable card scanning">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry.

        **To enable card scanning, add stripecardscan to the dependencies block of your app/build.gradle file:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripecardscan:22.6.1'
        ```
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="Server.cs" linesStart={62} linesEnd={78} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={84} linesEnd={85} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={149} linesEnd={187} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect shipping or billing addresses

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={44} linesEnd={53} title="Configure Address Element">
        Collect local and international shipping or billing addresses from your customers.

        **If you use the Address Element, you can optionally use the Google Places SDK to fetch address autocomplete suggestions. To enable autocomplete suggestions, add places to the dependency block of your app/build.gradle file:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.google.android.libraries.places:places:2.6.0'
        ```
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={27} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={1} linesEnd={27} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="Server.cs" linesStart={47} linesEnd={56} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>

    <FrameworkGuide framework="ad-java-java" label="Java + Java">
      # Build a checkout page with Payment Intents API

      Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe's Web or Mobile elements to let you accept payments. To build a custom integration that goes beyond the basics of this quickstart, see Accept a payment.

      To learn about different payment scenarios, such as subscriptions, and other Stripe products, compare payment integrations.

      <DownloadAndOpenButtons downloadUrl="/guardian/stripe-sandbox/stripe-accept-payments-with-stripe-checkout-ad-java-java.zip" gitUrl="https://github.com/sampleapp-ai/stripe-accept-payments-with-stripe-checkout-ad-java-java" className="mt-4 mb-6" />

      ### ❶ Set up the server

      <CodeFocusSection activeFilePath="pom.xml" linesStart={33} linesEnd={39} title="Install the Stripe Java library">
        Add the dependency to your build and import the library. Alternatively, if you're starting from scratch and need a sample pom.xml file (for Maven), download the project files using the link in the code editor.

        **Maven:**

        ```xml theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        <dependency>
          <groupId>com.stripe</groupId>
          <artifactId>stripe-java</artifactId>
          <version>{VERSION}</version>
        </dependency>
        ```

        **Gradle:**

        ```gradle theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation "com.stripe:stripe-java:{VERSION}"
        ```

        Add the following dependency to your POM and replace {VERSION} with the version number you want to use.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={144} linesEnd={211} title="Create a PaymentIntent">
        Add an endpoint on your server that creates a `PaymentIntent`. A PaymentIntent tracks the customer's payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent's `client_secret` in the response to finish the payment on the client.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={182} linesEnd={187} title="Configure payment methods">
        Stripe enables cards and other common payment methods by default with dynamic payment methods. You can update and configure payment methods from the Dashboard with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and buyer location.
      </CodeFocusSection>

      ### ❷ Build a checkout screen on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={26} linesEnd={72} title="Install the SDK">
        The Stripe Android SDK is open source and fully documented and compatible with devices running Android 5.0 (API level 21) and above.

        To install the SDK, add stripe-android to the dependencies block of your build.gradle file:

        **build.gradle:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripe-android:22.6.1'
        ```

        Note: For details on the latest SDK release and past versions, see the Releases page on GitHub.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/MyApp.java" linesStart={6} linesEnd={14} title="Setup the SDK">
        Configure the Stripe SDK with your Stripe publishable API key. Hardcoding the publishable API key in the SDK is for demonstration only. In a production app, you must retrieve the API key from your server.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={89} linesEnd={128} title="Fetch a PaymentIntent">
        Make a request to your server for a PaymentIntent as soon as the view loads. Store a reference to the PaymentIntent's client secret returned by the server; the Payment Sheet uses this secret to complete the payment later.
      </CodeFocusSection>

      ### ❸ Complete the payment on the client

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={142} linesEnd={154} title="Configure and present the Payment Sheet">
        Create a PaymentSheet instance using the client secret retrieved earlier, and present it from your view controller.

        Use the `PaymentSheet.Configuration` struct for customising the Payment Sheet.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={166} linesEnd={177} title="Handle the payment result">
        Use the completion block for handling the payment result.

        If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
      </CodeFocusSection>

      ### ❹ Test the integration

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={137} linesEnd={142} title="Make a test payment">
        To verify that your integration works, make a test payment using test payment details.

        **Payment succeeds**
        `4242 4242 4242 4242`

        **Payment requires authentication**
        `4000 0025 0000 3155`

        **Payment is declined**
        `4000 0000 0000 9995`
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={1} linesEnd={40} title="See your payment in the Dashboard">
        Navigate to the Stripe Dashboard to see your test payment.
      </CodeFocusSection>

      ### Accept payments and enhance your integration

      You're ready to accept payments with Stripe. Continue with the steps below to add more features.

      #### Calculate and collect the right amount of tax

      Calculate and collect the right amount of tax on your Stripe transactions. Learn more about Stripe Tax and how to add it to your Payments integration.

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={75} linesEnd={95} title="Use the Stripe Tax API to calculate tax">
        Use the Stripe Tax API to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

        Use the `tax_amount_exclusive` attribute of the resulting Tax Calculation to add the exclusive taxes to the order's total.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={188} linesEnd={203} title="Record a Tax Transaction upon successful Payment">
        Link the tax calculation to the PaymentIntent using `hooks[inputs][tax][calculation]`.

        This records the collected taxes in your Stripe account that you can later export for accounting purposes, and triggers other Stripe actions.
      </CodeFocusSection>

      #### Enable delayed payment methods

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={144} linesEnd={144} title="Allow delayed payment methods">
        Some payment methods can't guarantee that you'll receive funds from your customer at the end of the checkout because they take time to settle (for example, most bank debits, such as SEPA or ACH) or require customer action to complete (for example, OXXO, Konbini, Boleto). Use this flag to enable delayed payment methods.

        If you enable this feature, make sure your server integration listens to webhooks for notifications on whether payment has succeeded or not.
      </CodeFocusSection>

      #### Enable Google Pay

      <CodeFocusSection activeFilePath="android/AndroidManifest.xml" linesStart={1} linesEnd={6} title="Enable Google Pay API">
        To use Google Pay, first enable the Google Pay API in your AndroidManifest.xml.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={147} linesEnd={150} title="Configure Google Pay">
        Enable Google Pay by passing a `PaymentSheet.GooglePayConfiguration` object with the Google Pay environment (production or test) and the country code of your business when initializing `PaymentSheet.Configuration`.
      </CodeFocusSection>

      #### Customize the primary button

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={146} linesEnd={146} title="Custom primary button color">
        Consider using a custom color for the primary button that better matches your brand or app's visual identity.
      </CodeFocusSection>

      #### Enable card scanning

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={26} linesEnd={72} title="Add card scanning dependency">
        Card scanning can help increase your conversion rate by removing the friction of manual card entry. To enable card scanning, add stripecardscan to the dependencies block of your app/build.gradle file:

        **build.gradle:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.stripe:stripecardscan:22.6.1'
        ```
      </CodeFocusSection>

      #### Save payment details after payment

      Often used by SaaS or e-commerce businesses with recurring customers.

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={23} linesEnd={27} title="Import additional Stripe resources">
        Import the Stripe PaymentMethod and Customer models. Use these models to store information about your Customer.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={148} linesEnd={169} title="Create a customer">
        Stripe stores the card on an Account object representing the customer. Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={175} linesEnd={178} title="Add the customer to the PaymentIntent">
        Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method – certain regions, such as Europe and India, have requirements around reusing payment details.

        Learn more about the most effective way to apply `setup_future_usage`. You can also view a list of supported payment methods. After the PaymentIntent succeeds, Stripe automatically attaches the payment details (in a PaymentMethod object) to the customer-configured Account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={111} linesEnd={134} title="Charge the saved PaymentMethod">
        When you're ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.
      </CodeFocusSection>

      #### Collect local and international addresses

      <CodeFocusSection activeFilePath="android/CheckoutActivity.java" linesStart={41} linesEnd={51} title="Collect shipping or billing addresses">
        Collect local and international shipping or billing addresses from your customers.

        If you use the Address Element, you can optionally use the Google Places SDK to fetch address autocomplete suggestions. To enable autocomplete suggestions, add places to the dependency block of your app/build.gradle file:

        **build.gradle:**

        ```groovy theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
        implementation 'com.google.android.libraries.places:places:2.6.0'
        ```
      </CodeFocusSection>

      ### Next steps

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={1} linesEnd={40} title="Payouts">
        Learn how to move funds out of your Stripe account into your bank account.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={1} linesEnd={40} title="Refunds">
        Handle requests for refunds by using the Stripe API or Dashboard.
      </CodeFocusSection>

      <CodeFocusSection activeFilePath="src/main/java/com/stripe/sample/Server.java" linesStart={1} linesEnd={40} title="Fulfilment">
        Create an event destination to send events to your webhook endpoint to fulfil orders after a payment succeeds, and to handle other critical events.
      </CodeFocusSection>
    </FrameworkGuide>
  </Architecture>
</SideBySideLayout>
