package payment import ( "context" "errors" ) // Channel codes used in API body `channel`. const ( ChannelWechat = "wechat" ChannelAlipay = "alipay" ChannelBank = "bank" ) // Client scenes used in API body `client`. const ( ClientMiniProgram = "mini_program" ClientApp = "app" ClientH5 = "h5" ) var ( ErrUnsupportedChannel = errors.New("unsupported payment channel") ErrUnsupportedClient = errors.New("unsupported payment client for channel") ErrNotImplemented = errors.New("payment channel not implemented") ) // PrepayRequest is channel-agnostic prepay input. type PrepayRequest struct { OutTradeNo string Description string AmountFen int64 Currency string NotifyURL string Attach string // Payer identity: WeChat uses OpenID; Alipay uses BuyerID. OpenID string BuyerID string Extra map[string]string } // PrepayResult holds client-side invoke params (JSON-serializable). type PrepayResult struct { PrepayID string `json:"prepay_id,omitempty"` Payload map[string]any `json:"payload"` } // RefundRequest is channel-agnostic refund input. type RefundRequest struct { OutTradeNo string TransactionID string OutRefundNo string Reason string NotifyURL string RefundFen int64 TotalFen int64 Currency string } // RefundResult is channel-agnostic refund output. type RefundResult struct { RefundID string `json:"refund_id"` OutRefundNo string `json:"out_refund_no"` TransactionID string `json:"transaction_id"` OutTradeNo string `json:"out_trade_no"` Status string `json:"status"` } // NotifyResult is a normalized pay-success notify. type NotifyResult struct { OutTradeNo string `json:"out_trade_no"` TransactionID string `json:"transaction_id"` TradeState string `json:"trade_state"` AmountFen int64 `json:"amount_fen"` Success bool `json:"success"` Attach string `json:"attach,omitempty"` } // Channel abstracts WeChat / Alipay / bank card providers. type Channel interface { Name() string Prepay(ctx context.Context, client string, req *PrepayRequest) (*PrepayResult, error) Refund(ctx context.Context, req *RefundRequest) (*RefundResult, error) ParsePayNotify(ctx context.Context, headers map[string]string, body []byte) (*NotifyResult, error) }