diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b00f8b8..0e955d52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ -## v1.0.36 / 2021-12-27 +## v1.0.37 / 2021-12-27 +- update kashangwl service - update pinduoduo service ## v1.0.35 / 2021-12-25 diff --git a/library.go b/library.go index b6d89646..71bcabb5 100644 --- a/library.go +++ b/library.go @@ -1,5 +1,5 @@ package go_library func Version() string { - return "v1.0.36" + return "v1.0.37" } diff --git a/service/kashangwl/api.buy.go b/service/kashangwl/api.buy.go new file mode 100644 index 00000000..a5663bd8 --- /dev/null +++ b/service/kashangwl/api.buy.go @@ -0,0 +1,31 @@ +package kashangwl + +// ApiBuyResult 返回参数 +type ApiBuyResult struct { + Code string `json:"code"` + Message string `json:"message"` + Data struct { + OrderID int64 `json:"order_id"` // 订单号 + ProductPrice string `json:"product_price"` // 商品价格 + TotalPrice string `json:"total_price"` // 总支付价格 + RechargeUrl string `json:"recharge_url"` // 卡密充值网址 + State int `json:"state"` // 订单状态(100:等待发货,101:正在充值,200:交易成功,500:交易失败,501:未知状态) + Cards []struct { + CardNo string `json:"card_no"` + CardPassword string `json:"card_password"` + } `json:"cards,omitempty"` // 卡密(仅当订单成功并且商品类型为卡密时返回此数据) + Tickets []struct { + No string `json:"no"` + Ticket string `json:"ticket"` + } `json:"tickets,omitempty"` // 卡券(仅当订单成功并且商品类型为卡券时返回此数据) + } `json:"data"` +} + +// ApiBuy 购买商品 http://doc.cqmeihu.cn/sales/BuyProduct.html +func (app *App) ApiBuy(notMustParams ...Params) (body []byte, err error) { + // 参数 + params := app.NewParamsWith(notMustParams...) + // 请求 + body, err = app.request("http://www.kashangwl.com/api/buy", params) + return body, err +} diff --git a/service/kashangwl/api.order.go b/service/kashangwl/api.order.go new file mode 100644 index 00000000..f8287d92 --- /dev/null +++ b/service/kashangwl/api.order.go @@ -0,0 +1,55 @@ +package kashangwl + +import ( + "strconv" +) + +// ApiOrderResult 返回参数 +type ApiOrderResult struct { + Code string `json:"code"` + Message string `json:"message"` + Data struct { + ID int64 `json:"id"` // 订单号 + ProductID int `json:"product_id"` // 商品编号 + ProductName string `json:"product_name"` // 商品名称 + ProductType int `json:"product_type"` // 商品类型(1:充值,2:卡密,3:卡券,4:人工) + ProductPrice string `json:"product_price"` // 售价 + Quantity int `json:"quantity"` // 购买数量 + TotalPrice string `json:"total_price"` // 总支付价格 + RefundedAmount float64 `json:"refunded_amount"` // 已退款金额 + BuyerCustomerID int `json:"buyer_customer_id"` // 买家编号 + BuyerCustomerName string `json:"buyer_customer_name"` // 买家名称 + SellerCustomerID int `json:"seller_customer_id"` // 卖家编号 + SellerCustomerName string `json:"seller_customer_name"` // 卖家名称 + State int `json:"state"` // 订单状态(100:等待发货,101:正在充值,200:交易成功,500:交易失败,501:未知状态) + CreatedAt string `json:"created_at"` // 下单时间 + RechargeAccount string `json:"recharge_account"` // 充值账号 + ProgressInit int `json:"progress_init"` // 充值进度:初始值 + ProgressNow int `json:"progress_now"` // 充值进度:现在值 + ProgressTarget int `json:"progress_target"` // 充值进度:目标值 + RechargeInfo string `json:"recharge_info"` // 返回信息 + RechargeUrl string `json:"recharge_url"` // 卡密充值网址 + Cards []struct { + No string `json:"no"` + Password string `json:"password"` + } `json:"cards"` //【卡密类订单】卡密 + RechargeParams string `json:"recharge_params"` //【充值类订单】 + OuterOrderID string `json:"outer_order_id,omitempty"` // 外部订单号 + } `json:"data"` +} + +// ApiOrder 获取单个订单信息 http://doc.cqmeihu.cn/sales/OrderInfo.html +func (app *App) ApiOrder(orderId int64) (body []byte, err error) { + // 参数 + params := NewParams() + params.Set("order_id", orderId) + // 请求 + body, err = app.request("http://www.kashangwl.com/api/order", params) + return body, err +} + +// ApiOrderToPrice 价格单位转换 +func (app *App) ApiOrderToPrice(price string) (priceFloat64 float64) { + priceFloat64, _ = strconv.ParseFloat(price, 64) + return priceFloat64 +} diff --git a/service/kashangwl/app.go b/service/kashangwl/app.go new file mode 100644 index 00000000..f8f35a44 --- /dev/null +++ b/service/kashangwl/app.go @@ -0,0 +1,26 @@ +package kashangwl + +import ( + "encoding/json" + "github.com/dtapps/go-library/utils/gohttp" + "time" +) + +// App 卡商网服务 +type App struct { + CustomerId int // 商家编号 + CustomerKey string // 商家密钥 +} + +func (app *App) request(url string, params map[string]interface{}) ([]byte, error) { + // 公共参数 + params["timestamp"] = time.Now().UnixNano() / 1e6 + params["customer_id"] = app.CustomerId + // 签名参数 + params["sign"] = app.getSign(app.CustomerKey, params) + // 请求参数 + paramsStr, err := json.Marshal(params) + // 请求 + postJson, err := gohttp.PostJson(url, paramsStr) + return postJson.Body, err +} diff --git a/service/kashangwl/kashangwl.go b/service/kashangwl/kashangwl.go deleted file mode 100644 index 1295f529..00000000 --- a/service/kashangwl/kashangwl.go +++ /dev/null @@ -1,85 +0,0 @@ -package kashangwl - -import ( - "bytes" - "crypto/md5" - "encoding/hex" - "encoding/json" - "github.com/bitly/go-simplejson" - "github.com/dtapps/go-library/utils/goparams" - "io" - "io/ioutil" - "net/http" - "sort" - "strings" - "time" -) - -const api = "http://www.kashangwl.com/api/" - -// Parameter 参数 -type Parameter map[string]interface{} - -// ParameterEncode 参数 -type ParameterEncode []string - -// KaShangWl 每次请求需传入以下参数 -type KaShangWl struct { - CustomerId int // 商家编号 - CustomerKey string // 商家密钥 -} - -// Send 发送 http://cha.kashangwl.com/api-doc/ -func (w *KaShangWl) Send(url string, param Parameter) (*simplejson.Json, error) { - // 处理数据 - param.setRequestData(w) - // 请求 - resp, e := http.Post(api+url, "application/json", strings.NewReader(param.getRequestData())) - if e != nil { - return nil, e - } - defer resp.Body.Close() - // 返回结果 - body, _ := ioutil.ReadAll(resp.Body) - respJson, err := simplejson.NewJson(body) - if err != nil { - return nil, err - } - return respJson, nil -} - -// md5(key + 参数1名称 + 参数1值 + 参数2名称 + 参数2值...) 加密源串应为{key}customer_id1192442order_id827669582783timestamp1626845767 -func sign(params Parameter, customerKey string) string { - // 参数按照参数名的字典升序排列 - var keys []string - for k := range params { - keys = append(keys, k) - } - sort.Strings(keys) - // 拼接 - query := bytes.NewBufferString(customerKey) - for _, k := range keys { - query.WriteString(k) - query.WriteString(goparams.GetParamsString(params[k])) - } - // MD5加密 - h := md5.New() - io.Copy(h, query) - return strings.ToLower(hex.EncodeToString(h.Sum(nil))) -} - -// 设置请求数据 -func (p Parameter) setRequestData(w *KaShangWl) { - // 当前时间戳(单位:秒) - timestamp := time.Now().UnixNano() / 1e6 - p["timestamp"] = timestamp - p["customer_id"] = w.CustomerId - // 设置签名 - p["sign"] = sign(p, w.CustomerKey) -} - -// 获取请求数据 -func (p Parameter) getRequestData() string { - j, _ := json.Marshal(p) - return string(j) -} diff --git a/service/kashangwl/kashangwl_test.go b/service/kashangwl/kashangwl_test.go deleted file mode 100644 index 6a1ab1a9..00000000 --- a/service/kashangwl/kashangwl_test.go +++ /dev/null @@ -1,24 +0,0 @@ -package kashangwl - -import ( - "fmt" - _url "github.com/dtapps/go-library/service/kashangwl/url" - "testing" -) - -func TestName(t *testing.T) { - wl := KaShangWl{ - CustomerId: 0, - CustomerKey: "", - } - - param := Parameter{ - "order_id": 827669582783, - } - send, err := wl.Send(_url.Order, param) - fmt.Printf("send:%s\n", send) - if err != nil { - t.Errorf("err:%v\n", err) - return - } -} diff --git a/service/kashangwl/order.go b/service/kashangwl/order.go new file mode 100644 index 00000000..36e37021 --- /dev/null +++ b/service/kashangwl/order.go @@ -0,0 +1,43 @@ +package kashangwl + +// OrderResult 返回参数 +type OrderResult struct { + Code string `json:"code"` + Message string `json:"message"` + Data struct { + Id int64 `json:"id"` + ProductId int `json:"product_id"` + ProductName string `json:"product_name"` + ProductType int `json:"product_type"` + ProductPrice string `json:"product_price"` + Quantity int `json:"quantity"` + TotalPrice string `json:"total_price"` + RefundedAmount string `json:"refunded_amount"` + BuyerCustomerId int `json:"buyer_customer_id"` + BuyerCustomerName string `json:"buyer_customer_name"` + State int `json:"state"` + CreatedAt string `json:"created_at"` + OuterOrderId string `json:"outer_order_id"` + RechargeAccount string `json:"recharge_account"` + RechargeParams string `json:"recharge_params"` + RechargeInfo string `json:"recharge_info"` + RechargeUrl string `json:"recharge_url"` + Cards []struct { + No string `json:"no"` + Password string `json:"password"` + } `json:"cards"` + } `json:"data"` +} + +// Order 获取单个订单信息。 +// 仅能获取自己购买的订单。 +// http://doc.cqmeihu.cn/sales/OrderInfo.html +func (app App) Order(orderId string) (body []byte, err error) { + // 参数 + param := NewParams() + param.Set("order_id", orderId) + params := app.NewParamsWith(param) + // 请求 + body, err = app.request("http://www.kashangwl.com/api/order", params) + return body, err +} diff --git a/service/kashangwl/params.go b/service/kashangwl/params.go new file mode 100644 index 00000000..13b54712 --- /dev/null +++ b/service/kashangwl/params.go @@ -0,0 +1,27 @@ +package kashangwl + +// Params 请求参数 +type Params map[string]interface{} + +func NewParams() Params { + p := make(Params) + return p +} + +func (app *App) NewParamsWith(params ...Params) Params { + p := make(Params) + for _, v := range params { + p.SetParams(v) + } + return p +} + +func (p Params) Set(key string, value interface{}) { + p[key] = value +} + +func (p Params) SetParams(params Params) { + for key, value := range params { + p[key] = value + } +} diff --git a/service/kashangwl/product.go b/service/kashangwl/product.go new file mode 100644 index 00000000..2e506f1f --- /dev/null +++ b/service/kashangwl/product.go @@ -0,0 +1,56 @@ +package kashangwl + +// ProductResult 返回参数 +type ProductResult struct { + Code string `json:"code"` + Message string `json:"message"` + Data struct { + Id int64 `json:"id"` + ProductName string `json:"product_name,omitempty"` + Name string `json:"name"` + Price float64 `json:"price"` + ValidPurchasingQuantity string `json:"valid_purchasing_quantity"` + SuperiorCommissionsRate int `json:"superior_commissions_rate"` + Type int `json:"type"` + SupplyState int `json:"supply_state"` + StockState int `json:"stock_state"` + BanStartAt string `json:"ban_start_at,omitempty"` + BanEndAt string `json:"ban_end_at,omitempty"` + } `json:"data"` +} + +// Product 获取单个商品信息 +// http://doc.cqmeihu.cn/sales/product-info.html +func (app App) Product(productId int64) (body []byte, err error) { + // 参数 + params := NewParams() + params.Set("product_id", productId) + // 请求 + body, err = app.request("http://www.kashangwl.com/api/product", params) + return body, err +} + +// ProductRechargeParamsResult 返回参数 +type ProductRechargeParamsResult struct { + Code string `json:"code"` + Message string `json:"message"` + Data struct { + RechargeAccountLabel string `json:"recharge_account_label"` + RechargeParams []struct { + Name string `json:"name"` + Type string `json:"type"` + Options string `json:"options"` + } `json:"recharge_params"` + } `json:"data"` +} + +// ProductRechargeParams 接口说明 +// 获取商品的充值参数(仅支持充值类商品) +// http://doc.cqmeihu.cn/sales/ProductParams.html +func (app App) ProductRechargeParams(notMustParams ...Params) (body []byte, err error) { + // 参数 + params := app.NewParamsWith(notMustParams...) + // 请求 + body, err = app.request("http://www.kashangwl.com/api/product/recharge-params", params) + return body, err +} diff --git a/service/kashangwl/sign.go b/service/kashangwl/sign.go new file mode 100644 index 00000000..f2fbe561 --- /dev/null +++ b/service/kashangwl/sign.go @@ -0,0 +1,59 @@ +package kashangwl + +import ( + "bytes" + "crypto/md5" + "encoding/hex" + "encoding/json" + "github.com/dtapps/go-library/utils/goparams" + "io" + "net/url" + "sort" + "strconv" + "strings" +) + +// md5(key + 参数1名称 + 参数1值 + 参数2名称 + 参数2值...) 加密源串应为{key}customer_id1192442order_id827669582783timestamp1626845767 +func (app *App) getSign(customerKey string, params map[string]interface{}) string { + // 参数按照参数名的字典升序排列 + var keys []string + for k := range params { + keys = append(keys, k) + } + sort.Strings(keys) + // 拼接 + query := bytes.NewBufferString(customerKey) + for _, k := range keys { + query.WriteString(k) + query.WriteString(goparams.GetParamsString(params[k])) + } + // MD5加密 + h := md5.New() + io.Copy(h, query) + return strings.ToLower(hex.EncodeToString(h.Sum(nil))) +} + +// 获取请求数据 +func (app *App) getRequestData(params map[string]interface{}) string { + // 公共参数 + args := url.Values{} + // 请求参数 + for key, val := range params { + args.Set(key, app.getString(val)) + } + return args.Encode() +} + +func (app *App) getString(i interface{}) string { + switch v := i.(type) { + case string: + return v + case int: + return strconv.Itoa(v) + case bool: + return strconv.FormatBool(v) + default: + marshal, _ := json.Marshal(v) + return string(marshal) + } +} diff --git a/service/kashangwl/url/url.go b/service/kashangwl/url/url.go deleted file mode 100644 index a5fa1d0a..00000000 --- a/service/kashangwl/url/url.go +++ /dev/null @@ -1,9 +0,0 @@ -package _url - -const ( - Product = "product" // 获取单个商品信息 http://cha.kashangwl.com/api-doc/basic/product.html - ProductRechargeParams = "product/recharge-params" // 获取商品的充值参数 http://cha.kashangwl.com/api-doc/basic/product-recharge-params.html - Buy = "buy" // 购买商品(不支持购买选号类型的商品) http://cha.kashangwl.com/api-doc/basic/buy.html - Order = "order" // 获取单个订单信息 http://cha.kashangwl.com/api-doc/basic/order.html - Customer = "customer" // 获取商家信息 http://cha.kashangwl.com/api-doc/basic/customer.html -)