package handler import ( "io" "net/http" "kra/app/system/internal/dto" "kra/app/system/internal/service" "kra/app/system/internal/transport/httpx" "github.com/gin-gonic/gin" ) type Payment struct{ service *service.PaymentService } func NewPayment(service *service.PaymentService) *Payment { return &Payment{service: service} } func (h *Payment) Configs(c *gin.Context) { v, err := h.service.Configs(c.Request.Context()) if err != nil { httpx.Fail(c, err.Error()) return } httpx.OKWithData(c, v) } func (h *Payment) SaveConfig(c *gin.Context) { var req dto.PaymentConfigRequest if err := c.ShouldBindJSON(&req); err != nil { httpx.Fail(c, err.Error()) return } if err := h.service.SaveConfig(c.Request.Context(), &req); err != nil { httpx.Fail(c, err.Error()) return } httpx.OK(c) } func (h *Payment) Order(c *gin.Context) { var req dto.PaymentQueryRequest if err := c.ShouldBindJSON(&req); err != nil { httpx.Fail(c, err.Error()) return } order, err := h.service.Order(c.Request.Context(), req.Provider, req.TradeNo) if err != nil { httpx.Fail(c, err.Error()) return } httpx.OKWithData(c, order) } func (h *Payment) Orders(c *gin.Context) { var req dto.PaymentOrderListRequest if err := c.ShouldBindQuery(&req); err != nil { httpx.Fail(c, err.Error()) return } items, total, page, pageSize, err := h.service.Orders(c.Request.Context(), &req) if err != nil { httpx.Fail(c, err.Error()) return } httpx.Write(c, httpx.CodeSuccess, httpx.PageResult{List: items, Total: total, Page: page, PageSize: pageSize}, "获取成功") } func (h *Payment) Create(c *gin.Context) { var req dto.PaymentRequest if err := c.ShouldBindJSON(&req); err != nil { httpx.Fail(c, err.Error()) return } req.ClientIP = c.ClientIP() result, err := h.service.Create(c.Request.Context(), &req) if err != nil { httpx.Fail(c, err.Error()) return } httpx.OKWithData(c, result) } func (h *Payment) Query(c *gin.Context) { var req dto.PaymentQueryRequest if err := c.ShouldBindJSON(&req); err != nil { httpx.Fail(c, err.Error()) return } result, err := h.service.Query(c.Request.Context(), &req) if err != nil { httpx.Fail(c, err.Error()) return } httpx.OKWithData(c, result) } func (h *Payment) Refund(c *gin.Context) { var req dto.PaymentRefundRequest if err := c.ShouldBindJSON(&req); err != nil { httpx.Fail(c, err.Error()) return } result, err := h.service.Refund(c.Request.Context(), &req) if err != nil { httpx.Fail(c, err.Error()) return } httpx.OKWithData(c, result) } func (h *Payment) Callback(c *gin.Context) { c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, 8<<20) raw, err := io.ReadAll(c.Request.Body) if err != nil { writePaymentCallbackAck(c, service.DefaultPaymentCallbackAck(c.Param("provider"), false)) return } headers := map[string]string{} for k, v := range c.Request.Header { if len(v) > 0 { headers[k] = v[0] } } query := map[string]string{} for k, v := range c.Request.URL.Query() { if len(v) > 0 { query[k] = v[0] } } ack, err := h.service.Callback(c.Request.Context(), &dto.PaymentCallbackRequest{Provider: c.Param("provider"), Headers: headers, Body: raw, Query: query}) writePaymentCallbackAck(c, ack) _ = err } func writePaymentCallbackAck(c *gin.Context, ack dto.PaymentCallbackAck) { if ack.StatusCode == 0 { ack.StatusCode = http.StatusInternalServerError } if ack.ContentType != "" { c.Header("Content-Type", ack.ContentType) } c.Status(ack.StatusCode) if len(ack.Body) > 0 { _, _ = c.Writer.Write(ack.Body) } }