Documentation
¶
Overview ¶
Package pay360 封装 360 联运(软件管家)开放平台 OPENAPI 的服务端接口。
它面向需要对接 360 联运支付/退款/订单/代扣/签约/发票的 Go 服务端程序, 统一处理签名生成、access_token 生命周期、Header-Tid 排障头与错误码语义。
快速开始:
c, err := pay360.New("your-appid", 123456, "your-appsecret")
if err != nil {
// 处理构造错误
}
tid, err := c.Refund(ctx, pay360.RefundRequest{
OrderID: "order-1",
OrderAmount: 100, // 单位:分
UserID: "user-1",
RefundReason: "用户申请退款",
})
access_token 由 Client 内部缓存并按需刷新;默认实现为无锁内存缓存, 多实例部署可通过 WithTokenCache 注入共享存储实现,详见 TokenCache。
Client 构造后字段只读,可安全地在多个 goroutine 间共享。
Index ¶
- Constants
- Variables
- type APIError
- type Ack
- type Callback
- type CancelSignRequest
- type Client
- func (c *Client) CancelSign(ctx context.Context, req CancelSignRequest) (headerTid string, err error)
- func (c *Client) ComplainFinish(ctx context.Context, req ComplainFinishRequest) (headerTid string, err error)
- func (c *Client) ComplainReply(ctx context.Context, req ComplainReplyRequest) (headerTid string, err error)
- func (c *Client) DoPost(ctx context.Context, req DoPostRequest) (headerTid string, err error)
- func (c *Client) PlainInvoice(ctx context.Context, req PlainInvoiceRequest) (PlainInvoiceResult, error)
- func (c *Client) PlainInvoiceCancel(ctx context.Context, orderID string) (headerTid string, err error)
- func (c *Client) QueryOrder(ctx context.Context, req OrderQueryRequest) (OrderQueryResponse, error)
- func (c *Client) QuerySpecialInvoice(ctx context.Context, requestType, sourceID string) (SpecialInvoiceQueryResult, error)
- func (c *Client) Refund(ctx context.Context, req RefundRequest) (headerTid string, err error)
- func (c *Client) RefundOrders(ctx context.Context, req RefundOrdersRequest) (headerTid string, err error)
- func (c *Client) SpecialInvoice(ctx context.Context, req SpecialInvoiceRequest) (SpecialInvoiceResult, error)
- func (c *Client) SpecialInvoiceCancel(ctx context.Context, req SpecialInvoiceCancelRequest) (headerTid string, err error)
- func (c *Client) VerifyCallback(body []byte) (*Callback, error)
- func (c *Client) VerifyComplaintWebhook(body []byte) (*ComplaintWebhook, error)
- type ComplainFinishRequest
- type ComplainInfo
- type ComplainReplyInfo
- type ComplainReplyRequest
- type ComplaintWebhook
- type CreateOrderParams
- type DoPostRequest
- type Option
- func WithBaseURL(u string) Option
- func WithClock(now func() time.Time) Option
- func WithHTTPClient(h *httpc.Client) Option
- func WithTokenCache(tc TokenCache) Option
- func WithTokenRefreshAhead(d time.Duration) Option
- func WithTokenRefreshLock(l TokenRefreshLock) Option
- func WithVendorKey(k string) Option
- type OrderExtra
- type OrderQueryRequest
- type OrderQueryResponse
- type PlainInvoiceRequest
- type PlainInvoiceResult
- type RefundOrdersRequest
- type RefundRequest
- type SpecialInvoiceCancelRequest
- type SpecialInvoiceQueryResult
- type SpecialInvoiceRequest
- type SpecialInvoiceResult
- type TokenCache
- type TokenRefreshLock
Examples ¶
Constants ¶
const ( CallbackOrderStatus = 1 // 订单状态变更(普通下单扣款、退款) CallbackAutopay = 2 // 代扣推送(自动扣款),需厂商据 order_extra 创建订单 CallbackSign = 3 // 签约/取消签约状态通知,无需下发或取消权益 )
回调类型。
const ( AutoPayStatusOpen = 1 // 开通签约 AutoPayStatusCancel = 2 // 取消签约 )
签约状态(OrderExtra.AutoPayStatus / callback_type=3)。
const ( ComplainStatusPending = 1 // 待处理 ComplainStatusProcessing = 2 // 处理中 ComplainStatusFinished = 3 // 已完结 ComplainStatusUnfinished = 4 // 未完结/兼容值 )
投诉状态(complain_info.currStatus)。
const ( ComplainPlatformOther = 1 // 其他/未知 ComplainPlatformAlipay = 2 // 支付宝 ComplainPlatformWechat = 3 // 微信 ComplainPlatformAlipaySpecial = 4 // 支付宝特殊版 )
投诉来源平台(complain_info.platForm)。
const ( ComplainSourceNormal = 1 // 普通回复 ComplainSourceRefund = 2 // 退款相关回复 )
投诉回复来源(ComplainReplyRequest.Source)。
const ( ComplaintEventCreated = "COMPLAINT_CREATED" // 新投诉创建 ComplaintEventReplyAdded = "REPLY_ADDED" // 投诉新增回复 ComplaintEventStatusChanged = "STATUS_CHANGED" // 投诉状态发生变化 )
投诉 webhook 事件类型(ComplaintWebhook.EventType)。
const ( OrderStatusPending = 10 // 待付款(初始状态) OrderStatusPaid = 20 // 付款完成(待通知厂商) OrderStatusNotified = 30 // 待厂商发权益(已通知厂商) OrderStatusAfterSale = 40 // 售后中(厂商发起退款) OrderStatusCompleted = 50 // 交易完成(厂商已发放) OrderStatusCanceled = 60 // 已取消(支付超时、过期等) OrderStatusClosed = 70 // 交易关闭(退款完成) )
订单状态码(order_status,用于订单查询响应与订单推送回调)。
其中 20、30、50 均视为支付成功状态(见 OrderQueryResponse.IsPaid)。
const ( PayChannelTask = -1 // 任务单 PayChannelWechat = 1 // 微信 PayChannelAlipay = 2 // 支付宝 PayChannelAlipayAutopay = 3 // 支付宝代扣单 )
支付渠道(pay_channel / pay_chanel)。
const ( PeriodTypeDay = 0 // 扣款周期按天计 PeriodTypeMonth = 1 // 扣款周期按自然月计 )
代扣周期类型(period_type)。
const ( OrderPayTypeNormal = 0 // 付费单 OrderPayTypeTask = 3 // 任务单 )
订单类型(order_pay_type)。
const ( AutoPayDisabled = 0 // 不开启代扣 AutoPayEnabled = 1 // 开启代扣 )
是否开启代扣(createOrder 的 auto_pay_status)。
注意:与回调 order_extra 中的 auto_pay_status(AutoPayStatusOpen/AutoPayStatusCancel, 表示签约/取消签约)语义不同。
const ( AutopayModeManager = 0 // 管家侧发起代扣续费订单(需固定扣款周期) AutopayModeVendor = 1 // 厂商侧发起代扣续费订单(厂商完全可控,经服务端代扣接口发起) )
代扣发起方(ext.autopay_mode)。
const ( SpecialInvoiceQueryIssue = "1" // 开票查询 SpecialInvoiceQueryCancel = "2" // 红冲查询 )
专票查询请求类型。
const ( InvoiceRedCategorySeller = "1" // 专票红冲类别:销方红冲 InvoiceRedReasonMistake = "INVOICE_MISTAKE" // 专票红冲原因(销方红冲必填) InvoiceCustomTypeEnterprise = "1" // 专票商户类型:企业 )
文档明确定义的发票取值常量。仅供组装请求时复用, 请求方法不据此封闭取值集合(文档未声明集合封闭)。
const Version = "v0.3.0"
Variables ¶
var ( ErrParam = &APIError{Code: 10001, Msg: "参数错误"} ErrInternal = &APIError{Code: 10002, Msg: "服务内部错误"} ErrSign = &APIError{Code: 10006, Msg: "sign 错误"} ErrRequestExpired = &APIError{Code: 10007, Msg: "请求过期"} ErrAccessToken = &APIError{Code: 10012, Msg: "access_token 错误"} ErrIllegalAccess = &APIError{Code: 10014, Msg: "非法访问"} ErrContentType = &APIError{Code: 10015, Msg: "不支持的 content_type"} ErrParamType = &APIError{Code: 10016, Msg: "参数类型错误"} ErrRateLimited = &APIError{Code: 10018, Msg: "触发限流"} ErrComplainNotFound = &APIError{Code: 10034, Msg: "投诉不存在"} ErrComplainReplyLimit = &APIError{Code: 10035, Msg: "投诉回复次数超限"} ErrAppNotFound = &APIError{Code: 100001, Msg: "应用信息不存在"} ErrAppOffline = &APIError{Code: 100002, Msg: "应用信息已下线"} ErrVendorNotFound = &APIError{Code: 100003, Msg: "厂商信息不存在"} ErrVendorOffline = &APIError{Code: 100004, Msg: "厂商信息已下线"} ErrOrderNotFound = &APIError{Code: 100005, Msg: "订单不存在"} ErrAppCategoryNotFound = &APIError{Code: 100006, Msg: "应用分类不存在"} ErrAuthInfo = &APIError{Code: 100008, Msg: "认证信息错误"} ErrOrderStatusInvalid = &APIError{Code: 100009, Msg: "订单状态有误,不允许进行此操作"} )
文档《360联运JSSDK集成说明》第四章错误码表对应的哨兵值。 仅携带 Code,用于 errors.Is 判定。
var ErrCallbackMismatch = errors.New("pay360: callback appid/qid mismatch")
ErrCallbackMismatch 表示回调验签通过但其中的 app_id/qid 与客户端凭据不一致, 调用方不应处理该回调(它属于其它应用)。
var ErrCallbackSign = errors.New("pay360: callback sign mismatch")
ErrCallbackSign 表示回调验签失败。
var ErrComplaintWebhookSign = errors.New("pay360: complaint webhook sign mismatch")
ErrComplaintWebhookSign 表示投诉 webhook 推送验签失败。
Functions ¶
This section is empty.
Types ¶
type APIError ¶
APIError 表示 360 平台返回的业务错误(errno 非 0,或部分网关接口的 code 非 0)。
可用 errors.Is 与本包导出的错误码哨兵比较,例如:
if errors.Is(err, pay360.ErrAccessToken) { /* token 失效,触发重试 */ }
HeaderTid 为本次响应头 Header-Tid 的值,便于向 360 反馈问题时快速定位。
type Ack ¶
type Ack struct {
Code int `json:"code"`
Message string `json:"message"`
Data string `json:"data"`
}
Ack 为厂商对订单推送回调的响应体。
func AckResponse ¶
AckResponse 返回自定义响应体(成功时 code 应为 200)。
Example ¶
out, _ := json.Marshal(AckResponse(500, "retry later", "job-1")) fmt.Println(string(out))
Output: {"code":500,"message":"retry later","data":"job-1"}
func AckSuccess ¶
func AckSuccess() Ack
AckSuccess 返回标准成功响应 {"code":200,"message":"success","data":""}。 360-Server 收到此响应后会将 order_status 由 30 变更为 50。
Example ¶
out, _ := json.Marshal(AckSuccess()) fmt.Println(string(out))
Output: {"code":200,"message":"success","data":""}
type Callback ¶
type Callback struct {
AppID string `json:"app_id"`
AgreementNumber string `json:"agreement_number"` // 签约号
AutoPayStatus int `json:"auto_pay_status"` // 签约状态:1 开通签约,2 取消签约
BankTradeCode string `json:"bank_trade_code"`
CallbackType int `json:"callback_type"`
MfrOrderAmount int64 `json:"mfr_order_amount"`
MfrOrderID string `json:"mfr_order_id"`
MfrProductID string `json:"mfr_product_id"`
MfrProductName string `json:"mfr_product_name"`
OrderCode string `json:"order_code"`
OrderExtra string `json:"order_extra"`
OrderStatus int `json:"order_status"`
PayChannel int `json:"pay_channel"`
Qid int64 `json:"qid"`
Sign string `json:"sign"`
Timestamp int64 `json:"timestamp"`
TransTime string `json:"trans_time"` // 支付/退款时间;签约、解约推送中不使用,为占位值 0001-01-01 00:00:00
// Extra 为 OrderExtra 字段解析后的结构(callback_type 为 2/3 时有意义)。
Extra OrderExtra `json:"-"`
}
Callback 为厂商订单推送回调的解析结果。
AgreementNumber 与 AutoPayStatus 为文档 4.1.2.4 参数表列出的顶层签约字段; 推送示例中同名信息也可能出现在 order_extra 内(见 Extra),两处独立解析。
func ParseCallback ¶
ParseCallback 解析厂商订单推送回调的请求体,并解析内嵌的 order_extra。 它不做验签;如需验签请使用 Client.VerifyCallback。
Example ¶
body := `{"callback_type":2,"mfr_order_id":"parent1","order_extra":"{\"mfr_order_id\":\"child1\"}"}`
cb, _ := ParseCallback([]byte(body))
fmt.Println(cb.CallbackType, cb.Extra.MfrOrderID)
Output: 2 child1
func (Callback) IsPaid ¶ added in v0.2.0
IsPaid 报告回调订单是否处于支付成功状态(order_status 为 20、30 或 50), 与 OrderQueryResponse.IsPaid 语义一致。
type CancelSignRequest ¶
CancelSignRequest 为厂商侧取消签约的参数。
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client 是 360 联运 OPENAPI 的服务端客户端。
构造后所有字段只读(token 缓存内部自带并发安全),可在多个 goroutine 间共享。
func New ¶
New 创建客户端。appid 与 appsecret 必填,qid 为厂商 ID。
默认使用官方域名、进程内内存 token 缓存与带连接池的默认 HTTP 客户端。 构造期不发起任何网络请求,也不启动后台 goroutine。
func (*Client) CancelSign ¶
func (c *Client) CancelSign(ctx context.Context, req CancelSignRequest) (headerTid string, err error)
CancelSign 厂商侧取消用户代扣签约。返回本次响应的 Header-Tid。
func (*Client) ComplainFinish ¶ added in v0.3.0
func (c *Client) ComplainFinish(ctx context.Context, req ComplainFinishRequest) (headerTid string, err error)
ComplainFinish 完结投诉(厂商确认投诉已处理完成后调用)。返回本次响应的 Header-Tid。
func (*Client) ComplainReply ¶ added in v0.3.0
func (c *Client) ComplainReply(ctx context.Context, req ComplainReplyRequest) (headerTid string, err error)
ComplainReply 回复用户投诉,回复内容会同步至对应投诉渠道。返回本次响应的 Header-Tid。
func (*Client) PlainInvoice ¶
func (c *Client) PlainInvoice(ctx context.Context, req PlainInvoiceRequest) (PlainInvoiceResult, error)
PlainInvoice 开具普通发票。
func (*Client) PlainInvoiceCancel ¶
func (c *Client) PlainInvoiceCancel(ctx context.Context, orderID string) (headerTid string, err error)
PlainInvoiceCancel 普票红冲(红冲对应订单的普通发票)。返回本次响应的 Header-Tid。
此接口响应采用 {code,msg} 信封(code 0 表示成功),与多数接口的 errno 信封不同。
func (*Client) QueryOrder ¶
func (c *Client) QueryOrder(ctx context.Context, req OrderQueryRequest) (OrderQueryResponse, error)
QueryOrder 查询订单详情。
注意:请勿通过客户端轮询此接口;SDK 本身会通过订单推送通知状态变更。
func (*Client) QuerySpecialInvoice ¶
func (c *Client) QuerySpecialInvoice(ctx context.Context, requestType, sourceID string) (SpecialInvoiceQueryResult, error)
QuerySpecialInvoice 查询专票开票或红冲进度。 requestType 取 SpecialInvoiceQueryIssue 或 SpecialInvoiceQueryCancel。
func (*Client) RefundOrders ¶ added in v0.3.0
func (c *Client) RefundOrders(ctx context.Context, req RefundOrdersRequest) (headerTid string, err error)
RefundOrders 申请订单退款(v2 接口),支持单笔与多笔。返回本次响应的 Header-Tid。
多笔时平台按逗号拆分去重逐笔处理,任一订单退款失败则本次请求返回失败。 通过任务系统完成的订单(任务单)不允许退款。退款成功后,如订单关联投诉且 关联订单均已关闭,平台会自动完结投诉。与 v1 Client.Refund 并存。
func (*Client) SpecialInvoice ¶
func (c *Client) SpecialInvoice(ctx context.Context, req SpecialInvoiceRequest) (SpecialInvoiceResult, error)
SpecialInvoice 申请开具专用发票,返回 source_id。建议保存返回信息以便后续查询/红冲。
func (*Client) SpecialInvoiceCancel ¶
func (c *Client) SpecialInvoiceCancel(ctx context.Context, req SpecialInvoiceCancelRequest) (headerTid string, err error)
SpecialInvoiceCancel 申请专票红冲。返回本次响应的 Header-Tid。
func (*Client) VerifyCallback ¶
VerifyCallback 验签并解析厂商订单推送回调。
验签规则与出站一致(空值不参与),签名盐为本客户端的 appsecret。 验签失败返回 ErrCallbackSign;验签通过但回调中的 app_id/qid 与客户端凭据 不一致时返回 ErrCallbackMismatch。金额与订单数据的一致性核对仍由调用方 在发放权益前完成(本包不持有订单数据)。
func (*Client) VerifyComplaintWebhook ¶ added in v0.3.0
func (c *Client) VerifyComplaintWebhook(body []byte) (*ComplaintWebhook, error)
VerifyComplaintWebhook 验签并解析投诉 webhook 推送。
验签规则与 OPENAPI 一致,但参与签名的字段仅有 data 与 timestamp,且 data 取 请求原文中的 JSON 字符串(不重新序列化)。签名密钥优先使用 WithVendorKey 配置的厂商密钥,未配置时使用 appsecret。验签失败返回 ErrComplaintWebhookSign。
平台按 HTTP 状态码判定推送结果:处理成功请返回任意 2xx;失败最多重试 3 次, 请按 MessageID 做幂等。
Example ¶
c, _ := New("your-appid", 123456, "your-appsecret")
http.HandleFunc("/union/complain/callback", func(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
wh, err := c.VerifyComplaintWebhook(body)
if err != nil {
http.Error(w, "invalid sign", http.StatusBadRequest)
return
}
// 按 wh.MessageID 做幂等;建议先落库后返回 2xx,再异步处理
switch wh.EventType {
case ComplaintEventCreated, ComplaintEventReplyAdded, ComplaintEventStatusChanged:
}
w.WriteHeader(http.StatusOK)
})
fmt.Println("registered")
Output: registered
type ComplainFinishRequest ¶ added in v0.3.0
ComplainFinishRequest 为投诉完结参数。完结处理码 code 由本包固定填充 "05"。
type ComplainInfo ¶ added in v0.3.0
type ComplainInfo struct {
Qid int64 `json:"qid"` // 厂商 ID
AppID string `json:"appId"` // 应用 ID
ComplainNo string `json:"complainNo"` // 投诉编号
ComplainTime string `json:"complainTime"` // 投诉时间,YYYY-MM-DD HH:MM:SS
BankTradeCode string `json:"bankTradeCode"` // 第三方支付流水号
CurrStatus int `json:"currStatus"` // 投诉状态,见 ComplainStatus*
PhoneNo string `json:"phoneNo"` // 用户联系方式
ComplainContent string `json:"complainContent"` // 投诉内容
PlatForm int `json:"platForm"` // 来源平台,见 ComplainPlatform*
BankTradeCodes []string `json:"bankTradeCodes"` // 关联的第三方支付流水号列表
LatestReplyContentDigest string `json:"latestReplyContentDigest"` // 最新回复摘要
HasNewMsg int `json:"hasNewMsg"` // 是否存在新的待处理消息:1 是,0 否
Images []string `json:"images"` // 投诉图片,base64 编码,不带 data:image/... 前缀
Replies []ComplainReplyInfo `json:"replies"` // 投诉历史回复列表
}
ComplainInfo 为投诉信息(webhook 的 complain_info)。
服务端以 omitempty 序列化:字段值为空、0、空数组时可能不出现在推送中, 解析后表现为对应零值,不代表平台显式推送了空值。
type ComplainReplyInfo ¶ added in v0.3.0
type ComplainReplyInfo struct {
ComplainNo string `json:"complainNo"` // 投诉编号
OperateTime string `json:"operateTime"` // 回复时间
Operator string `json:"operator"` // 回复操作人
Content string `json:"content"` // 回复内容
Images []string `json:"images"` // 回复图片,base64 编码,不带 data:image/... 前缀
}
ComplainReplyInfo 为投诉回复信息(webhook 的 reply_info 及 complain_info.replies 元素)。
type ComplainReplyRequest ¶ added in v0.3.0
type ComplainReplyRequest struct {
ComplainNo string // 投诉编号,即 webhook 推送中的 complainNo
Content string // 回复内容,长度 1-100 字符
Source int // 回复来源,见 ComplainSourceNormal / ComplainSourceRefund
}
ComplainReplyRequest 为投诉回复参数。
type ComplaintWebhook ¶ added in v0.3.0
type ComplaintWebhook struct {
MessageID string `json:"message_id"` // 推送消息 ID,与请求头 X-Message-Id 一致,请据此做幂等
EventType string `json:"event_type"` // 事件类型,见 ComplaintEvent*
PayloadVersion string `json:"payload_version"` // 推送协议版本,当前固定 v1
ComplainInfo *ComplainInfo `json:"complain_info"` // 投诉信息
ReplyInfo *ComplainReplyInfo `json:"reply_info"` // 本次新增回复信息
Timestamp int64 `json:"-"` // 外层推送时间戳,单位秒
}
ComplaintWebhook 为投诉 webhook 推送的解析结果。
ComplainInfo 与 ReplyInfo 按事件类型出现:COMPLAINT_CREATED、REPLY_ADDED、 STATUS_CHANGED 均携带 ComplainInfo;仅 REPLY_ADDED 携带 ReplyInfo。未携带时为 nil。
func ParseComplaintWebhook ¶ added in v0.3.0
func ParseComplaintWebhook(body []byte) (*ComplaintWebhook, error)
ParseComplaintWebhook 解析投诉 webhook 推送体。 它不做验签;如需验签请使用 Client.VerifyComplaintWebhook。
type CreateOrderParams ¶
type CreateOrderParams struct {
OrderID string // 厂商订单号,需保证应用内唯一
OrderAmount int64 // 订单金额,单位:分
CreateTime string // 厂商创建订单的时间戳(10 位,秒级)
UserID string // 用户 ID
ProductID string // 商品 ID
ProductName string // 商品描述
AutoPayStatus int // 是否开启代扣,见 AutoPayDisabled / AutoPayEnabled
OrderPayType int // 订单类型,见 OrderPayTypeNormal / OrderPayTypeTask
PeriodType int // 代扣周期类型,见 PeriodTypeDay / PeriodTypeMonth
Period int // 代扣周期值(与 PeriodType 组合,如 PeriodTypeDay+90 表示 90 天)
ExecuteTime string // 首次扣款时间,格式 yyyy-MM-dd
AutoPayAmount int64 // 代扣金额,单位:分
AutopayMode int // 代扣发起方,见 AutopayModeManager / AutopayModeVendor
TaskID string // 任务 ID,OrderPayType == OrderPayTypeTask 时必填(不要求开启代扣)
}
CreateOrderParams 是前端 SDK360.createOrder 所需的订单参数。
360 联运的下单由前端 JSSDK 直连完成,但订单数据应由厂商服务端生成唯一 order_id、 组装并留存后下发给前端。本结构提供类型化构造、条件校验与序列化,不发起任何请求。
代扣字段(AutoPayStatus 起的一组)仅当开启代扣(AutoPayStatus == AutoPayEnabled)时 生效且必填,校验由 CreateOrderParams.Validate 强制。
任务单(OrderPayType == OrderPayTypeTask)独立于代扣:不开启代扣亦可构造, 此时 TaskID 必填,且 OrderAmount 允许为 0(依据文档任务示例 task_amount 为 0)。
func (CreateOrderParams) MarshalForSDK ¶
func (p CreateOrderParams) MarshalForSDK() ([]byte, error)
MarshalForSDK 校验并序列化为前端 SDK360.createOrder 所需的 JSON。
非代扣付费单只输出基础字段;任务单无论是否开启代扣均附带 order_pay_type 与 task_id; 开启代扣时附带代扣字段及 ext(autopay_mode 的 JSON 字符串)。 数字字段以 JSON number 输出,与 360 前端约定一致。
Example ¶
p := CreateOrderParams{
OrderID: "order-1", OrderAmount: 1, CreateTime: "1700000000",
UserID: "user-1", ProductID: "vip-1", ProductName: "会员月卡",
}
data, _ := p.MarshalForSDK()
fmt.Println(string(data))
Output: {"create_time":"1700000000","order_amount":1,"order_id":"order-1","product_id":"vip-1","product_name":"会员月卡","user_id":"user-1"}
func (CreateOrderParams) Validate ¶
func (p CreateOrderParams) Validate() error
Validate 校验参数。基础字段与订单类型恒校验;任务单强制 task_id 且允许金额为 0; 开启代扣时强制校验代扣相关字段。
type DoPostRequest ¶
type DoPostRequest struct {
OrderID string // 签约的订单 ID
AgreementNumber string // 签约的协议号
AutopayAmount int64 // 代扣金额,单位:分
AutopayOrderID string // 本次代扣的订单 ID,须保证唯一
}
DoPostRequest 为厂商侧发起代扣的参数。
本接口仅用于厂商服务端主动发起代扣,代扣发起日期与周期由厂商自行设定。 注意:若上一笔代扣失败需重新发起,必须使用一个全新的 AutopayOrderID, 复用旧值可能出现“代扣失败但显示成功”的异常。
type Option ¶
type Option func(*Client)
Option 配置 Client。
func WithBaseURL ¶
WithBaseURL 覆盖接口域名(默认 https://api.openstore.360.cn)。主要用于测试。
func WithHTTPClient ¶
WithHTTPClient 注入自定义的 httpc 客户端(用于自定义超时、传输等)。 如需请求日志,可在构造该客户端时通过 httpc.WithTransport 注入带日志的 RoundTripper。
func WithTokenCache ¶
func WithTokenCache(tc TokenCache) Option
WithTokenCache 注入自定义的 access_token 缓存实现(如基于 Redis 的多实例共享)。
func WithTokenRefreshAhead ¶
WithTokenRefreshAhead 设置 token 提前刷新的安全边界(默认 5 分钟)。 剩余有效期不足该值时,下一次取 token 会触发刷新。
func WithTokenRefreshLock ¶ added in v0.2.0
func WithTokenRefreshLock(l TokenRefreshLock) Option
WithTokenRefreshLock 注入 access_token 刷新锁(如基于 Redis/etcd 的分布式锁)。
func WithVendorKey ¶ added in v0.3.0
WithVendorKey 设置 360 下发的厂商密钥,用于投诉 webhook 验签 (见 Client.VerifyComplaintWebhook)。未设置时验签使用 appsecret。
type OrderExtra ¶
type OrderExtra struct {
MfrOrderID string `json:"mfr_order_id"`
AgreementNumber string `json:"agreement_number"`
AutoPayStatus int `json:"auto_pay_status"`
}
OrderExtra 为回调中 order_extra 字段(JSON 字符串)解析后的内容。
type OrderQueryRequest ¶
OrderQueryRequest 为订单查询参数。
type OrderQueryResponse ¶ added in v0.3.1
type OrderQueryResponse struct {
MfrOrderID string `json:"mfr_order_id"` // 厂商订单编号
MfrOrderAmount int64 `json:"mfr_order_amount"` // 厂商订单金额,单位:分
MfrCreateTime string `json:"mfr_create_time"` // 厂商订单创建时间
MfrProductID string `json:"mfr_product_id"` // 厂商商品 ID
MfrProductName string `json:"mfr_product_name"` // 厂商商品名称
OrderStatus int `json:"order_status"` // 订单状态,见文档状态码
PayChannel int `json:"pay_chanel"` // 支付渠道 1-微信 2-支付宝(沿用文档查询响应字段名 pay_chanel)
OrderCode string `json:"order_code"` // 360 订单编号
BankTradeCode string `json:"bank_trade_code"` // 银行流水号
OrderPayTime string `json:"order_pay_time"` // 付款时间
OrderRefundTime string `json:"order_refund_time"` // 退款时间
HeaderTid string `json:"-"` // 本次响应的 Header-Tid
}
OrderQueryResponse 为订单查询返回的订单详情。
func (OrderQueryResponse) IsPaid ¶ added in v0.3.1
func (o OrderQueryResponse) IsPaid() bool
IsPaid 报告订单是否处于支付成功状态(order_status 为 20、30 或 50)。
type PlainInvoiceRequest ¶
type PlainInvoiceRequest struct {
OrderID string // 厂商调用 SDK 传入的订单 ID
InvoiceTitle string // 发票抬头
UserEmail string // 用户邮箱
TaxRegisterNo string // 纳税人识别号
Address string // 地址
Phone string // 电话
BankName string // 银行名称
BankAccount string // 银行账号
Remarks string // 备注
}
PlainInvoiceRequest 为普票开具参数。OrderID、InvoiceTitle、UserEmail 必填,其余可选。
type PlainInvoiceResult ¶
type PlainInvoiceResult struct {
DownloadURL string `json:"download_url"` // PDF 下载地址
InvoiceCode string `json:"invoice_code"` // 发票代码
InvoiceNo string `json:"invoice_no"` // 发票号码
ReceiptURL string `json:"receipt_url"` // 收票地址,可据此生成二维码
SuccessTime string `json:"success_time"` // 开票日期
VerifyCode string `json:"verify_code"` // 校验码
HeaderTid string `json:"-"`
}
PlainInvoiceResult 为普票开具返回结果。
type RefundOrdersRequest ¶ added in v0.3.0
type RefundOrdersRequest struct {
OrderIDs []string // 厂商订单 ID 列表,发送时以英文逗号拼接,拼接后总长 1-500 字符
UserID string // 用户 ID(厂商的用户唯一标识),长度 1-50 字符
OrderAmount int64 // 订单金额,单位:分,必须大于 0;建议与原订单金额一致
RefundReason string // 退款原因,长度 1-200 字符
}
RefundOrdersRequest 为多笔订单退款(v2)参数。
type RefundRequest ¶
type RefundRequest struct {
OrderID string // 厂商调用 SDK 传入的订单 ID
OrderAmount int64 // 订单金额,单位:分
UserID string // 用户 ID(厂商的用户唯一标识)
RefundReason string // 申请退款说明,长度不超过 200 个字符
}
RefundRequest 为订单退款申请参数。
type SpecialInvoiceCancelRequest ¶
type SpecialInvoiceCancelRequest struct {
Category string // 红冲类别,1 销方红冲
InvoiceNum string // 发票号码
RedReason string // 红冲原因,如 INVOICE_MISTAKE
SourceID string // 蓝票申请单来源 ID
OrderID string // 厂商调用 SDK 传入的订单 ID
}
SpecialInvoiceCancelRequest 为专票红冲参数(销方红冲)。
type SpecialInvoiceQueryResult ¶
type SpecialInvoiceQueryResult struct {
DownloadURL string `json:"download_url"` // PDF 下载地址
InvoiceCode string `json:"invoice_code"` // 发票代码
InvoiceNum string `json:"invoice_num"` // 发票号码
ReceiptURL string `json:"receipt_url"` // 收票地址
Status string `json:"status"` // 状态,如 SUCCESS_END
SuccessTime string `json:"success_time"` // 开票/红冲日期
HeaderTid string `json:"-"`
}
SpecialInvoiceQueryResult 为专票查询返回结果(开票或红冲)。
type SpecialInvoiceRequest ¶
type SpecialInvoiceRequest struct {
OrderID string // 厂商调用 SDK 传入的订单 ID
InvoiceTitle string // 发票抬头(不支持个人抬头)
UserEmail string // 用户邮箱
TaxRegisterNo string // 纳税人识别号
Address string // 地址
Phone string // 电话
BankName string // 银行名称
BankAccount string // 银行账号
CustomType string // 商户类型,1 企业
Remarks string // 备注
}
SpecialInvoiceRequest 为专票开具参数。除 Remarks 外均为必填。 专票申请后需人工审核(一般 5 个工作日内),可通过 Client.QuerySpecialInvoice 查询进度。
type SpecialInvoiceResult ¶
type SpecialInvoiceResult struct {
SourceID string `json:"source_id"` // 蓝票申请单来源 ID,红冲时需要
HeaderTid string `json:"-"`
}
SpecialInvoiceResult 为专票开具返回结果。
type TokenCache ¶
type TokenCache interface {
// Load 返回当前缓存的 token 及其过期时间;ok 为 false 表示无缓存。
Load(ctx context.Context) (token string, expireAt time.Time, ok bool, err error)
// Store 写入新的 token 及其过期时间。
Store(ctx context.Context, token string, expireAt time.Time) error
}
TokenCache 抽象 access_token 的持久化,供多实例部署共享 token。
默认实现为进程内无锁内存缓存,适用于单实例。多实例(多进程)场景下, 由于“新申请 token 会使旧 token 失效”,应注入基于共享存储(如 Redis)的实现, 并在刷新处自行加分布式锁或采用单点刷新,避免实例间互相作废 token。