# dotnet-paypal-demo **Repository Path**: idbb98/dotnet-paypal-demo ## Basic Information - **Project Name**: dotnet-paypal-demo - **Description**: 在 ASP.NET Core 中使用PayPal REST API集成 PayPal 支付功能示例 - **Primary Language**: C# - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-02-24 - **Last Updated**: 2026-03-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: dotNET, PayPal ## README # PayPal 集成演示项目 本项目是一个的 PayPal 支付集成示例,展示了如何在 ASP.NET Core 应用程序中安全地集成 PayPal 支付功能。它包含了从创建订单到处理支付回调、Webhook 通知以及完整的退款功能。 ## 🛠️ 技术栈 - **后端框架**:ASP.NET Core 8.0 - **API 版本**:PayPal REST API v2 - **前端框架**:Bootstrap 5 + jQuery ## 🏗️ 系统架构 ```mermaid graph TB A[用户发起支付] --> B[后端创建 PayPal 订单] B --> C[返回批准 URL] C --> D[前端打开 PayPal 弹窗] D --> E[用户在 PayPal 授权] E --> F[重定向回应用] F --> G[捕获支付] G --> H[完成支付] I[PayPal Webhook] --> J[验证签名] J --> K[处理事件] K --> L[更新本地状态] M[用户发起退款] --> N[创建退款请求] N --> O[本地记录存储] O --> P[Webhook 状态更新] ``` ## 📁 项目结构 ``` PayPalIntegrationDemo/ ├── Controllers/ │ ├── HomeController.cs # 主页控制器 │ ├── PaymentController.cs # 支付相关控制器 │ └── RefundController.cs # 退款管理控制器 ├── Models/ │ ├── Configurations/ │ │ └── PayPalConfig.cs # PayPal 配置模型 │ ├── DTOs/ │ │ ├── PayPalCaptureResult.cs # 捕获结果 DTO │ │ ├── PayPalOrderResult.cs # 订单结果 DTO │ │ └── PayPalRefundResult.cs # 退款结果 DTO │ ├── Entities/ │ │ ├── PayPalOrderStatus.cs # 订单状态枚举 │ │ ├── PayPalRefundStatus.cs # 退款状态枚举 │ │ └── PayPalWebhookEvent.cs # Webhook 事件实体 │ └── ErrorViewModel.cs # 错误视图模型 ├── Services/ │ ├── IPayPalService.cs # PayPal 服务接口 │ └── PayPalService.cs # PayPal 服务实现 ├── Views/ │ ├── Home/ │ │ ├── Index.cshtml # 主页视图 │ │ └── Privacy.cshtml # 隐私政策页面 │ ├── Payment/ │ │ ├── Checkout.cshtml # 支付结账页面 │ │ ├── PaymentSuccess.cshtml # 支付成功页面 │ │ └── PaymentFailure.cshtml # 支付失败页面 │ ├── Refund/ │ │ └── Manage.cshtml # 退款管理页面 │ └── Shared/ │ └── _Layout.cshtml # 布局模板 ├── wwwroot/ │ ├── css/ │ │ ├── site.css # 主样式文件 │ │ └── refund-management.css # 退款管理专用样式 │ ├── js/ │ │ └── site.js # 主要 JavaScript 文件 │ └── lib/ # 第三方库 ├── docs/ │ └── payment-sequence-diagram.puml # 支付时序图 │ └── payment-sequence-diagram.svg # 支付时序图svg格式 ├── Properties/ │ └── launchSettings.json # 启动配置 ├── appsettings.json # 应用配置 ├── Program.cs # 应用入口点 └── PayPalIntegrationDemo.csproj # 项目文件 ``` ## ⚙️ 配置要求 ### PayPal 凭据配置 在 `appsettings.json` 文件中配置 PayPal 凭据: ```json { "PayPal": { "ActiveEnvironment": "Sandbox", "Sandbox": { "ClientId": "your-sandbox-client-id", "ClientSecret": "your-sandbox-client-secret", "BaseUrl": "https://api.sandbox.paypal.com" }, "Production": { "ClientId": "your-production-client-id", "ClientSecret": "your-production-client-secret", "BaseUrl": "https://api.paypal.com" }, "WebhookId": "your-webhook-id", "WebhookSecret": "your-webhook-secret", "ReturnUrl": "https://yoursite.com/Payment/PayPalReturn", "CancelUrl": "https://yoursite.com/Payment/PayPalCancel" } } ``` > 为安全性考虑,建议使用环境变量 ## 🎯 核心功能详解 ### 1. 支付功能 #### 创建 PayPal 订单 ```csharp var orderResult = await _payPalService.CreateOrderAsync( amount: 100.00m, currency: "USD", description: "商品描述", correlationId: "unique-request-id" // 幂等性控制 ); ``` #### 捕获支付 ```csharp var captureResult = await _payPalService.CapturePaymentAsync(orderId); ``` #### 获取订单状态 ```csharp var orderStatus = await _payPalService.GetOrderStatusAsync(orderId); ``` ### 2. Webhook 功能 #### Webhook 验证 ```csharp var isValid = await _payPalService.ValidateWebhookNotificationAsync( webhookId, certUrl, authAlgo, transmissionId, signature, timestamp, requestBody ); ``` #### Webhook 事件处理 ```csharp var webhookEvent = _payPalService.ParseWebhookEvent(requestBody); // 处理不同类型的事件 switch(webhookEvent.EventType) { case "PAYMENT.CAPTURE.COMPLETED": // 处理支付完成事件 break; case "PAYMENT.CAPTURE.REFUNDED": // 处理退款事件 break; // ... 更多事件类型 } ``` ### 3. 退款功能 #### 创建退款 (多策略验证) ```csharp // 1. 先查询现有退款记录 var existingRefunds = await _payPalService.GetActualRefundsForCaptureAsync(captureId); // 2. 计算剩余可退款金额 var remainingAmount = await _payPalService.CalculateRemainingRefundableAmountAsync(captureId); // 3. 验证退款金额 if (amount > remainingAmount) { throw new InvalidOperationException("退款金额超过剩余可退金额"); } // 4. 创建退款 var refundResult = await _payPalService.CreateRefundAsync( captureId: captureId, amount: amount, currency: "USD", description: "退款原因", correlationId: "refund-request-id" // 幂等性控制 ); ``` #### 查询退款状态 ```csharp var refundStatus = await _payPalService.GetRefundStatusAsync(refundId); ``` #### 获取退款详情 ```csharp var refundDetails = await _payPalService.GetRefundDetailsAsync(refundId); ``` #### 列出退款记录 (多数据源整合) ```csharp var refunds = await _payPalService.ListRefundsAsync(captureId); // 内部实现整合了: // 1. 本地数据库存储的退款记录 // 2. PayPal Webhook 事件通知 // 3. 捕获状态推断信息 ``` #### 计算剩余可退款金额 ```csharp var remainingAmount = await _payPalService.CalculateRemainingRefundableAmountAsync(captureId); ``` ## 退款记录查询规范 系统严格遵循退款记录查询规范,结合三个数据源确保数据完整性: 1. **本地数据库存储**(主数据源) 2. **PayPal Webhook 事件通知**(实时更新) 3. **捕获状态推断**(备用方案) ⚠️ **重要提示**:只有将退款记录保存到本地数据库,才能保证历史记录的完整性和可追溯性。 ## API 接口 ### 支付相关接口 | 方法 | 路径 | 描述 | |------|------|------| | POST | `/Payment/InitiatePayPalPayment` | 启动 PayPal 支付流程 | | GET | `/Payment/PayPalReturn` | 处理 PayPal 支付成功返回 | | GET | `/Payment/PayPalCancel` | 处理 PayPal 支付取消返回 | | POST | `/Payment/Webhook` | 处理 PayPal Webhook 通知 | ### 退款相关接口 | 方法 | 路径 | 描述 | |------|------|------| | POST | `/Refund/RequestRefund` | 发起退款请求 | | GET | `/Refund/GetRefundStatus` | 查询退款状态 | | GET | `/Refund/GetRefundDetails` | 获取退款详情 | | GET | `/Refund/ListRefunds` | 列出退款记录(多数据源整合)| | GET | `/Refund/GetPartialRefunds` | 获取部分退款记录 | | GET | `/Refund/GetRemainingRefundableAmount` | 计算剩余可退款金额 | ## 🚀 快速开始 ### 1. 克隆项目 ``` git clone https://github.com/yourusername/PayPalIntegrationDemo.git cd PayPalIntegrationDemo ``` ### 2. 配置 PayPal 凭据 编辑 `appsettings.json` 文件,填入您的 PayPal 凭据。 ### 3. 构建和运行 ``` dotnet build dotnet run ``` ### 4. 访问应用 打开浏览器访问 `https://localhost:5001` ## 📊 文档资源 ### 📈 时序图 ![支付时序图](docs/payment-sequence-diagram.svg) ## 🤝 贡献指南 欢迎提交 Issue 和 Pull Request 来改进此项目: 1. Fork 项目 2. 创建功能分支 3. 提交更改 4. 推送到分支 5. 创建 Pull Request ## 📄 许可证 本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情。 ## 📞 支持 如有问题,请提交 Issue 或联系项目维护者。