添加蜂鸟新API
This commit is contained in:
54
platformapi/fnpsapi_v3/callback.go
Normal file
54
platformapi/fnpsapi_v3/callback.go
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package fnpsapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CallBackInfo struct {
|
||||||
|
AppID string `json:"app_id"`
|
||||||
|
Data string `json:"data"`
|
||||||
|
Salt int `json:"salt"`
|
||||||
|
Signature string `json:"signature"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WayBillInfo struct {
|
||||||
|
PartnerOrderCode string `json:"partner_order_code"`
|
||||||
|
OrderStatus int `json:"order_status"`
|
||||||
|
PushTime int64 `json:"push_time"`
|
||||||
|
CarrierDriverName string `json:"carrier_driver_name"`
|
||||||
|
CarrierDriverPhone string `json:"carrier_driver_phone"`
|
||||||
|
OpenOrderCode int64 `json:"open_order_code"`
|
||||||
|
PlatformCode string `json:"platform_code"`
|
||||||
|
ErrorScene string `json:"error_scene"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
ErrorCode string `json:"error_code"`
|
||||||
|
DetailDescription string `json:"detail_description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *API) GetOrderCallbackMsg(data []byte) (orderMsg *WayBillInfo) {
|
||||||
|
callbackInfo := &CallBackInfo{}
|
||||||
|
err := utils.UnmarshalUseNumber(data, callbackInfo)
|
||||||
|
if err != nil {
|
||||||
|
globals.SugarLogger.Debugf("fn msg faild %v, err : %v", string(data), err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
if str, err := url.QueryUnescape(callbackInfo.Data); err == nil {
|
||||||
|
orderMsg = &WayBillInfo{}
|
||||||
|
if err := utils.UnmarshalUseNumber([]byte(str), orderMsg); err == nil {
|
||||||
|
return orderMsg
|
||||||
|
} else {
|
||||||
|
globals.SugarLogger.Debugf("fn msg faild3 %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
globals.SugarLogger.Debugf("fn msg faild2 %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return orderMsg
|
||||||
|
}
|
||||||
63
platformapi/fnpsapi_v3/fnps_v3.go
Normal file
63
platformapi/fnpsapi_v3/fnps_v3.go
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package fnpsapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi"
|
||||||
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
sigKey = "signature"
|
||||||
|
|
||||||
|
TokenURL = "https://open-anubis.ele.me/anubis-webapi/openapi/token"
|
||||||
|
ApiURL = "https://open-anubis.ele.me/anubis-webapi/v3/invoke/"
|
||||||
|
RequestPost = "POST"
|
||||||
|
RequestGet = "GET"
|
||||||
|
)
|
||||||
|
|
||||||
|
//todo 返回参数没做玩
|
||||||
|
type TokenInfo struct {
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
AppID string `json:"app_id"`
|
||||||
|
ExpireTime int64 `json:"expire_time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册请求api
|
||||||
|
type API struct {
|
||||||
|
grantType string `json:"grant_type"`
|
||||||
|
code string `json:"code"`
|
||||||
|
appID string `json:"app_id"`
|
||||||
|
merchantId string `json:"merchant_id"`
|
||||||
|
signature string `json:"signature"`
|
||||||
|
timestamp int64 `json:"timestamp"`
|
||||||
|
accessToken string `json:"access_token"`
|
||||||
|
appSecret string `json:"app_secret"`
|
||||||
|
|
||||||
|
locker sync.RWMutex
|
||||||
|
client *http.Client
|
||||||
|
config *platformapi.APIConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateStoreParam 创建门店请求参数
|
||||||
|
type CreateStoreParam struct {
|
||||||
|
BranchShopName string `json:"branch_shop_name"` // 门店主店名 必填
|
||||||
|
ContactPhone string `json:"contact_phone"` // 门店联系方式
|
||||||
|
OwnerIDPicFrontHash string `json:"owner_id_pic_front_hash"` // 身份证正面
|
||||||
|
BusinessLicencePicHash string `json:"business_licence_pic_hash"` // 营业执照图片
|
||||||
|
Longitude float64 `json:"longitude"` // 门店经度(0-18)
|
||||||
|
Latitude float64 `json:"latitude"` // 门店纬度(0-90)
|
||||||
|
OutShopCode string `json:"out_shop_code"` // 外部门店编码
|
||||||
|
CategoryID string `json:"category_id"` // 门店类目
|
||||||
|
HandheldLicencePicHash string `json:"handheld_licence_pic_hash"` // 门店拥有人手持身份证、营业执照图片
|
||||||
|
CreditCode string `json:"credit_code"` // 统一社会信用代码
|
||||||
|
SettlementModel string `json:"settlement_model"` // 1:实时结算; 2:账期结算;默认为1,若为账期结算,需额外传入结算账号id
|
||||||
|
SettlementAccountID string `json:"settlement_account_id"` // 门店结算账号id
|
||||||
|
OwnerIDNum string `json:"owner_id_num"` // 门店拥有人身份证号
|
||||||
|
FoodLicensePicHash string `json:"food_license_pic_hash"` // 食品安全执照图片(食品经营必传)
|
||||||
|
HeadShopName string `json:"head_shop_name"` // 门店主店名
|
||||||
|
Address string `json:"address"` // 门店地址
|
||||||
|
OwnerName string `json:"owner_name"` // 门店拥有人姓名
|
||||||
|
ChainstoreType int `json:"chainstore_type"` // 门店类型 1:正式门店;2:测试门店;默认为1
|
||||||
|
OwnerIDPicBackHash string `json:"owner_id_pic_back_hash"` // 身份证反面
|
||||||
|
PositionSource int `json:"position_source"` // 经纬度来源只支持高德(默认值3)
|
||||||
|
}
|
||||||
116
platformapi/fnpsapi_v3/fnpsapi.go
Normal file
116
platformapi/fnpsapi_v3/fnpsapi.go
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
package fnpsapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"git.rosy.net.cn/baseapi"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *API) SetToken(token string) {
|
||||||
|
a.locker.Lock()
|
||||||
|
defer a.locker.Unlock()
|
||||||
|
a.accessToken = token
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(appID, appSecret, merchantId string, config ...*platformapi.APIConfig) *API {
|
||||||
|
curConfig := platformapi.DefAPIConfig
|
||||||
|
if len(config) > 0 {
|
||||||
|
curConfig = *config[0]
|
||||||
|
}
|
||||||
|
return &API{
|
||||||
|
grantType: "authorization_code", // 授权模式,填固定值authorization_code
|
||||||
|
code: "cod3",
|
||||||
|
appID: appID,
|
||||||
|
merchantId: merchantId,
|
||||||
|
signature: "",
|
||||||
|
timestamp: time.Now().UnixNano(),
|
||||||
|
accessToken: "",
|
||||||
|
appSecret: appSecret,
|
||||||
|
locker: sync.RWMutex{},
|
||||||
|
client: &http.Client{Timeout: curConfig.ClientTimeout},
|
||||||
|
config: &curConfig,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// signParam2 apiV3签名算法SHA-256
|
||||||
|
func (a *API) signParam2() (sig string) {
|
||||||
|
sb := new(strings.Builder)
|
||||||
|
sb.WriteString("grant_type=")
|
||||||
|
sb.WriteString("CODE") //todo
|
||||||
|
sb.WriteString("&code=")
|
||||||
|
sb.WriteString(a.code) //todo
|
||||||
|
sb.WriteString("&app_id=")
|
||||||
|
sb.WriteString(a.appID)
|
||||||
|
sb.WriteString("&merchant_id=")
|
||||||
|
sb.WriteString(a.merchantId)
|
||||||
|
sb.WriteString("×tamp=")
|
||||||
|
sb.WriteString(utils.Int64ToStr(a.timestamp))
|
||||||
|
sig = sb.String()
|
||||||
|
sig = base64.StdEncoding.EncodeToString(sha256.New().Sum([]byte(sig)))
|
||||||
|
return sig
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *API) AccessAPI(baseUrl, actionApi, method string, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) {
|
||||||
|
// 序列化
|
||||||
|
data, err := json.Marshal(bizParams)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全路径请求参数
|
||||||
|
fullURL := utils.GenerateGetURL(baseUrl, actionApi, nil)
|
||||||
|
|
||||||
|
// 发送请求
|
||||||
|
sendUrl := func() *http.Request {
|
||||||
|
var request *http.Request
|
||||||
|
if method == "POST" {
|
||||||
|
request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(string(data)))
|
||||||
|
} else {
|
||||||
|
request, _ = http.NewRequest(http.MethodGet, utils.GenerateGetURL(baseUrl, actionApi, bizParams), nil)
|
||||||
|
}
|
||||||
|
request.Header.Set("Content-Type", "application/json")
|
||||||
|
return request
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数据解析
|
||||||
|
dataMarshal := func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
|
||||||
|
if jsonResult1 == nil {
|
||||||
|
return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if utils.MustInterface2Int64(jsonResult1["code"]) != 200 {
|
||||||
|
errLevel = platformapi.ErrLevelGeneralFail
|
||||||
|
err = utils.NewErrorCode(jsonResult1["msg"].(string), utils.Int64ToStr(utils.MustInterface2Int64(jsonResult1["code"])))
|
||||||
|
baseapi.SugarLogger.Debugf("fnps AccessAPI failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true))
|
||||||
|
}
|
||||||
|
retVal = jsonResult1
|
||||||
|
return errLevel, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = platformapi.AccessPlatformAPIWithRetry(a.client, sendUrl, a.config, dataMarshal)
|
||||||
|
return retVal, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取access_token
|
||||||
|
func (a *API) GetAccessToken() (tokenInfo *TokenInfo, err error) {
|
||||||
|
result, err := a.AccessAPI(TokenURL, "", RequestPost, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := utils.Map2StructByJson(result["data"], &tokenInfo, false); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokenInfo, err
|
||||||
|
}
|
||||||
175
platformapi/fnpsapi_v3/order.go
Normal file
175
platformapi/fnpsapi_v3/order.go
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
package fnpsapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
OrderCancelReson1 = 1 // 1:物流原因:订单长时间未分配骑手,
|
||||||
|
OrderCancelReson2 = 2 // 2:物流原因:分配骑手后,骑手长时间未取件 ,
|
||||||
|
OrderCancelReson3 = 3 // 3:物流原因:骑手告知不配送,让取消订单,
|
||||||
|
OrderCancelReson4 = 4 // 4:商品缺货/无法出货/已售完,
|
||||||
|
OrderCancelReson5 = 5 // 5:商户联系不上门店/门店关门了,
|
||||||
|
OrderCancelReson6 = 6 // 6:商户发错单,
|
||||||
|
OrderCancelReson7 = 7 // 7:商户/顾客自身定位错误,
|
||||||
|
OrderCancelReson8 = 8 // 8:商户改其他第三方配送,
|
||||||
|
OrderCancelReson9 = 9 // 9:顾客下错单/临时不想要了,
|
||||||
|
OrderCancelReson10 = 10 // 10:顾客自取/不在家/要求另改时间配送)(0类型已下线)
|
||||||
|
|
||||||
|
OrderStatusAccept = 1 //系统已接单
|
||||||
|
OrderStatusAssigned = 20 //已分配骑手
|
||||||
|
OrderStatusArrived = 80 //已到店
|
||||||
|
OrderStatusDelivering = 2 //配送中
|
||||||
|
OrderStatusDelivered = 3 //已送达
|
||||||
|
OrderStatusException = 5 //异常
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateOrderParam struct {
|
||||||
|
PartnerRemark string `json:"partner_remark,omitempty"`
|
||||||
|
PartnerOrderCode string `json:"partner_order_code,omitempty"`
|
||||||
|
NotifyURL string `json:"notify_url,omitempty"`
|
||||||
|
OrderType int `json:"order_type,omitempty"`
|
||||||
|
ChainStoreCode string `json:"chain_store_code,omitempty"`
|
||||||
|
TransportInfo *TransportInfo `json:"transport_info,omitempty"`
|
||||||
|
OrderAddTime int64 `json:"order_add_time,omitempty"`
|
||||||
|
OrderTotalAmount float64 `json:"order_total_amount,omitempty"`
|
||||||
|
OrderActualAmount float64 `json:"order_actual_amount,omitempty"`
|
||||||
|
OrderWeight float64 `json:"order_weight,omitempty"`
|
||||||
|
OrderRemark string `json:"order_remark,omitempty"`
|
||||||
|
IsInvoiced int `json:"is_invoiced"`
|
||||||
|
Invoice string `json:"invoice,omitempty"`
|
||||||
|
OrderPaymentStatus int `json:"order_payment_status,omitempty"`
|
||||||
|
OrderPaymentMethod int `json:"order_payment_method,omitempty"`
|
||||||
|
IsAgentPayment int `json:"is_agent_payment"`
|
||||||
|
RequirePaymentPay float64 `json:"require_payment_pay,omitempty"`
|
||||||
|
GoodsCount int `json:"goods_count,omitempty"`
|
||||||
|
RequireReceiveTime int64 `json:"require_receive_time,omitempty"`
|
||||||
|
SerialNumber string `json:"serial_number,omitempty"`
|
||||||
|
ReceiverInfo *ReceiverInfo `json:"receiver_info,omitempty"`
|
||||||
|
ItemsJSON []*ItemsJSON `json:"items_json,omitempty"`
|
||||||
|
OrderSource string `json:"order_source,omitempty"` //饿百订单传109
|
||||||
|
ChannelOrderCode string `json:"channel_order_code,omitempty"`
|
||||||
|
CookingTime int64 `json:"cooking_time,omitempty"`
|
||||||
|
PlatformPaidTime int64 `json:"platform_paid_time,omitempty"`
|
||||||
|
PlatformCreatedTime int64 `json:"platform_created_time,omitempty"`
|
||||||
|
MerchantCode string `json:"merchant_code,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReceiverInfo struct {
|
||||||
|
ReceiverName string `json:"receiver_name,omitempty"`
|
||||||
|
ReceiverPrimaryPhone string `json:"receiver_primary_phone,omitempty"`
|
||||||
|
ReceiverSecondPhone string `json:"receiver_second_phone,omitempty"`
|
||||||
|
ReceiverAddress string `json:"receiver_address,omitempty"`
|
||||||
|
ReceiverLongitude float64 `json:"receiver_longitude,omitempty"`
|
||||||
|
ReceiverLatitude float64 `json:"receiver_latitude,omitempty"`
|
||||||
|
PositionSource int `json:"position_source,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TransportInfo struct {
|
||||||
|
TransportName string `json:"transport_name,omitempty"`
|
||||||
|
TransportAddress string `json:"transport_address,omitempty"`
|
||||||
|
TransportLongitude float64 `json:"transport_longitude,omitempty"`
|
||||||
|
TransportLatitude float64 `json:"transport_latitude,omitempty"`
|
||||||
|
PositionSource int `json:"position_source,omitempty"`
|
||||||
|
TransportTel string `json:"transport_tel,omitempty"`
|
||||||
|
TransportRemark string `json:"transport_remark,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ItemsJSON struct {
|
||||||
|
ItemID string `json:"item_id,omitempty"`
|
||||||
|
ItemName string `json:"item_name,omitempty"`
|
||||||
|
ItemQuantity int `json:"item_quantity,omitempty"`
|
||||||
|
ItemPrice float64 `json:"item_price"`
|
||||||
|
ItemActualPrice float64 `json:"item_actual_price"`
|
||||||
|
ItemSize int `json:"item_size,omitempty"`
|
||||||
|
ItemRemark string `json:"item_remark,omitempty"`
|
||||||
|
IsNeedPackage int `json:"is_need_package"`
|
||||||
|
IsAgentPurchase int `json:"is_agent_purchase"`
|
||||||
|
AgentPurchasePrice float64 `json:"agent_purchase_price,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//https://open.ele.me/documents/%E5%88%9B%E5%BB%BA%E8%9C%82%E9%B8%9F%E8%AE%A2%E5%8D%95
|
||||||
|
func (a *API) CreateOrder(createOrderParam *CreateOrderParam) (err error) {
|
||||||
|
params := utils.Struct2FlatMap(createOrderParam)
|
||||||
|
_, err = a.AccessAPI("v2/order", URL, params, true)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
//order_cancel_reason_code 订单取消原因代码(1:用户取消,2:商家取消)
|
||||||
|
// order_cancel_code 订单取消编码(
|
||||||
|
// 1:物流原因:订单长时间未分配骑手,
|
||||||
|
// 2:物流原因:分配骑手后,骑手长时间未取件 ,
|
||||||
|
// 3:物流原因:骑手告知不配送,让取消订单,
|
||||||
|
// 4:商品缺货/无法出货/已售完, 5:商户联系不上门店/门店关门了, 6:商户发错单,
|
||||||
|
// 7:商户/顾客自身定位错误, 8:商户改其他第三方配送, 9:顾客下错单/临时不想要了,
|
||||||
|
// 10:顾客自取/不在家/要求另改时间配送)(0类型已下线)
|
||||||
|
|
||||||
|
type CancelOrderParam struct {
|
||||||
|
PartnerOrderCode string `json:"partner_order_code,omitempty"`
|
||||||
|
OrderCancelReasonCode int `json:"order_cancel_reason_code,omitempty"`
|
||||||
|
OrderCancelCode int `json:"order_cancel_code,omitempty"`
|
||||||
|
OrderCancelDescription string `json:"order_cancel_description,omitempty"`
|
||||||
|
OrderCancelTime int64 `json:"order_cancel_time,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *API) CancelOrder(cancelOrderParam *CancelOrderParam) (err error) {
|
||||||
|
params := utils.Struct2FlatMap(cancelOrderParam)
|
||||||
|
_, err = a.AccessAPI("v2/order/cancel", URL, params, true)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *API) ComplaintOrder(cancelOrderParam *CancelOrderParam) (err error) {
|
||||||
|
params := utils.Struct2FlatMap(cancelOrderParam)
|
||||||
|
_, err = a.AccessAPI("v2/order/complaint", URL, params, true)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type QueryOrderResult struct {
|
||||||
|
AbnormalCode string `json:"abnormal_code"`
|
||||||
|
AbnormalDesc string `json:"abnormal_desc"`
|
||||||
|
CarrierDriverID int `json:"carrier_driver_id"`
|
||||||
|
CarrierDriverName string `json:"carrier_driver_name"`
|
||||||
|
CarrierDriverPhone string `json:"carrier_driver_phone"`
|
||||||
|
ComplaintDescription interface{} `json:"complaintDescription"`
|
||||||
|
ComplaintStatus interface{} `json:"complaintStatus"`
|
||||||
|
EstimateArriveTime int64 `json:"estimate_arrive_time"`
|
||||||
|
EventLogDetails []struct {
|
||||||
|
CarrierDriverName string `json:"carrier_driver_name"`
|
||||||
|
CarrierDriverPhone string `json:"carrier_driver_phone"`
|
||||||
|
OccurTime int64 `json:"occur_time"`
|
||||||
|
OrderStatus int `json:"order_status"`
|
||||||
|
} `json:"event_log_details"`
|
||||||
|
HandleID interface{} `json:"handleId"`
|
||||||
|
OrderID interface{} `json:"orderId"`
|
||||||
|
OrderStatus int `json:"order_status"`
|
||||||
|
OrderTotalDeliveryCost float64 `json:"order_total_delivery_cost"`
|
||||||
|
OrderTotalDeliveryDiscount interface{} `json:"order_total_delivery_discount"`
|
||||||
|
OvertimeCompensationCost float64 `json:"overtime_compensation_cost"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
SupportClaims bool `json:"support_claims"`
|
||||||
|
TrackingID int64 `json:"trackingId"`
|
||||||
|
TrackingID2 int64 `json:"tracking_id"`
|
||||||
|
TransportStationID string `json:"transport_station_id"`
|
||||||
|
TransportStationTel string `json:"transport_station_tel"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *API) QueryOrder(partnerOrderCode string) (queryOrderResult *QueryOrderResult, err error) {
|
||||||
|
result, err := a.AccessAPI("v2/order/query", URL, map[string]interface{}{
|
||||||
|
"partner_order_code": partnerOrderCode,
|
||||||
|
}, true)
|
||||||
|
if err == nil {
|
||||||
|
utils.Map2StructByJson(result["data"], &queryOrderResult, false)
|
||||||
|
}
|
||||||
|
return queryOrderResult, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *API) ComplaintRider(partnerOrderCode string, orderComplaintCode int) (err error) {
|
||||||
|
_, err = a.AccessAPI("v2/order/complaint", URL, map[string]interface{}{
|
||||||
|
"partner_order_code": partnerOrderCode,
|
||||||
|
"order_complaint_code": orderComplaintCode,
|
||||||
|
"order_complaint_time": time.Now().UnixNano() / 1e6,
|
||||||
|
}, true)
|
||||||
|
return err
|
||||||
|
}
|
||||||
71
platformapi/fnpsapi_v3/store.go
Normal file
71
platformapi/fnpsapi_v3/store.go
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
package fnpsapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
StoreNotExist = "门店信息不存在"
|
||||||
|
StoreExist = "该门店已存在"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 创建门店.
|
||||||
|
func (a *API) CreateStore(createStoreParam *CreateStoreParam) (err error) {
|
||||||
|
params := utils.Struct2FlatMap(createStoreParam)
|
||||||
|
_, err = a.AccessAPI(ApiURL, "chainstoreCreate", RequestPost, params)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetStoreResult struct {
|
||||||
|
ChainStoreCode string `json:"chain_store_code"`
|
||||||
|
ChainStoreName string `json:"chain_store_name"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
Latitude string `json:"latitude"`
|
||||||
|
Longitude string `json:"longitude"`
|
||||||
|
PositionSource int `json:"position_source"`
|
||||||
|
City string `json:"city"`
|
||||||
|
ContactPhone string `json:"contact_phone"`
|
||||||
|
ServiceCode string `json:"service_code"`
|
||||||
|
Status int `json:"status"` //1关店,2开店
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *API) GetStore(storeID string) (getStoreResult *GetStoreResult, err error) {
|
||||||
|
result, err := a.AccessAPI("v2/chain_store/query", URL, map[string]interface{}{
|
||||||
|
"chain_store_code": []string{storeID},
|
||||||
|
}, true)
|
||||||
|
if err == nil {
|
||||||
|
if data, ok := result["data"].([]interface{}); ok {
|
||||||
|
utils.Map2StructByJson(data[0], &getStoreResult, false)
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf(result["msg"].(string))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return getStoreResult, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsErrShopNotExist(err error) bool {
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), StoreNotExist) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsErrShopExist(err error) bool {
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), StoreExist) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *API) UpdateStore(createStoreParam *CreateStoreParam) (err error) {
|
||||||
|
params := utils.Struct2FlatMap(createStoreParam)
|
||||||
|
_, err = a.AccessAPI("v2/chain_store/update", URL, params, true)
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -91,57 +91,51 @@ func Err2CallbackResponse(err error, data string) *CallbackResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *API) GetCallbackMsg(request *http.Request) (msg *CallbackMsg, callbackResponse *CallbackResponse) {
|
func (a *API) GetCallbackMsg(request *http.Request) (msg *CallbackMsg, callbackResponse *CallbackResponse) {
|
||||||
err := request.ParseForm()
|
if err := request.ParseForm(); err != nil {
|
||||||
if err == nil {
|
|
||||||
data := utils.URLValues2Map(request.Form)
|
|
||||||
if dataSign, ok := data[signKey]; ok {
|
|
||||||
// fullURL := strings.TrimRight(a.callbackURL+request.URL.Path, "/")
|
|
||||||
// sign := a.signParams(fullURL+"?", data)
|
|
||||||
cmd := strings.Trim(request.URL.EscapedPath(), "/")
|
|
||||||
cmd = cmd[strings.LastIndex(cmd, "/")+1:]
|
|
||||||
// if sign != dataSign.(string) && cmd != MsgTypeStoreStatusChanged {
|
|
||||||
// baseapi.SugarLogger.Debugf("mtwm GetCallbackMsg my sign:%v, data sign:%v", sign, dataSign.(string))
|
|
||||||
// callbackResponse = SignatureIsNotOk
|
|
||||||
// } else {
|
|
||||||
msg = &CallbackMsg{
|
|
||||||
Cmd: cmd,
|
|
||||||
}
|
|
||||||
msg.FormData = make(url.Values)
|
|
||||||
for k, v := range data {
|
|
||||||
// 美团外卖的用户催单信息的timestamp是毫秒(其它的事件是秒),统一归一化为秒
|
|
||||||
if cmd == MsgTypeUserUrgeOrder && k == "timestamp" {
|
|
||||||
intV := utils.Str2Int64(v.(string))
|
|
||||||
if intV > time.Now().Unix()*2 {
|
|
||||||
v = utils.Int64ToStr(intV / 1000)
|
|
||||||
data[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
msg.FormData.Set(k, v.(string))
|
|
||||||
}
|
|
||||||
msg.Timestamp = utils.Str2Int64(msg.FormData.Get("timestamp"))
|
|
||||||
msg.Sig = dataSign.(string)
|
|
||||||
msg.AppID = msg.FormData.Get("app_id")
|
|
||||||
|
|
||||||
if msg.Cmd == MsgTypeOrderRefund || msg.Cmd == MsgTypeOrderPartialRefund {
|
|
||||||
var refundData *CallbackRefundInfo
|
|
||||||
if err = utils.Map2StructByJson(data, &refundData, true); err == nil {
|
|
||||||
if refundData.Food != "" {
|
|
||||||
utils.UnmarshalUseNumber([]byte(refundData.Food), &refundData.FoodList)
|
|
||||||
}
|
|
||||||
if refundData.Pictures != "" {
|
|
||||||
utils.UnmarshalUseNumber([]byte(refundData.Pictures), &refundData.PictureList)
|
|
||||||
}
|
|
||||||
msg.Data = refundData
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
} else {
|
|
||||||
callbackResponse = SuccessResponse // 美团外卖PING消息没有sign
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
baseapi.SugarLogger.Warnf("mtwm GetCallbackMsg ParseForm failed with error:%v", err)
|
baseapi.SugarLogger.Warnf("mtwm GetCallbackMsg ParseForm failed with error:%v", err)
|
||||||
callbackResponse = Err2CallbackResponse(err, "")
|
callbackResponse = Err2CallbackResponse(err, "")
|
||||||
|
return nil, callbackResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data := utils.URLValues2Map(request.Form)
|
||||||
|
if dataSign, ok := data[signKey]; ok {
|
||||||
|
cmd := strings.Trim(request.URL.EscapedPath(), "/")
|
||||||
|
cmd = cmd[strings.LastIndex(cmd, "/")+1:]
|
||||||
|
msg = &CallbackMsg{
|
||||||
|
Cmd: cmd,
|
||||||
|
}
|
||||||
|
msg.FormData = make(url.Values)
|
||||||
|
for k, v := range data {
|
||||||
|
// 美团外卖的用户催单信息的timestamp是毫秒(其它的事件是秒),统一归一化为秒
|
||||||
|
if cmd == MsgTypeUserUrgeOrder && k == "timestamp" {
|
||||||
|
intV := utils.Str2Int64(v.(string))
|
||||||
|
if intV > time.Now().Unix()*2 {
|
||||||
|
v = utils.Int64ToStr(intV / 1000)
|
||||||
|
data[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.FormData.Set(k, v.(string))
|
||||||
|
}
|
||||||
|
msg.Timestamp = utils.Str2Int64(msg.FormData.Get("timestamp"))
|
||||||
|
msg.Sig = dataSign.(string)
|
||||||
|
msg.AppID = msg.FormData.Get("app_id")
|
||||||
|
|
||||||
|
if msg.Cmd == MsgTypeOrderRefund || msg.Cmd == MsgTypeOrderPartialRefund {
|
||||||
|
var refundData *CallbackRefundInfo
|
||||||
|
if err := utils.Map2StructByJson(data, &refundData, true); err == nil {
|
||||||
|
if refundData.Food != "" {
|
||||||
|
utils.UnmarshalUseNumber([]byte(refundData.Food), &refundData.FoodList)
|
||||||
|
}
|
||||||
|
if refundData.Pictures != "" {
|
||||||
|
utils.UnmarshalUseNumber([]byte(refundData.Pictures), &refundData.PictureList)
|
||||||
|
}
|
||||||
|
msg.Data = refundData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callbackResponse = SuccessResponse // 美团外卖PING消息没有sign
|
||||||
|
}
|
||||||
|
|
||||||
return msg, callbackResponse
|
return msg, callbackResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ func AccessPlatformAPIWithRetry(client *http.Client, handleRequest func() *http.
|
|||||||
baseapi.SugarLogger.Errorf("AccessPlatformAPIWithRetry:%s ioutil.ReadAll failed, url:%v, error:%v", trackInfo, request.URL, err)
|
baseapi.SugarLogger.Errorf("AccessPlatformAPIWithRetry:%s ioutil.ReadAll failed, url:%v, error:%v", trackInfo, request.URL, err)
|
||||||
errLevel = ErrLevelRecoverableErr // 读取数据错误,或数据格式错误认为是偶发情况,重试
|
errLevel = ErrLevelRecoverableErr // 读取数据错误,或数据格式错误认为是偶发情况,重试
|
||||||
} else {
|
} else {
|
||||||
baseapi.SugarLogger.Debugf("AccessPlatformAPIWithRetry:%s url:%v, response:%s", trackInfo, request.URL, string(bodyData))
|
//baseapi.SugarLogger.Debugf("AccessPlatformAPIWithRetry:%s url:%v, response:%s", trackInfo, request.URL, string(bodyData))
|
||||||
if err = utils.TryUnmarshalUseNumber(bodyData, &bodyGeneral); err != nil {
|
if err = utils.TryUnmarshalUseNumber(bodyData, &bodyGeneral); err != nil {
|
||||||
parseJSONErr = err
|
parseJSONErr = err
|
||||||
err = nil // 尝试忽略解析成json错
|
err = nil // 尝试忽略解析成json错
|
||||||
|
|||||||
Reference in New Issue
Block a user