golang iFood API 集成开发工具插件库golang-ifood-sdk的使用

golang-ifood-sdk 使用指南

概述

golang-ifood-sdk 是一个用于与 iFood API 集成的 Golang SDK,提供了两种版本的使用方式:V1 和 V2。

V2 版本使用示例

以下是使用 V2 版本的完整示例代码:

package main

import (
    sdk "github.com/arxdsilva/golang-ifood-sdk/container"
)

func main() {
    var clientID, clientSecret, user, password string
    clientID = os.GetEnv("CLIENT_ID")
    clientSecret = os.GetEnv("CLIENT_SECRET")
    // 创建新的 SDK 实例
    container := sdk.Create(clientID, clientSecret, 0, true)
    // 获取用户代码以连接供应商到餐厅
    uc, err := container.AuthService.V2GetUserCode()
    if err != nil { 
        log.Fatal(err)
    }
    fmt.Println("user_code_url_complete:", uc.VerificationURLComplete)
    v2Creds, err := container.AuthService.V2Authenticate("client_credentials", uc.Usercode, uc.AuthorizationCodeVerifier)
    if err != nil { 
        log.Fatal(err)
    }
    events, err := container.EventsService.V2Poll()
    if err != nil {
        log.Fatal(err)
    }
    err = container.EventsService.V2Acknowledge(events)
    if err != nil {
        log.Fatal(err)
    }
    var newOrdersDetails []orders.OrderDetails
	for _, event := range events {
        // 过滤非新订单
        if event.Code != "PLACED" {
            continue
        }
        details, err := container.OrdersService.V2GetDetails(event.ID)
        if err != nil {
            fmt.Println("err: ", err)
            continue
        }
        newOrdersDetails = append(newOrdersDetails, details)
	}
	for _, order := range newOrdersDetails {
        // 更改订单状态
        err = container.OrdersService.V2SetConfirmStatus(order.ID)
        if err != nil {
            fmt.Println("err: ", err)
            continue
        }
        // 更改其他状态
    }
    fmt.Printf("new orders: %+v\n", newOrdersDetails)
}

V1 版本使用示例

以下是使用 V1 版本的完整示例代码:

package main

import (
    sdk "github.com/arxdsilva/golang-ifood-sdk/container"
)

func main() {
    var clientID, clientSecret, user, password string
    clientID = os.GetEnv("CLIENT_ID")
    clientSecret = os.GetEnv("CLIENT_SECRET")
    // 创建新的 SDK 实例
    container := sdk.New(0, time.Minute, false)
    container.GetHttpAdapter()
    // 分配服务
    container.GetAuthenticationService(clientID, clientSecret)
    container.GetMerchantService()
    container.GetCatalogService()
    container.GetEventsService()
    container.GetOrdersService()
    user = os.GetEnv("USER")
    password = os.GetEnv("PASSWORD")
    creds, err := container.AuthService.Authenticate(user,password)
    if err != nil { 
        log.Fatal(err)
    }
    merchants, err := container.MerchantService.ListAll()
    if err != nil { 
        log.Fatal(err)
    }
    events, err := container.EventsService.Poll()
    if err != nil {
        log.Fatal(err)
    }
    var newOrdersDetails []orders.OrderDetails
    for _, event := range events {
        err = container.EventsService.Acknowledge(event)
        if err != nil {
            fmt.Println("err: ", err)
            continue
        }
        // 过滤非新订单
        if event.Code != "PLACED" {
            continue
        }
        details, err := container.OrdersService.GetDetails(event.ID)
        if err != nil {
            fmt.Println("err: ", err)
            continue
        }
        newOrdersDetails = append(newOrdersDetails, details)
	}
	for _, order := range newOrdersDetails {
        // 更改订单状态
        err = container.OrdersService.SetIntegrateStatus(order.ID)
        if err != nil {
            fmt.Println("err: ", err)
            continue
        }
        // 更改其他状态
    }
    fmt.Printf("new orders: %+v\n", newOrdersDetails)
}

主要功能

  1. 认证服务:处理与 iFood API 的认证流程
  2. 商家服务:获取商家信息
  3. 目录服务:管理商品目录
  4. 事件服务:轮询和处理订单事件
  5. 订单服务:获取订单详情和更改订单状态

注意事项

  • 使用前需要设置必要的环境变量(CLIENT_ID, CLIENT_SECRET 等)
  • V2 版本使用了更新的认证流程
  • 需要处理 API 调用可能返回的错误

更多关于golang iFood API 集成开发工具插件库golang-ifood-sdk的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang iFood API 集成开发工具插件库golang-ifood-sdk的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang iFood API 集成开发工具库指南

iFood 是巴西领先的食品配送平台,提供了丰富的API接口供开发者集成。以下是关于使用 golang-ifood-sdk 或类似工具进行 iFood API 集成的详细指南。

1. 准备工作

在开始之前,你需要:

  1. 注册为 iFood 开发者并创建应用
  2. 获取 API 认证凭据 (Client ID 和 Client Secret)
  3. 设置回调 URL (用于 OAuth 流程)

2. 安装 SDK

如果存在官方的 golang-ifood-sdk,你可以使用以下命令安装:

go get github.com/ifood/golang-ifood-sdk

如果没有官方 SDK,你可以使用通用的 HTTP 客户端与 iFood API 交互:

go get github.com/go-resty/resty/v2

3. 认证流程示例

iFood 使用 OAuth 2.0 进行认证,以下是获取访问令牌的示例代码:

package main

import (
	"fmt"
	"log"
	"github.com/go-resty/resty/v2"
)

const (
	clientID     = "your-client-id"
	clientSecret = "your-client-secret"
	redirectURI  = "your-redirect-uri"
)

