graph TD
A[接收 POST 请求] --> B[读取原始请求体]
B --> C{验证签名}
C -->|失败| D[返回 400 错误]
C -->|成功| E[解析 JSON 事件]
E -->|解析失败| D
E -->|成功| F[提取事件类型和元数据]
F --> G{事件类型判断}
G -->|checkout.completed| H[从 checkout 对象提取数据]
G -->|subscription.paid| I[从 subscription 对象提取数据]
G -->|subscription.active| J{是否订阅类型?}
J -->|是| K[更新订阅状态为 active]
J -->|否| L[返回 received]
K --> L
H --> M{验证必需元数据}
I --> M
M -->|缺失| D
M -->|完整| N{检查幂等性}
N -->|已处理| L
N -->|未处理| O{支付类型判断}
O -->|一次性购买| P[计算一次性积分]
O -->|订阅| Q[计算订阅积分和排期]
P --> R[插入支付记录]
Q --> S[插入/更新订阅记录]
S --> R
R --> T[数据库事务开始]
T --> U[更新用户积分]
U --> V[记录积分账本]
V --> W{是否订阅?}
W -->|是| X{有排期?}
W -->|否| Y[事务提交]
X -->|是| Z[重置订阅排期]
X -->|否| AA[删除订阅排期]
Z --> Y
AA --> Y
Y --> AB[查询用户邮箱]
AB --> AC{发送购买确认邮件}
AC -->|失败| AD[记录错误但继续]
AC -->|成功| L
AD --> L
style D fill:#ffcccc
style L fill:#ccffcc