Files
MTKJPAY/PAYPAL_WEBHOOK_GUIDE.md
qiube 7794accdeb feat(payment): 添加PayPal支付配置和订单状态更新功能
- 配置PayPal沙箱环境的Client ID和密钥
- 新增updatePaymentStatus方法用于更新订单支付状态
- 新增updateOrderStatus方法用于更新订单状态
- 实现支付状态更新时同步更新订单状态逻辑
- 添加详细的日志记录和异常处理机制
- 集成MyBatis Plus查询更新订单数据
2025-12-23 10:18:37 +08:00

171 lines
4.5 KiB
Markdown
Raw 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.
# PayPal Webhook处理指南
## 概述
PayPal Webhook是PayPal向你的服务器发送事件通知的机制。当支付状态发生变化时PayPal会主动推送事件到你的Webhook URL。
## Webhook URL配置
在你的PayPal开发者控制台中配置Webhook URL
- **开发环境**: `https://你的域名/api/paypal/webhook`
- **生产环境**: `https://你的生产域名/api/paypal/webhook`
## 支持的事件类型
系统已实现以下事件类型的处理:
### 1. PAYMENT.CAPTURE.COMPLETED
**触发时机**: 当PayPal成功捕获资金时触发
**处理逻辑**:
- 提取capture信息金额、货币、状态等
- 通过`supplementary_data.related_ids.order_id``custom_id`获取ERP订单号
- 更新ERP订单状态为"已支付"PAID
### 2. PAYMENT.CAPTURE.DENIED
**触发时机**: 当支付捕获被拒绝时触发
**处理逻辑**:
- 记录支付失败信息
- 更新ERP订单状态为"支付失败"
### 3. PAYMENT.CAPTURE.REFUNDED
**触发时机**: 当支付被退款时触发
**处理逻辑**:
- 记录退款信息
- 更新ERP订单状态为"已退款"
### 4. CHECKOUT.ORDER.APPROVED
**触发时机**: 当订单被顾客批准时触发
**处理逻辑**:
- 记录订单批准信息
- 可以触发自动捕获逻辑(如果需要)
### 5. CHECKOUT.ORDER.COMPLETED
**触发时机**: 当订单完成时触发
**处理逻辑**:
- 记录订单完成信息
- 根据业务需求处理订单完成逻辑
### 6. CHECKOUT.ORDER.CANCELLED
**触发时机**: 当订单被取消时触发
**处理逻辑**:
- 记录订单取消信息
- 更新ERP订单状态为"已取消"
## 签名验证
### 开发环境(沙箱)
- 签名验证可以暂时跳过(已实现自动跳过)
- 但建议在测试时也启用验证,确保代码正确
### 生产环境
- **必须启用签名验证**
- 需要在配置文件中设置`webhook-id`
- 系统会自动验证每个Webhook请求的签名
## 配置Webhook ID
### 1. 获取Webhook ID
1. 登录PayPal开发者控制台https://developer.paypal.com/dashboard/
2. 进入你的应用设置
3. 找到Webhook配置部分
4. 创建或查看Webhook获取Webhook ID
### 2. 配置到系统
`application-dev.yml``application-prod.yml`中添加:
```yaml
paypal:
webhook-id: YOUR_WEBHOOK_ID
```
## 订单号关联
PayPal Webhook事件中需要关联ERP订单号系统会按以下顺序尝试获取
1. **从`supplementary_data.related_ids.order_id`获取**
- 这是PayPal自动填充的包含原始订单ID
- 然后通过查询PayPal订单详情获取`reference_id`即ERP订单号
2. **从`custom_id`获取**
- 如果创建PayPal订单时设置了`custom_id`,可以直接获取
3. **通过`order_id`查询订单详情**
- 如果上述方法都无法获取会通过PayPal API查询订单详情
- 从订单的`purchase_units[0].reference_id`获取ERP订单号
## 测试Webhook
### 使用PayPal Webhook模拟器
1. 登录PayPal开发者控制台
2. 进入Webhook配置页面
3. 使用"Send test webhook"功能
4. 选择要测试的事件类型
5. 系统会收到测试事件并处理
### 本地测试
如果需要在本地测试,可以使用以下工具:
1. **ngrok**(推荐):
```bash
ngrok http 8082
```
然后将ngrok提供的URL配置到PayPal Webhook URL
2. **PayPal Webhook模拟器**:
使用Postman等工具模拟Webhook请求
## 日志查看
Webhook处理的所有步骤都会记录日志包括
- 接收到的Webhook事件
- 签名验证结果
- 事件处理过程
- 订单状态更新结果
查看日志位置:
- 应用日志文件
- 控制台输出
## 常见问题
### 1. Webhook未收到事件
- 检查Webhook URL是否正确配置
- 确认服务器可以访问(防火墙、网络等)
- 检查PayPal控制台中的Webhook状态
### 2. 签名验证失败
- 确认Webhook ID配置正确
- 检查请求头是否完整
- 确认使用的是正确的环境(沙箱/生产)
### 3. 无法关联ERP订单
- 确认创建PayPal订单时设置了`reference_id`
- 检查订单号格式是否正确
- 查看日志中的详细信息
## 安全建议
1. **生产环境必须启用签名验证**
2. **使用HTTPS**PayPal要求
3. **记录所有Webhook事件**(用于审计和调试)
4. **实现幂等性处理**(防止重复处理同一事件)
5. **设置超时和重试机制**
## 代码位置
- **Webhook控制器**: `PayPalController.webhook()`
- **Webhook服务**: `PayPalWebhookService` 和 `PayPalWebhookServiceImpl`
- **事件DTO**: `PayPalWebhookEventDTO`
- **配置**: `PayPalProperties.webhookId`