func main() {
	client := resty.New()
	
	// 获取授权码 (通常在回调处理中)
	authCode := "authorization-code-from-callback"
	
	// 使用授权码获取访问令牌
	resp, err := client.R().
		SetFormData(map[string]string{
			"grant_type":    "authorization_code",
			"code":          authCode,
			"redirect_uri":  redirectURI,
			"client_id":     clientID,
			"client_secret": clientSecret,
		}).
		Post("https://merchant-api.ifood.com.br/oauth/token")
	
	if err != nil {
		log.Fatalf("Error getting access token: %v", err)
	}
	
	fmt.Printf("Access Token Response: %s\n", resp.Body())
}

4. 常用 API 调用示例

4.1 获取商家信息

func getMerchantInfo(accessToken string) {
	client := resty.New()
	
	resp, err := client.R().
		SetAuthToken(accessToken).
		Get("https://merchant-api.ifood.com.br/merchant/v1.0/merchants")
	
	if err != nil {
		log.Printf("Error getting merchant info: %v", err)
		return
	}
	
	fmt.Printf("Merchant Info: %s\n", resp.Body())
}

4.2 获取订单列表

func getOrders(accessToken, merchantID string) {
	client := resty.New()
	
	resp, err := client.R().
		SetAuthToken(accessToken).
		SetQueryParams(map[string]string{
			"merchantId": merchantID,
			"page":      "0",
			"size":      "20",
		}).
		Get("https://merchant-api.ifood.com.br/order/v1.0/orders")
	
	if err != nil {
		log.Printf("Error getting orders: %v", err)
		return
	}
	
	fmt.Printf("Orders: %s\n", resp.Body())
}

4.3 更新订单状态

func updateOrderStatus(accessToken, orderID, status string) {
	client := resty.New()
	
	resp, err := client.R().
		SetAuthToken(accessToken).
		SetHeader("Content-Type", "application/json").
		SetBody(map[string]string{
			"status": status,
		}).
		Post(fmt.Sprintf("https://merchant-api.ifood.com.br/order/v1.0/orders/%s/status", orderID))
	
	if err != nil {
		log.Printf("Error updating order status: %v", err)
		return
	}
	
	fmt.Printf("Order Status Update Response: %s\n", resp.Body())
}

5. 最佳实践

  1. 令牌管理:实现令牌的自动刷新机制,避免频繁重新认证
  2. 错误处理:正确处理 API 限流 (429 状态码) 和其他错误情况
  3. 日志记录:记录所有 API 请求和响应,便于调试
  4. 重试机制:对于临时性错误实现自动重试
  5. 测试环境:先在沙箱环境中测试你的集成

6. 完整示例

以下是一个更完整的示例,包含令牌刷新和基本错误处理:

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"time"
	
	"github.com/go-resty/resty/v2"
)

type TokenResponse struct {
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
	ExpiresIn    int    `json:"expires_in"`
	TokenType    string `json:"token_type"`
}

type IFoodClient struct {
	client       *resty.Client
	accessToken  string
	refreshToken string
	expiresAt    time.Time
	clientID     string
	clientSecret string
}

func NewIFoodClient(clientID, clientSecret string) *IFoodClient {
	return &IFoodClient{
		client:       resty.New(),
		clientID:     clientID,
		clientSecret: clientSecret,
	}
}

func (c *IFoodClient) ensureTokenValid() error {
	if time.Now().Before(c.expiresAt) {
		return nil
	}
	
	if c.refreshToken == "" {
		return fmt.Errorf("no refresh token available")
	}
	
	resp, err := c.client.R().
		SetFormData(map[string]string{
			"grant_type":    "refresh_token",
			"refresh_token": c.refreshToken,
			"client_id":     c.clientID,
			"client_secret": c.clientSecret,
		}).
		Post("https://merchant-api.ifood.com.br/oauth/token")
	
	if err != nil {
		return fmt.Errorf("token refresh failed: %v", err)
	}
	
	var tokenResp TokenResponse
	if err := json.Unmarshal(resp.Body(), &tokenResp); err != nil {
		return fmt.Errorf("failed to parse token response: %v", err)
	}
	
	c.accessToken = tokenResp.AccessToken
	c.refreshToken = tokenResp.RefreshToken
	c.expiresAt = time.Now().Add(time.Duration(tokenResp.ExpiresIn-60) * time.Second) // 提前60秒过期
	
	return nil
}

func (c *IFoodClient) GetMerchants() (string, error) {
	if err := c.ensureTokenValid(); err != nil {
		return "", err
	}
	
	resp, err := c.client.R().
		SetAuthToken(c.accessToken).
		Get("https://merchant-api.ifood.com.br/merchant/v1.0/merchants")
	
	if err != nil {
		return "", fmt.Errorf("failed to get merchants: %v", err)
	}
	
	return resp.String(), nil
}

func main() {
	client := NewIFoodClient("your-client-id", "your-client-secret")
	// 初始化时设置 accessToken 和 refreshToken (通常从数据库或配置加载)
	
	merchants, err := client.GetMerchants()
	if err != nil {
		log.Fatalf("Error: %v", err)
	}
	
	fmt.Println("Merchants:", merchants)
}

7. 注意事项

  1. iFood API 有严格的速率限制,请确保遵守
  2. 生产环境中应该将凭据存储在安全的地方,而不是硬编码在代码中
  3. 定期检查 API 文档更新,iFood 可能会更改 API 端点或参数
  4. 考虑实现 webhook 接收订单状态变更通知

希望这个指南能帮助你开始使用 Golang 进行 iFood API 集成开发!如需更详细的信息,请参考 iFood 官方 API 文档。

回到顶部