package payment import ( "context" "encoding/json" "fmt" ) // Service 支付业务层,内部封装 Client,对外暴露方法 type Service struct { client *Client cfg Config } // NewService 创建支付服务 func NewService(cfg Config) *Service { return &Service{ client: NewClient(cfg), cfg: cfg, } } // GetClient 获取底层 HTTP 客户端(供高级用法) func (s *Service) GetClient() *Client { return s.client } // Login 登录授权,获取 access_token func (s *Service) Login(ctx context.Context) (map[string]any, error) { token, err := s.client.GetToken(ctx) if err != nil { return nil, err } return map[string]any{ "success": true, "access_token": token.AccessToken, "expires_in": token.ExpiresIn, "message": "授权成功", }, nil } // CheckAuth 查询授权状态 func (s *Service) CheckAuth(ctx context.Context) (map[string]any, error) { token, err := s.client.GetToken(ctx) if err != nil { return map[string]any{"success": false, "message": "授权失效,请重新登录"}, err } return map[string]any{ "success": true, "access_token": token.AccessToken, "expires_in": token.ExpiresIn, "message": "授权有效", }, nil } // Refresh 主动刷新令牌 func (s *Service) Refresh(ctx context.Context) (map[string]any, error) { token, err := s.client.RefreshToken(ctx) if err != nil { return nil, err } return map[string]any{ "success": true, "access_token": token.AccessToken, "expires_in": token.ExpiresIn, "message": "续期成功", }, nil } // GetAccountInfo 获取授权账号信息 func (s *Service) GetAccountInfo(ctx context.Context) (map[string]any, error) { raw, err := s.client.Get(ctx, "/v1/account/info", nil) if err != nil { return nil, fmt.Errorf("get account info: %w", err) } return parseAPIResponse(raw) } // QueryOrder 通过 order_id 查询订单 func (s *Service) QueryOrder(ctx context.Context, orderID string) (map[string]any, error) { raw, err := s.client.Get(ctx, "/v1/orders/"+orderID, nil) if err != nil { return nil, fmt.Errorf("query order: %w", err) } return parseAPIResponse(raw) } // QueryOrderByOutNo 通过商户订单号查询 func (s *Service) QueryOrderByOutNo(ctx context.Context, outTradeNo string) (map[string]any, error) { raw, err := s.client.Get(ctx, "/v1/orders", map[string]string{"out_trade_no": outTradeNo}) if err != nil { return nil, fmt.Errorf("query order by out_no: %w", err) } return parseAPIResponse(raw) } // RequestRefund 申请退款 func (s *Service) RequestRefund(ctx context.Context, req map[string]any) (map[string]any, error) { raw, err := s.client.Post(ctx, "/v1/refunds", nil, req) if err != nil { return nil, fmt.Errorf("request refund: %w", err) } return parseAPIResponse(raw) } // GetBill 分页获取账单 func (s *Service) GetBill(ctx context.Context, page, pageSize int) (map[string]any, error) { params := map[string]string{ "page": fmt.Sprintf("%d", page), "page_size": fmt.Sprintf("%d", pageSize), } raw, err := s.client.Get(ctx, "/v1/bills", params) if err != nil { return nil, fmt.Errorf("get bill: %w", err) } return parseAPIResponse(raw) } // GetBillByDate 按日期范围查账单 func (s *Service) GetBillByDate(ctx context.Context, startDate, endDate string) (map[string]any, error) { params := map[string]string{ "start_date": startDate, "end_date": endDate, } raw, err := s.client.Get(ctx, "/v1/bills/range", params) if err != nil { return nil, fmt.Errorf("get bill by date: %w", err) } return parseAPIResponse(raw) } // ───────────────────────────────────────────── // 内部辅助 // ───────────────────────────────────────────── func parseAPIResponse(raw []byte) (map[string]any, error) { var result struct { Code int `json:"code"` Message string `json:"message"` Data interface{} `json:"data"` } if err := json.Unmarshal(raw, &result); err != nil { return nil, err } if result.Code != 0 { return nil, fmt.Errorf("api error code=%d msg=%s", result.Code, result.Message) } return map[string]any{"success": true, "data": result.Data, "message": result.Message}, nil }