Files
eryao/.trellis/tasks/archive/05-11-creem-payment-integration/prd.md
T

5.4 KiB
Raw Blame History

PRD: CREEM Web Payment Integration

Background

iOS App 路线已放弃,需改用 CREEM (Merchant of Record) 进行 Web 端支付。现有 Apple IAP 代码保留但不再活跃使用。

Goals

  1. Web 端用户可通过 CREEM 托管支付页购买积分
  2. 商品价格从 CREEM API 动态获取,不在本地硬编码
  3. 支付成功后通过 webhook 自动发放积分
  4. 保留现有 Apple IAP 架构,不破坏

CREEM Product Mapping

内部 product_code CREEM Product ID 积分
new_user_pack prod_2x9LzVlR3ot1HLgbIZALPd 60
starter_pack prod_697ay0pXFXrBYEVC7HS0MR 100
popular_pack prod_5ivxlPnZWN6dIhnOxctThy 210
premium_pack prod_2L13k70jlpPYkdHhexHP2s 415

Pricing Notes

  • CREEM 最低支持 $1.00,因此新人专享包价格从原 $0.99 调整为 $1.00
  • 价格由 CREEM Dashboard 管理,后端通过 API 动态获取,不硬编码在 mapping.yaml 中
  • mapping.yaml 只存储: creem_product_id, credits, type, sort_order, enabled

Architecture

Payment Flow

Frontend                Backend                 CREEM
   |                      |                      |
   |-- GET /packages ---->|                      |
   |                      |-- GET /products ---->|
   |                      |<-- products list ----|
   |<-- packages+prices --|                      |
   |                      |                      |
   |-- POST /checkout --->|                      |
   |                      |-- POST /checkouts -->|
   |                      |<-- checkout_url -----|
   |<-- checkout_url -----|                      |
   |                      |                      |
   |-- redirect to CREEM checkout page --------->|
   |                      |                      |
   |                      |<-- webhook ----------|
   |                      |   (checkout.completed)
   |                      |   verify signature
   |                      |   grant credits      |
   |                      |                      |
   |-- success_url -------|                      |

API Endpoints

Method Endpoint Auth Description
POST /api/v1/payments/creem/checkouts User Create checkout session, return checkout_url
POST /api/v1/payments/creem/webhook None CREEM callback (verify signature)

Existing Endpoint Changes

Method Endpoint Change
GET /api/v1/points/packages Add priceCents and currency fields from CREEM API

Implementation Details

Phase 1: Backend Infrastructure

  1. settings.py - Add CreemSettings (api_key, webhook_secret, base_url, success_url)
  2. creem_client.py - HTTP client for CREEM API (get_products, create_checkout)
  3. models/creem_transaction.py - New DB table for CREEM transactions
  4. alembic migration - Create creem_transactions table
  5. repository.py - Add CREEM transaction CRUD methods

Phase 2: Backend Business Logic

  1. creem_service.py - Checkout creation + webhook handling
  2. service.py - Update ProductMapping to include creem_product_id
  3. schemas.py - Add CreateCheckoutRequest/Response, update PackageInfo with price fields
  4. dependencies.py - Add get_creem_service DI
  5. router.py - Add 2 new CREEM endpoints
  6. points/service.py - get_available_packages merges CREEM product prices

Phase 3: Frontend

  1. api.ts - Add createCheckout() function and types
  2. StorePage.tsx - Use dynamic price from API, add buy button that redirects to checkout_url

DB Schema: creem_transactions

Column Type Description
id UUID PK
user_id UUID FK
product_code String(32) Internal product code
creem_product_id String(128) CREEM product ID
checkout_id String(128) UNIQUE CREEM checkout session ID
order_id String(128) nullable CREEM order ID
customer_id String(128) nullable CREEM customer ID
status enum(pending, completed, failed, refunded)
credits BigInt Points to grant
amount_cents BigInt Payment amount in cents
currency String(8) Currency code
creem_payload JSONB Full CREEM webhook payload
ledger_event_id String(128) nullable Points ledger event ID
created_at, updated_at Timestamp

Environment Variables

ERYAO_CREEM_API_KEY=          # CREEM API key
ERYAO_CREEM_WEBHOOK_SECRET=   # Webhook signature verification secret (先占位,实现后配置)
ERYAO_CREEM_BASE_URL=https://test-api.creem.io  # test or production
ERYAO_CREEM_SUCCESS_URL=https://yourdomain.com/store?payment=success  # 支付成功跳转URL

Frontend Behavior

  1. 支付成功后跳转到 ERYAO_CREEM_SUCCESS_URL
  2. 前端检测 URL 参数 ?payment=success,显示成功提示并刷新积分
  3. 价格从后端 API 动态获取,不再使用翻译文件中的硬编码价格
  4. 翻译文件保留:套餐名称、描述、badge 文字(如"限购一次"、"推荐"

Security

  • Webhook must verify creem-signature HMAC-SHA256 header
  • API key never exposed to frontend
  • Checkout idempotency: prevent duplicate credit grants via checkout_id unique constraint
  • Starter pack eligibility check shared with Apple IAP logic

Out of Scope

  • CREEM subscription management (one-time purchases only)
  • CREEM license keys
  • Removing Apple IAP code (preserved for potential future use)
  • Customer portal integration