# 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`