package ebaiapi import ( "errors" "fmt" "net/http" "net/url" "git.rosy.net.cn/baseapi" "git.rosy.net.cn/baseapi/utils" ) const ( CmdOrderCreate = "order.create" CmdOrderDeliveryStatus = "order.deliveryStatus.push" CmdOrderPartRefund = "order.partrefund.push" // 售前只能是商户发起 售后是用户, 你看是由谁发起的就可以知道,来自惠焕 CmdOrderStatus = "order.status.push" CmdOrderUserCancel = "order.user.cancel" CmdShopMsgPush = "shop.msg.push" CmdShopBindMsg = "shop.bind.msg" CmdShopUnbindMsg = "shop.unbind.msg" ) type CallbackResponse struct { Cmd string `json:"cmd"` Sign string `json:"sign"` Source string `json:"source"` Ticket string `json:"ticket"` Encrypt string `json:"encrypt"` Timestamp int64 `json:"timestamp"` Version int `json:"version"` Body *ResponseResult `json:"body"` } type CallbackMsg struct { Cmd string `json:"cmd"` Version string `json:"version"` Timestamp int64 `json:"timestamp"` Ticket string `json:"ticket"` Source string `json:"source"` Sign string `json:"sign"` Encrypt string `json:"encrypt"` Body map[string]interface{} `json:"body"` Data interface{} `json:"data"` } type CBPartRefundInfo struct { OrderID int64 `json:"order_id"` RefundID string `json:"refund_id"` Type int `json:"type"` Status int `json:"status"` AdditionReason string `json:"addition_reason"` Photos []string `json:"photos"` ReasonType string `json:"reason_type"` Reason string `json:"reason"` RefundProducts []*struct { SkuID string `json:"sku_id"` Upc string `json:"upc"` CustomSkuID string `json:"custom_sku_id"` Name string `json:"name"` Number int `json:"number"` TotalRefund int64 `json:"total_refund"` ShopEleRefund int64 `json:"shop_ele_refund"` } `json:"refund_products"` RefundPrice int64 `json:"refund_price"` } type CBUserCancelInfo struct { OrderID int64 `json:"order_id"` CancelReason string `json:"cancel_reason"` AdditionReason string `json:"addition_reason"` RefuseReason string `json:"refuse_reason"` Pictures []string `json:"pictures"` Type int `json:"type"` CancelType int `json:"cancel_type"` } func (a *API) Err2CallbackResponse(cmd string, err error, data interface{}) *CallbackResponse { response := &CallbackResponse{ Cmd: "resp." + cmd, Source: a.source, Ticket: utils.GetUpperUUID(), Timestamp: utils.GetCurTimestamp(), Version: 3, } if err == nil { response.Body = &ResponseResult{ Error: "success", ErrNo: 0, Data: data, } } else { response.Body = &ResponseResult{ Error: fmt.Sprintf("error:%v, data:%v", err, data), ErrNo: -1, Data: data, } } params := url.Values{ "cmd": []string{response.Cmd}, "version": []string{utils.Int2Str(response.Version)}, "timestamp": []string{utils.Int64ToStr(response.Timestamp)}, "ticket": []string{response.Ticket}, "source": []string{response.Source}, "body": []string{string(utils.MustMarshal(response.Body))}, "encrypt": []string{""}, } response.Sign = a.signParams(params) return response } func (a *API) unmarshalData(cmd string, data []byte, msg interface{}) (callbackResponse *CallbackResponse) { err := utils.UnmarshalUseNumber(data, msg) if err != nil { return a.Err2CallbackResponse(cmd, err, nil) } return nil } func (a *API) CheckCallbackValidation(cmd string, params url.Values) (callbackResponse *CallbackResponse) { sign := a.signParams(params) if sign != params.Get(signKey) { msg := fmt.Sprintf("Signature is not ok, mine:%v, get:%v", sign, params.Get(signKey)) baseapi.SugarLogger.Info(msg) return a.Err2CallbackResponse(cmd, errors.New(msg), nil) } return nil } func (a *API) GetCallbackMsg(request *http.Request) (msg *CallbackMsg, callbackResponse *CallbackResponse) { err := request.ParseForm() if err == nil { params := make(url.Values) for k := range request.PostForm { decodedValue, _ := url.QueryUnescape(request.PostFormValue(k)) params.Set(k, decodedValue) } msg = new(CallbackMsg) msg.Cmd = GetCmd(request) if callbackResponse = a.CheckCallbackValidation(msg.Cmd, params); callbackResponse != nil { return nil, callbackResponse } if callbackResponse = a.unmarshalData(msg.Cmd, []byte(params.Get("body")), &msg.Body); callbackResponse != nil { return nil, callbackResponse } msg.Timestamp = utils.Str2Int64(params.Get("timestamp")) msg.Version = params.Get("version") msg.Ticket = params.Get("ticket") msg.Source = params.Get("source") msg.Sign = params.Get("sign") msg.Encrypt = params.Get("encrypt") var tmpObj interface{} switch msg.Cmd { case CmdOrderPartRefund: var partRefundData CBPartRefundInfo tmpObj = &partRefundData case CmdOrderUserCancel: var userCancelData CBUserCancelInfo tmpObj = &userCancelData } if tmpObj != nil { if utils.Map2StructByJson(msg.Body, tmpObj, true) == nil { msg.Data = tmpObj } } return msg, nil } return nil, a.Err2CallbackResponse("", err, nil) } func GetCmd(request *http.Request) (cmd string) { cmd, _ = url.QueryUnescape(request.FormValue("cmd")) return cmd }