Files
plates-server/docs/app-store-server-notifications.md
2025-08-13 15:17:33 +08:00

190 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# App Store 服务器通知接收接口
## 概述
本接口用于接收来自苹果App Store的服务器通知App Store Server Notifications V2处理用户订阅状态的变化包括订阅、续订、过期、退款等事件。
## 接口地址
```
POST /api/users/app-store-notifications
```
## 配置要求
### 1. 在App Store Connect中配置
1. 登录 [App Store Connect](https://appstoreconnect.apple.com)
2. 选择你的应用
3. 在左侧菜单中选择 "App信息"
4. 滚动到 "App Store服务器通知" 部分
5. 设置生产环境URL`https://your-domain.com/api/users/app-store-notifications`
6. 设置沙盒环境URL`https://your-domain.com/api/users/app-store-notifications`
7. 选择 "Version 2" 通知格式
8. 保存设置
### 2. 环境变量配置
确保以下环境变量已正确设置:
```bash
# Apple相关配置
APPLE_BUNDLE_ID=com.yourcompany.yourapp
APPLE_KEY_ID=your_key_id
APPLE_ISSUER_ID=your_issuer_id
APPLE_PRIVATE_KEY_PATH=path/to/your/private/key.p8
APPLE_APP_SHARED_SECRET=your_shared_secret
```
## 请求格式
### 请求头
```
Content-Type: application/json
```
### 请求体
```json
{
"signedPayload": "eyJhbGciOiJFUzI1NiIsImtpZCI6IjEyMzQ1Njc4OTAiLCJ0eXAiOiJKV1QifQ..."
}
```
## 响应格式
### 成功响应
```json
{
"code": 200,
"message": "通知处理成功",
"data": {
"processed": true,
"notificationType": "SUBSCRIBED",
"notificationUUID": "12345678-1234-1234-1234-123456789012",
"userId": "user_12345",
"transactionId": "1000000123456789"
}
}
```
### 错误响应
```json
{
"code": 500,
"message": "处理通知失败: 无法解码通知负载",
"data": {
"processed": false
}
}
```
## 支持的通知类型
### 1. SUBSCRIBED订阅
- **描述**: 用户首次订阅或重新订阅
- **处理**: 更新用户的订阅状态和到期时间
### 2. DID_RENEW续订
- **描述**: 订阅成功续订
- **处理**: 延长用户的订阅到期时间
### 3. EXPIRED过期
- **描述**: 订阅已过期
- **处理**: 可以发送邮件通知或降级用户权限
### 4. DID_FAIL_TO_RENEW续订失败
- **描述**: 订阅续订失败(通常是支付问题)
- **处理**: 发送付款提醒或进入宽限期
### 5. REFUND退款
- **描述**: 用户获得退款
- **处理**: 立即撤销用户的订阅权限
### 6. REVOKE撤销
- **描述**: 通过家庭共享获得的权限被撤销
- **处理**: 撤销用户的订阅权限
### 7. DID_CHANGE_RENEWAL_STATUS续订状态变更
- **描述**: 用户更改了自动续订设置
- **处理**: 记录用户的续订偏好
### 8. TEST测试
- **描述**: 测试通知
- **处理**: 仅记录日志,无特殊处理
## 安全考虑
### 1. 签名验证
- 接口会验证通知的JWS签名
- 确保通知来自苹果官方服务器
- 验证bundleId匹配
### 2. 重复处理
- 建议实现幂等性处理
- 根据notificationUUID去重
- 避免重复处理相同通知
### 3. 错误处理
- 对于无法处理的通知返回适当的HTTP状态码
- 苹果会根据响应状态码决定是否重试
## 日志记录
接口会记录以下信息:
- 收到的通知类型和UUID
- 解码后的交易信息
- 处理结果和任何错误
- 用户ID和交易ID如果可用
## 测试
### 1. 使用App Store Connect测试
1. 在App Store Connect中请求测试通知
2. 检查服务器日志确认收到通知
3. 验证通知处理逻辑是否正确
### 2. 沙盒环境测试
1. 使用沙盒环境进行购买测试
2. 观察通知是否正确触发
3. 验证用户状态是否正确更新
## 故障排除
### 常见问题
1. **收不到通知**
- 检查App Store Connect中的URL配置
- 确保服务器可以从外网访问
- 检查防火墙设置
2. **通知解码失败**
- 验证私钥文件路径和格式
- 检查环境变量配置
- 确认bundleId匹配
3. **用户状态未更新**
- 检查appAccountToken是否正确设置
- 验证用户ID映射逻辑
- 查看数据库更新日志
### 日志查看
```bash
# 查看相关日志
grep "App Store" /path/to/your/logs/app.log
grep "processAppStoreNotification" /path/to/your/logs/app.log
```
## 扩展功能
可以根据业务需求扩展以下功能:
1. **邮件通知**: 在特定事件发生时发送邮件
2. **数据分析**: 收集订阅数据用于分析
3. **第三方集成**: 将事件发送到其他系统
4. **自定义业务逻辑**: 根据不同的通知类型执行特定操作
## 相关文档
- [App Store Server Notifications](https://developer.apple.com/documentation/appstoreservernotifications)
- [App Store Server API](https://developer.apple.com/documentation/appstoreserverapi)
- [StoreKit 2](https://developer.apple.com/documentation/storekit)