payment.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package routes
  2. import (
  3. "github.com/Wei-Shaw/sub2api/internal/handler"
  4. "github.com/Wei-Shaw/sub2api/internal/handler/admin"
  5. "github.com/Wei-Shaw/sub2api/internal/server/middleware"
  6. "github.com/Wei-Shaw/sub2api/internal/service"
  7. "github.com/gin-gonic/gin"
  8. )
  9. // RegisterPaymentRoutes registers all payment-related routes:
  10. // user-facing endpoints, webhook endpoints, and admin endpoints.
  11. func RegisterPaymentRoutes(
  12. v1 *gin.RouterGroup,
  13. paymentHandler *handler.PaymentHandler,
  14. webhookHandler *handler.PaymentWebhookHandler,
  15. adminPaymentHandler *admin.PaymentHandler,
  16. jwtAuth middleware.JWTAuthMiddleware,
  17. adminAuth middleware.AdminAuthMiddleware,
  18. auditLog middleware.AuditLogMiddleware,
  19. settingService *service.SettingService,
  20. panelRateLimiter *middleware.PanelRateLimiter,
  21. ) {
  22. // --- User-facing payment endpoints (authenticated) ---
  23. authenticated := v1.Group("/payment")
  24. authenticated.Use(gin.HandlerFunc(jwtAuth))
  25. authenticated.Use(middleware.BackendModeUserGuard(settingService))
  26. // 面板全局按用户限流
  27. authenticated.Use(panelRateLimiter.Global())
  28. {
  29. authenticated.GET("/config", paymentHandler.GetPaymentConfig)
  30. authenticated.GET("/checkout-info", paymentHandler.GetCheckoutInfo)
  31. authenticated.GET("/plans", paymentHandler.GetPlans)
  32. authenticated.GET("/limits", paymentHandler.GetLimits)
  33. orders := authenticated.Group("/orders")
  34. {
  35. orders.POST("", paymentHandler.CreateOrder)
  36. orders.POST("/verify", paymentHandler.VerifyOrder)
  37. orders.GET("/my", paymentHandler.GetMyOrders)
  38. orders.GET("/:id", paymentHandler.GetOrder)
  39. orders.POST("/:id/cancel", paymentHandler.CancelOrder)
  40. orders.POST("/:id/refund-request", paymentHandler.RequestRefund)
  41. orders.GET("/refund-eligible-providers", paymentHandler.GetRefundEligibleProviders)
  42. }
  43. }
  44. // --- Public payment endpoints (no auth) ---
  45. // Signed resume-token recovery is the preferred public lookup path.
  46. // The legacy anonymous out_trade_no verify endpoint remains available as a
  47. // persisted-state compatibility path for staggered upgrades.
  48. public := v1.Group("/payment/public")
  49. {
  50. public.POST("/orders/verify", paymentHandler.VerifyOrderPublic)
  51. public.POST("/orders/resolve", paymentHandler.ResolveOrderPublicByResumeToken)
  52. }
  53. // --- Webhook endpoints (no auth) ---
  54. webhook := v1.Group("/payment/webhook")
  55. {
  56. // EasyPay sends GET callbacks with query params
  57. webhook.GET("/easypay", webhookHandler.EasyPayNotify)
  58. webhook.POST("/easypay", webhookHandler.EasyPayNotify)
  59. webhook.POST("/alipay", webhookHandler.AlipayNotify)
  60. webhook.POST("/wxpay", webhookHandler.WxpayNotify)
  61. webhook.POST("/stripe", webhookHandler.StripeWebhook)
  62. webhook.POST("/airwallex", webhookHandler.AirwallexWebhook)
  63. }
  64. // --- Admin payment endpoints (admin auth) ---
  65. adminGroup := v1.Group("/admin/payment")
  66. adminGroup.Use(gin.HandlerFunc(adminAuth))
  67. adminGroup.Use(gin.HandlerFunc(auditLog))
  68. adminGroup.Use(middleware.AdminComplianceGuard(settingService))
  69. {
  70. // Dashboard
  71. adminGroup.GET("/dashboard", adminPaymentHandler.GetDashboard)
  72. // Config
  73. adminGroup.GET("/config", adminPaymentHandler.GetConfig)
  74. adminGroup.PUT("/config", adminPaymentHandler.UpdateConfig)
  75. // Orders
  76. adminOrders := adminGroup.Group("/orders")
  77. {
  78. adminOrders.GET("", adminPaymentHandler.ListOrders)
  79. adminOrders.GET("/:id", adminPaymentHandler.GetOrderDetail)
  80. adminOrders.POST("/:id/cancel", adminPaymentHandler.CancelOrder)
  81. adminOrders.POST("/:id/retry", adminPaymentHandler.RetryFulfillment)
  82. adminOrders.POST("/:id/refund", adminPaymentHandler.ProcessRefund)
  83. adminOrders.POST("/:id/refund/query", adminPaymentHandler.QueryAndFinalizeRefund)
  84. }
  85. // Subscription Plans
  86. plans := adminGroup.Group("/plans")
  87. {
  88. plans.GET("", adminPaymentHandler.ListPlans)
  89. plans.POST("", adminPaymentHandler.CreatePlan)
  90. plans.PUT("/:id", adminPaymentHandler.UpdatePlan)
  91. plans.DELETE("/:id", adminPaymentHandler.DeletePlan)
  92. }
  93. // Provider Instances
  94. providers := adminGroup.Group("/providers")
  95. {
  96. providers.GET("", adminPaymentHandler.ListProviders)
  97. providers.POST("", adminPaymentHandler.CreateProvider)
  98. providers.PUT("/:id", adminPaymentHandler.UpdateProvider)
  99. providers.DELETE("/:id", adminPaymentHandler.DeleteProvider)
  100. }
  101. }
  102. }