Skip to content

建立 2026-09-14 更新 2026-09-14

Checkout 託管頁

Checkout Session 是現在最推薦的寫法:你的網站只負責「這一筆要賣什麼、收多少錢」,付款畫面由 Stripe 託管(或嵌入你的頁面)。顧客卡號不會碰到你的伺服器。

官方文件:Build a Stripe-hosted checkout page。對應影片見 官方影音

流程

  1. 顧客在你的網站按「購買」。
  2. Flask 用 Secret key 建立 checkout.Session,帶入 line items、成功與取消網址。
  3. 回應 303,把瀏覽器導向 session.url
  4. 顧客在 Stripe 頁面付款。
  5. Stripe 呼叫你的 webhook,同時可能把人導回 success_url

Flask 完整範例

import os
import stripe
from flask import Flask, redirect, request, render_template_string

app = Flask(__name__)
stripe.api_key = os.environ["STRIPE_SECRET_KEY"]
DOMAIN = os.environ.get("DOMAIN", "http://localhost:4242")

INDEX = """
<form action="/create-checkout-session" method="POST">
  <button type="submit">購買電子書 NT$350</button>
</form>
"""

@app.get("/")
def index():
    return render_template_string(INDEX)

@app.post("/create-checkout-session")
def create_checkout_session():
    session = stripe.checkout.Session.create(
        mode="payment",
        line_items=[{
            "price_data": {
                "currency": "twd",
                "product_data": {"name": "電子書"},
                "unit_amount": 350,
            },
            "quantity": 1,
        }],
        success_url=DOMAIN + "/success?session_id={CHECKOUT_SESSION_ID}",
        cancel_url=DOMAIN + "/cancel",
        metadata={"sku": "ebook-001"},  # 之後 webhook 用來對訂單
    )
    return redirect(session.url, code=303)

@app.get("/success")
def success():
    return "付款流程已完成。出貨請等 webhook。"

@app.get("/cancel")
def cancel():
    return "已取消。"

{CHECKOUT_SESSION_ID} 是 Stripe 會替換的佔位字串,成功頁可用它向 API 再查一次 Session,僅供顯示。出貨仍以 webhook 為準。

參數在做什麼

參數 意義
mode="payment" 一次付清。訂閱改 "subscription"
line_items 品名、單價、數量。價格來自伺服器
success_url / cancel_url 付完或按返回後的網址
metadata 你自己的訂單編號,webhook 會原樣帶回
customer_email 可預填 email,非必填

固定商品更建議在 Dashboard 建好 Product / Price,程式只傳 price="price_xxx",避免售價散落在程式各處。

嵌入自己的網站

不想把人帶走,可改 ui_mode 為嵌入式 Checkout,伺服器改回 client_secret,前端用 Stripe.js mount。觀念與 PaymentIntent 類似,但商品列、稅、折扣仍走 Checkout Session API。見 Embedded Checkout

下一步

沒有 webhook,這支程式只能「看起來付完了」。請接 Webhook 履約