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)
}
主要功能
- 认证服务:处理与 iFood API 的认证流程
- 商家服务:获取商家信息
- 目录服务:管理商品目录
- 事件服务:轮询和处理订单事件
- 订单服务:获取订单详情和更改订单状态
注意事项
- 使用前需要设置必要的环境变量(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. 准备工作
在开始之前,你需要:
- 注册为 iFood 开发者并创建应用
- 获取 API 认证凭据 (Client ID 和 Client Secret)
- 设置回调 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. 最佳实践
- 令牌管理:实现令牌的自动刷新机制,避免频繁重新认证
- 错误处理:正确处理 API 限流 (429 状态码) 和其他错误情况
- 日志记录:记录所有 API 请求和响应,便于调试
- 重试机制:对于临时性错误实现自动重试
- 测试环境:先在沙箱环境中测试你的集成
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. 注意事项
- iFood API 有严格的速率限制,请确保遵守
- 生产环境中应该将凭据存储在安全的地方,而不是硬编码在代码中
- 定期检查 API 文档更新,iFood 可能会更改 API 端点或参数
- 考虑实现 webhook 接收订单状态变更通知
希望这个指南能帮助你开始使用 Golang 进行 iFood API 集成开发!如需更详细的信息,请参考 iFood 官方 API 文档。