package mtwmapi import ( "encoding/json" "errors" "git.rosy.net.cn/baseapi/utils" "time" ) const ( MaxBatchPullPhoneNumberLimit = 1000 ) // http://developer.waimai.meituan.com/home/doc/food/99 const ( OrderStatusUserCommitted = "1" // 用户已提交订单 OrderStatusNew = "2" // 向商家推送订单 OrderStatusReceived = "3" // 商家已收到 OrderStatusAccepted = "4" // 商家已确认 OrderStatusDelivering = "6" // 订单配送中 OrderStatusDelivered = "7" // 订单已送达 OrderStatusFinished = "8" // 订单已完成 OrderStatusCanceled = "9" // 订单已取消 ) const ( WaybillStatusWait4Delivery = "0" // 配送单发往配送 WaybillStatusPending = "5" // 配送压单 WaybillStatusAccepted = "10" // 配送单已确认 WaybillStatusCourierArrived = "15" // 骑手已到店 WaybillStatusPickedup = "20" // 骑手已取餐 WaybillStatusDelivered = "40" // 骑手已送达 WaybillStatusCanceled = "100" // 配送单已取消 ) // APP方URL 推送用户或客服取消订单(必接) const ( CancelReasonAcceptTimeout = 1001 // 系统取消,超时未确认 CancelReasonPayTimeout = 1002 // 系统取消,在线支付订单15分钟未支付 CancelReasonPayCanceled = 1101 // 用户取消,在线支付中取消 CancelReasonCancelBeforeAccepted = 1102 // 用户取消,商家确认前取消 CancelReasonRefundCanceled = 1103 // 用户取消,用户退款取消 CancelReasonWrongOrder = 1201 // 客服取消,用户下错单 CancelReasonUserTest = 1202 // 客服取消,用户测试 CancelReasonDuplicatedOrder = 1203 // 客服取消,重复订单 CancelReasonCSOther = 1204 // 客服取消,其他原因 CancelReasonOther = 1301 // 其他原因 ) const ( ResTypePending = 0 // 未处理 ResTypeMerchantRefused = 1 // 商家驳回退款请求 ResTypeMerchantAgreed = 2 // 商家同意退款 ResTypeCSRefused = 3 // 客服驳回退款请求 ResTypeCSAgreed = 4 // 客服帮商家同意退款 ResTypeTimeoutAutoAgreed = 5 // 超过3小时自动同意 ResTypeAutoAgreed = 6 // 系统自动确认 ResTypeUserCancelApply = 7 // 用户取消退款申请 ResTypeUserCancelComplain = 8 // 用户取消退款申诉 ) const ( NotifyTypeApply = "apply" // 发起全款退款 NotifyTypePartyApply = "part" // 发起部分退款 NotifyTypeSuccess = "agree" // 确认退款 NotifyTypeReject = "reject" // 驳回退款 NotifyTypeCancelRefund = "cancelRefund" // 用户取消退款申请 NotifyTypeCancelRefundComplaint = "cancelRefundComplaint" // 用户取消退款申诉 ) const ( OrderPickTypeNormal = 0 // 普通(配送) OrderPickTypeSelf = 1 // 用户到店自取 ) const ( UserApplyCancelWaitMinute = 30 // 用户申请退款后,商家未在30分钟内(大连锁商家为3小时内)处理退款请求,系统将自动同意退款 ) const ( RefundTypeAll = 1 RefundTypePart = 2 ) const ( ExtrasPromotionTypeTaoCanZeng = 4 // 套餐赠 ExtrasPromotionTypeManZeng = 5 // 满赠 ExtrasPromotionTypeTeJiaCai = 7 // 特价菜 ExtrasPromotionTypeZheKouCai = 17 // 折扣菜 ExtrasPromotionTypeSecondHalfPrice = 20 // 第2份半价活动 ExtrasPromotionTypeShanGouBaoPin = 56 // 闪购爆品 ) const ( MaxGap4GetOrderIdByDaySeq = 100 ) type RefundSku struct { AppFoodCode string `json:"app_food_code"` SkuID string `json:"sku_id,omitempty"` Count int `json:"count"` ItemID string `json:"item_id,omitempty"` ActualWeight float64 `json:"actual_weight,omitempty"` } type RefundSkuDetail struct { AppFoodCode string `json:"app_food_code"` BoxNum float64 `json:"box_num"` BoxPrice float64 `json:"box_price"` Count int `json:"count"` FoodName string `json:"food_name"` FoodPrice float64 `json:"food_price"` OriginFoodPrice float64 `json:"origin_food_price"` RefundPrice float64 `json:"refund_price"` SkuID string `json:"sku_id"` Spec string `json:"spec"` } type RefundDetail struct { TotalFoodAmount string `json:"total_food_amount"` BoxAmount string `json:"box_amount"` ActivityPoiAmount string `json:"activity_poi_amount"` ActivityMeituanAmount string `json:"activity_meituan_amount"` ActivityAgentAmount string `json:"activity_agent_amount"` PlatformChargeFee string `json:"platform_charge_fee"` SettleAmount string `json:"settle_amount"` Productpreferences string `json:"productpreferences"` NotProductpreferences string `json:"not_productpreferences"` } type RefundOrderDetail struct { ApplyReason string `json:"apply_reason"` ApplyType int `json:"apply_type"` CTime int64 `json:"ctime"` Money float64 `json:"money"` OrderID int64 `json:"order_id"` Pictures string `json:"pictures"` PictureList []string `json:"pictureList"` RefundType int `json:"refund_type"` ResReason string `json:"res_reason"` ResType int `json:"res_type"` UTime int64 `json:"utime"` WmAppRetailForOrderPartRefundList []*RefundSkuDetail `json:"wmAppRetailForOrderPartRefundList"` WmOrderIDView int64 `json:"wm_order_id_view"` RefundPartialEstimateCharge *RefundDetail `json:"refund_partial_estimate_charge"` } type OrderExtraInfo struct { ActDetailID int `json:"act_detail_id,omitempty"` MtCharge float64 `json:"mt_charge,omitempty"` PoiCharge float64 `json:"poi_charge,omitempty"` ReduceFee float64 `json:"reduce_fee,omitempty"` Remark string `json:"remark,omitempty"` Type int `json:"type,omitempty"` RiderFee float64 `json:"rider_fee,omitempty"` } type FoodInfo struct { AppFoodCode string `json:"app_food_code"` BoxNum float64 `json:"box_num"` BoxPrice float64 `json:"box_price"` CartID int `json:"cart_id"` FoodDiscount float64 `json:"food_discount"` FoodName string `json:"food_name"` FoodProperty string `json:"food_property"` Price float64 `json:"price"` Quantity int `json:"quantity"` SkuID string `json:"sku_id"` Spec string `json:"spec"` Unit string `json:"unit"` Weight int64 `json:"weight"` } type CanRefundFoodInfo struct { AppFoodCode string `json:"app_food_code"` BoxNum float64 `json:"box_num"` BoxPrice float64 `json:"box_price"` Count int `json:"count"` FoodName string `json:"food_name"` FoodPrice float64 `json:"food_price"` IsRefundDifference int `json:"is_refund_difference"` OriginFoodPrice float64 `json:"origin_food_price"` RefundPrice float64 `json:"refund_price"` SkuID string `json:"sku_id"` } type WmAppOrderActDetailInfo struct { ActID int64 `json:"act_id"` Count int `json:"count"` MtCharge float64 `json:"mtCharge"` PoiCharge float64 `json:"poiCharge"` Remark string `json:"remark"` Type int `json:"type"` } type SkuBenefitDetailInfo struct { ActivityPrice float64 `json:"activityPrice"` AppFoodCode string `json:"app_food_code"` BoxNumber float64 `json:"boxNumber"` BoxPrice float64 `json:"boxPrice"` Count int `json:"count"` Name string `json:"name"` OriginPrice float64 `json:"originPrice"` SkuID string `json:"sku_id"` TotalActivityPrice float64 `json:"totalActivityPrice"` TotalBoxPrice float64 `json:"totalBoxPrice"` TotalMtCharge float64 `json:"totalMtCharge"` TotalOriginPrice float64 `json:"totalOriginPrice"` TotalPoiCharge float64 `json:"totalPoiCharge"` TotalReducePrice float64 `json:"totalReducePrice"` WmAppOrderActDetails []*WmAppOrderActDetailInfo `json:"wmAppOrderActDetails"` } type ActOrderChargeInfo struct { Comment string `json:"comment"` FeeTypeDesc string `json:"feeTypeDesc"` FeeTypeID int `json:"feeTypeId"` MoneyCent int64 `json:"moneyCent"` } type PoiReceiveDetailInfo struct { ActOrderChargeByMt []*ActOrderChargeInfo `json:"actOrderChargeByMt"` ActOrderChargeByPoi []*ActOrderChargeInfo `json:"actOrderChargeByPoi"` FoodShareFeeChargeByPoi int64 `json:"foodShareFeeChargeByPoi"` LogisticsFee int64 `json:"logisticsFee"` OnlinePayment int64 `json:"onlinePayment"` WmPoiReceiveCent int64 `json:"wmPoiReceiveCent"` } type OrderInfo struct { AppOrderCode string `json:"app_order_code"` AppPoiCode string `json:"app_poi_code"` AvgSendTime float64 `json:"avg_send_time"` BackupRecipientPhone string `json:"backup_recipient_phone"` Caution string `json:"caution"` CityID int `json:"city_id"` Ctime int64 `json:"ctime"` DaySeq int `json:"day_seq"` DeliveryTime int `json:"delivery_time"` Detail string `json:"detail"` DetailList []*FoodInfo `json:"detailList"` DinnersNumber int `json:"dinners_number"` ExpectDeliverTime int64 `json:"expect_deliver_time"` Extras string `json:"extras"` ExtraList []*OrderExtraInfo `json:"extraList"` HasInvoiced int `json:"has_invoiced"` InvoiceTitle string `json:"invoice_title"` IsFavorites bool `json:"is_favorites"` IsPoiFirstOrder bool `json:"is_poi_first_order"` IsPre int `json:"is_pre"` IsThirdShipping int `json:"is_third_shipping"` Latitude float64 `json:"latitude"` Longitude float64 `json:"longitude"` LogisticsCancelTime int64 `json:"logistics_cancel_time"` LogisticsCode string `json:"logistics_code"` // 此字段是配送方式变化后,不会改变 LogisticsCompletedTime int64 `json:"logistics_completed_time"` LogisticsConfirmTime int64 `json:"logistics_confirm_time"` LogisticsDispatcherMobile string `json:"logistics_dispatcher_mobile"` LogisticsDispatcherName string `json:"logistics_dispatcher_name"` LogisticsFetchTime int64 `json:"logistics_fetch_time"` LogisticsID int `json:"logistics_id"` LogisticsName string `json:"logistics_name"` LogisticsSendTime int64 `json:"logistics_send_time"` LogisticsStatus int `json:"logistics_status"` OrderCompletedTime int `json:"order_completed_time"` OrderConfirmTime int `json:"order_confirm_time"` OrderID int64 `json:"order_id"` OrderSendTime int `json:"order_send_time"` OriginalPrice float64 `json:"original_price"` PackageBagMoney int `json:"package_bag_money"` PayType int `json:"pay_type"` PickType int `json:"pick_type"` PoiReceiveDetail string `json:"poi_receive_detail"` PoiReceiveDetailPtr *PoiReceiveDetailInfo `json:"poi_receive_detail_ptr"` RecipientAddress string `json:"recipient_address"` RecipientName string `json:"recipient_name"` RecipientPhone string `json:"recipient_phone"` Remark string `json:"remark"` Result string `json:"result"` ShipperPhone string `json:"shipper_phone"` ShippingFee float64 `json:"shipping_fee"` ShippingType int `json:"shipping_type"` SkuBenefitDetail string `json:"sku_benefit_detail"` SkuBenefitDetailList []*SkuBenefitDetailInfo `json:"sku_benefit_detail_list"` SourceID int `json:"source_id"` Status int `json:"status"` TaxpayerID string `json:"taxpayer_id"` Total float64 `json:"total"` TotalWeight int64 `json:"total_weight"` Utime int64 `json:"utime"` WmOrderIDView int64 `json:"wm_order_id_view"` WmPoiAddress string `json:"wm_poi_address"` WmPoiID int `json:"wm_poi_id"` WmPoiName string `json:"wm_poi_name"` WmPoiPhone string `json:"wm_poi_phone"` } type GetOrderActDetailParamAct struct { Type int `json:"type,omitempty"` ActID int64 `json:"act_id,omitempty"` } type GetOrderActDetailParam struct { OrderID int64 `json:"order_id_view"` ActParam []*GetOrderActDetailParamAct `json:"act_param,omitempty"` } type OrderActInfo struct { OrderID int64 `json:"order_id_view"` ActDetailList []*struct { ActID int64 `json:"act_id"` CouponDetail interface{} `json:"coupon_detail"` EndTime int64 `json:"end_time"` GiftsDetail interface{} `json:"gifts_detail"` PoiDetail interface{} `json:"poi_detail"` ProductDetail struct { AppFoodCode string `json:"app_food_code"` CategorySeqence int `json:"category_seqence"` Charge string `json:"charge"` DayLimit int `json:"day_limit"` Name string `json:"name"` OrderLimit int `json:"order_limit"` Period string `json:"period"` Policy string `json:"policy"` SettingType int `json:"setting_type"` UserType int `json:"user_type"` WeeksTime string `json:"weeks_time"` } `json:"product_detail"` Remark string `json:"remark"` StartTime int64 `json:"start_time"` Status int `json:"status"` Type int `json:"type"` TypeName string `json:"type_name"` } `json:"act_detail_list"` } type GetOrderIdByDaySeqResult struct { Result string `json:"result"` OrderIDs []int64 `json:"order_ids"` } type UserRealPhoneNumberInfo struct { OrderID int64 `json:"order_id"` AppPoiCode string `json:"app_poi_code"` WmOrderIDView string `json:"wm_order_id_view"` DaySeq int `json:"day_seq"` RealPhoneNumber string `json:"real_phone_number"` // 订单收货人的真实手机号码 RealOrderPhoneNumber string `json:"real_order_phone_number"` // 鲜花绿植类订单预订人的真实手机号码,如无则返回空。 } type RiderRealPhoneNumberInfo struct { OrderID int64 `json:"order_id"` AppPoiCode string `json:"app_poi_code"` WmOrderIDView string `json:"wm_order_id_view"` RiderName string `json:"rider_name"` RiderRealPhoneNumber string `json:"rider_real_phone_number"` // 骑手真实手机号 } func (a *API) OrderReceived(orderID int64) (err error) { _, err = a.AccessAPI("order/poi_received", true, map[string]interface{}{ KeyOrderID: orderID, }) return err } func (a *API) OrderConfirm(orderID int64) (err error) { _, err = a.AccessAPI("order/confirm", true, map[string]interface{}{ KeyOrderID: orderID, }) return err } // 商家确认已完成拣货 // https://developer.waimai.meituan.com/home/docDetail/216 func (a *API) PreparationMealComplete(orderID int64) (err error) { params := map[string]interface{}{ KeyOrderID: orderID, } _, err = a.AccessAPI("order/preparationMealComplete", true, params) return err } func (a *API) OrderCancel(orderID int64, cancelReason string, cancelReasonCode int) (err error) { _, err = a.AccessAPI("order/cancel", true, map[string]interface{}{ KeyOrderID: orderID, "reason": cancelReason, "reason_code": cancelReasonCode, }) return err } type MtwmOrderDelivering struct { Data string `json:"data"` Err *Errors `json:"err"` } type Errors struct { Code int64 `json:"code"` Msg string `json:"msg"` } // 专快混配送转为商家自配送 // 预定单不能调用此接口 // https://developer.waimai.meituan.com/home/myquestionDetail/7382 func (a *API) OrderLogisticsChange2Self(orderID int64) (err error) { _, err = a.AccessAPI("order/logistics/change/poi_self", false, map[string]interface{}{ KeyOrderID: orderID, }) return err } // OrderDelivering 订单自配送中不支持骑手信息 func (a *API) OrderDelivering(orderID int64) (err error) { retval, err := a.AccessAPI("order/delivering", true, map[string]interface{}{ KeyOrderID: orderID, }) if err != nil { return err } if retval != nil { if retval.(string) == "ok" { return nil } else { return errors.New("美团系统操作异常,订单查询ng") } } return err } func (a *API) OrderArrived(orderID int64) (err error) { result, err := a.AccessAPI("order/arrived", true, map[string]interface{}{ KeyOrderID: orderID, }) if err != nil { return err } if result != nil { if result.(string) == "ok" { return nil } else { return errors.New("美团系统操作异常,订单查询ng") } } return err } func (a *API) OrderRefundAgree(orderID int64, reason string) (err error) { _, err = a.AccessAPI("order/refund/agree", true, map[string]interface{}{ KeyOrderID: orderID, "reason": reason, }) return err } func (a *API) OrderRefundReject(orderID int64, reason string) (err error) { _, err = a.AccessAPI("order/refund/reject", true, map[string]interface{}{ KeyOrderID: orderID, "reason": reason, }) return err } func (a *API) OrderApplyPartRefund(orderID int64, reason string, removeSkuList []*RefundSku) (err error) { _, err = a.AccessAPI("order/applyPartRefund", false, map[string]interface{}{ KeyOrderID: orderID, "reason": reason, "food_data": string(utils.MustMarshal(removeSkuList)), }) return err } func (a *API) OrderViewStatus(orderID int64) (status int, err error) { result, err := a.AccessAPI("order/viewstatus", true, map[string]interface{}{ KeyOrderID: orderID, }) if err == nil { return int(utils.MustInterface2Int64(result.(map[string]interface{})["status"])), nil } return 0, err } func (a *API) OrderGetOrderDetail(orderID int64, isMTLogistics bool) (orderInfo map[string]interface{}, err error) { params := map[string]interface{}{ KeyOrderID: orderID, } if isMTLogistics { params["is_mt_logistics"] = 1 } result, err := a.AccessAPI("order/getOrderDetail", true, params) if err == nil { return result.(map[string]interface{}), nil } return nil, err } func (a *API) OrderGetOrderDetail2(orderID int64, isMTLogistics bool) (orderInfo *OrderInfo, err error) { orderMap, err := a.OrderGetOrderDetail(orderID, isMTLogistics) if err == nil { if err = utils.Map2StructByJson(orderMap, &orderInfo, false); err == nil { if orderInfo.Detail != "" { err = utils.UnmarshalUseNumber([]byte(orderInfo.Detail), &orderInfo.DetailList) } if err != nil { return nil, err } if orderInfo.Extras != "" { err = utils.UnmarshalUseNumber([]byte(orderInfo.Extras), &orderInfo.ExtraList) } if err != nil { return nil, err } if orderInfo.SkuBenefitDetail != "" { err = utils.UnmarshalUseNumber([]byte(orderInfo.SkuBenefitDetail), &orderInfo.SkuBenefitDetailList) } if err != nil { return nil, err } if orderInfo.PoiReceiveDetail != "" { err = utils.UnmarshalUseNumber([]byte(orderInfo.PoiReceiveDetail), &orderInfo.PoiReceiveDetailPtr) } } } return orderInfo, err } func (a *API) OrderGetPartRefundFoods(orderID int64) (canRefundFoodList []*CanRefundFoodInfo, err error) { params := map[string]interface{}{ KeyOrderID: orderID, } result, err := a.AccessAPI("order/getPartRefundFoods", true, params) if err == nil { err = utils.Map2StructByJson(result, &canRefundFoodList, false) } return canRefundFoodList, err } func (a *API) OrderLogisticsPush(orderID int64, reason string) (err error) { _, err = a.AccessAPI("order/logistics/push", true, map[string]interface{}{ KeyOrderID: orderID, }) return err } func (a *API) OrderLogisticsCancel(orderID int64, reason string) (err error) { _, err = a.AccessAPI("order/logistics/cancel", true, map[string]interface{}{ KeyOrderID: orderID, }) return err } // OrderLogisticsStatus 获取订单状态 func (a *API) OrderLogisticsStatus(orderID int64) (status *utils.RiderInfo, err error) { result, err := a.AccessAPI("order/logistics/status", true, map[string]interface{}{ KeyOrderID: orderID, }) if err != nil { return nil, err } logistics := &utils.RiderInfo{} data := result.(map[string]interface{}) logistics.LogisticsStatus = int(utils.Interface2Int64WithDefault(data["logistics_status"], 0)) logistics.CourierName = utils.Interface2String(data["dispatcher_name"]) logistics.CourierPhone = utils.Interface2String(data["dispatcher_mobile"]) return logistics, err } // OrderLogisticsFee 获取订单配送费 func (a *API) OrderLogisticsFee(orderID int64) (payFee float64, err error) { result, err := a.AccessAPI("order/logistics/status", true, map[string]interface{}{ KeyOrderID: orderID, }) if err != nil { return 0, err } data := result.(map[string]interface{}) // 美团运单,骑手确认订单之后取消的话就需要扣除全部的运单费用了,到店之后取消订单也不支付骑手配送费 if utils.Interface2Int64WithDefault(data["logistics_status"], 0) == utils.Str2Int64WithDefault(WaybillStatusCanceled, 0) { if utils.Interface2Int64WithDefault(data["dispatcher_reach_poi_time"], 0) != 0 { return 2, nil } else if utils.Interface2Int64WithDefault(data["send_time"], 0) != 0 { return utils.TryInterface2Float64(data["pay_amount"]) } else { return 0, nil } } return utils.TryInterface2Float64(data["pay_amount"]) } // 拉取用户真实手机号(必接) // https://developer.waimai.meituan.com/home/docDetail/222 // limit最大为MaxBatchPullPhoneNumberLimit = 1000 func (a *API) OrderBatchPullPhoneNumber(poiCode string, offset, limit int) (realNumberList []*UserRealPhoneNumberInfo, err error) { params := map[string]interface{}{ "offset": offset, "limit": limit, } if poiCode != "" { params[KeyAppPoiCode] = poiCode } result, err := a.AccessAPI("order/batchPullPhoneNumber", false, params) if err == nil { err = utils.Map2StructByJson(result, &realNumberList, false) } return realNumberList, err } // 拉取骑手真实手机号(必接),美团2019-09-17才开始灰度上线 // https://developer.waimai.meituan.com/home/docDetail/388 // limit最大为MaxBatchPullPhoneNumberLimit = 1000 func (a *API) OrderGetRiderInfoPhoneNumber(poiCode string, offset, limit int) (realNumberList []*RiderRealPhoneNumberInfo, err error) { params := map[string]interface{}{ "offset": offset, "limit": limit, } if poiCode != "" { params[KeyAppPoiCode] = poiCode } result, err := a.AccessAPI("order/getRiderInfoPhoneNumber", false, params) if err == nil { err = utils.Map2StructByJson(result, &realNumberList, false) } return realNumberList, err } // refundOrderDetailList不能定义为[]*RefundOrderDetail,否则会有解析错误,原因不明 func (a *API) GetOrderRefundDetail(orderID int64, refundType int) (refundOrderDetailList []*RefundOrderDetail, err error) { params := map[string]interface{}{ "wm_order_id_view": orderID, } if refundType > 0 { params["refund_type"] = refundType } result, err := a.AccessAPI("ecommerce/order/getOrderRefundDetail", true, params) if err == nil { if err = utils.Map2StructByJson(result, &refundOrderDetailList, false); err == nil { for _, v := range refundOrderDetailList { if v.Pictures != "" { if err = utils.UnmarshalUseNumber([]byte(v.Pictures), &v.PictureList); err != nil { return nil, err } } } } } return refundOrderDetailList, err } func (a *API) GetOrderActDetail(queryData []*GetOrderActDetailParam) (orderActList []*OrderActInfo, err error) { params := map[string]interface{}{ "query_data": string(utils.MustMarshal(queryData)), } result, err := a.AccessAPI("ecommerce/order/getOrderActDetail", true, params) if err == nil { err = utils.Map2StructByJson(result, &orderActList, false) } return orderActList, err } func (a *API) GetOrderDaySeq(poiCode string) (daySeq int, err error) { params := map[string]interface{}{ KeyAppPoiCode: poiCode, } result, err := a.AccessAPI("order/getOrderDaySeq", true, params) if err == nil { daySeq = int(utils.MustInterface2Int64(result.(map[string]interface{})["day_seq"])) } return daySeq, err } func (a *API) GetOrderIdByDaySeqSingle(poiCode string, dateTime time.Time, daySeq int) (vendorOrderID int64, err error) { params := map[string]interface{}{ KeyAppPoiCode: poiCode, "date_time": dateTime.Format("20060102"), "day_seq": daySeq, } result, err := a.AccessAPI("order/getOrderIdByDaySeq", true, params) if err == nil { vendorOrderID = utils.ForceInterface2Int64(result.(map[string]interface{})["order_id"]) } return vendorOrderID, err } // 订单流水号的开始序号,门店内每日的订单流水号都是从1开始。 // 订单流水号的结束序号,注意开始流水号与结束流水号的跨度需小于100,即差值最大为99 // 这个函数在给定的区间范围全部没有订单时,返回错误808, // 但如果有部分订单,底层返回的错误是0(然后被忽略),vendorOrderIDs只包含有效的订单号(数量少于seqEnd-seqStart+1) // 此API速度与查询的区间范围直接相关,越大越慢(即使订单不存在),最大可到4,5秒级别 func (a *API) GetOrderIdByDaySeq(poiCode string, dateTime time.Time, seqStart, seqEnd int) (vendorOrderIDs []int64, err error) { params := map[string]interface{}{ KeyAppPoiCode: poiCode, "date_time": dateTime.Format("20060102"), "day_seq_start": seqStart, "day_seq_end": seqEnd, } result, err := a.AccessAPI("ecommerce/order/getOrderIdByDaySeq", true, params) // 当前底层已经处理了错误0的情况了,不会返回错误0了 if extErr, ok := err.(*utils.ErrorWithCode); err == nil || (ok && extErr.IntCode() == 0) { var data GetOrderIdByDaySeqResult if err2 := utils.UnmarshalUseNumber([]byte(utils.Interface2String(result)), &data); err2 == nil { vendorOrderIDs = data.OrderIDs err = nil } } return vendorOrderIDs, err } // 众包配送单追加小费 // https://developer.waimai.meituan.com/home/docDetail/158 func (a *API) OrderUpdateTip(orderID int64, tipAmount float64) (err error) { params := map[string]interface{}{ KeyOrderID: orderID, "tip_amount": tipAmount, } _, err = a.AccessAPI("order/zhongbao/update/tip", true, params) return err } // 美团外卖自配送商家同步发货状态和配送信息(推荐) // https://waimaiopen.meituan.com/api/v1/ecommerce/order/logistics/sync func (a *API) OrderStatusAndPsInfo(params map[string]interface{}) (err error) { delete(params, "opcode") // 美团不需要此参数 delete(params, "logistics_context") // 美团不需要此参数 _, err = a.AccessAPI("ecommerce/order/logistics/sync", false, params) return err } // 获取取消跑腿理由刘表 // https://open-shangou.meituan.com/home/docDetail/482 func (a *API) GetCancelDeliveryReason(orderId int64, appPoiCode string) (string, error) { data, err := a.AccessAPI("order/getCancelDeliveryReason", false, map[string]interface{}{"order_id": orderId, "app_poi_code": appPoiCode}) if err != nil { return "", err } str, _ := json.Marshal(data) result := &DeliveryData{} if err := json.Unmarshal(str, result); err != nil { return "", err } list, _ := json.Marshal(&result.ReasonList) return string(list), nil } type DeliveryData struct { Code int `json:"code"` Title string `json:"title"` ReasonList []*ReasonList `json:"reasonList"` Msg string `json:"msg"` DeliveryStatus int `json:"deliveryStatus"` } type ReasonList struct { Code string `json:"code"` Content string `json:"content"` PreCancelCode int `json:"preCancelCode"` PreCancelMsg string `json:"preCancelMsg"` } // 取消跑腿配送 func (a *API) CancelLogisticsByWmOrderId(reasonCode, detailContent, appPoiCode, orderId string) error { param := &CancelOrderParam{ ReasonCode: reasonCode, DetailContent: detailContent, AppPoiCode: appPoiCode, OrderId: orderId, } data, err := a.AccessAPI("order/cancelLogisticsByWmOrderId", false, utils.Struct2FlatMap(param)) if err != nil { return err } result := &ResultMsg{} if err := json.Unmarshal([]byte(utils.Interface2String(data)), result); err != nil { return err } if result.Data != "ok" { return errors.New(result.Error.Msg) } return nil } type ResultMsg struct { Data string `json:"data"` Error *struct { Code int `json:"code"` Msg string `json:"msg"` } } // 取消跑腿配送请求参数 type CancelOrderParam struct { ReasonCode string `json:"reason_code"` // 取消原因code 请开发者一定要先调用 DetailContent string `json:"detail_content"` // 取消原因 AppPoiCode string `json:"app_poi_code"` // 门店号 OrderId string `json:"order_id"` // 订单id }