跳转到主要内容

概述

Waffo Pancake GraphQL API 提供对所有数据的只读访问。写操作使用 REST action 端点,查询使用 GraphQL。
POST /v1/graphql
认证方式: API Key
GraphQL API 仅支持查询(Query)。所有写操作(创建、更新、删除)使用 REST action 端点

发送请求

请求体

字段类型必需说明
querystringGraphQL 查询字符串
variablesobject查询变量
import { WaffoPancake } from "@waffo/pancake-ts";

const client = new WaffoPancake({
  merchantId: process.env.WAFFO_MERCHANT_ID!,
  privateKey: process.env.WAFFO_PRIVATE_KEY!,
});

interface StoresQuery {
  stores: Array<{ id: string; name: string; status: string }>;
}

const result = await client.graphql.query<StoresQuery>({
  query: `{ stores { id name status } }`,
});
console.log(result.stores);
// => [{ id: "STO_2aUyqjCzEIiEcYMKj7TZtw", name: "My Store", status: "active" }]
// Uses callApi() helper from authentication.mdx
const result = await callApi("POST", "/v1/graphql", {
  query: "query { stores { id name status } }",
  variables: {},
});
console.log(result.data.stores);
// => [{ id: "STO_2aUyqjCzEIiEcYMKj7TZtw", name: "My Store", status: "active" }]
// Uses callApi() helper from authentication.mdx
String body = """
    {"query":"query { stores { id name status } }","variables":{}}""";

String response = callApi("POST", "/v1/graphql", body);
System.out.println(response);
// => {"data":{"stores":[{"id":"STO_2aUyqjCzEIiEcYMKj7TZtw","name":"My Store","status":"active"}]}}
# Uses call_api() helper from authentication.mdx
result = call_api("POST", "/v1/graphql", {
    "query": "query { stores { id name status } }",
    "variables": {},
})
stores = result["data"]["stores"]
print(stores)
# => [{"id": "STO_2aUyqjCzEIiEcYMKj7TZtw", "name": "My Store", "status": "active"}]
// Uses callAPI() helper from authentication.mdx
body := map[string]interface{}{
    "query":     "query { stores { id name status } }",
    "variables": map[string]interface{}{},
}
result, err := callAPI("POST", "/v1/graphql", body)
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(result))
// => {"data":{"stores":[{"id":"STO_2aUyqjCzEIiEcYMKj7TZtw","name":"My Store","status":"active"}]}}
// Uses call_api() helper from authentication.mdx
let body = serde_json::json!({
    "query": "query { stores { id name status } }",
    "variables": {}
});
let result = call_api("POST", "/v1/graphql", &body).await?;
println!("{}", result);
// => {"data":{"stores":[{"id":"STO_2aUyqjCzEIiEcYMKj7TZtw","name":"My Store","status":"active"}]}}
/* Uses call_api() helper from authentication.mdx */
const char *body = "{\"query\":\"query { stores { id name status } }\",\"variables\":{}}";
char *response = call_api("POST", "/v1/graphql", body);
printf("%s\n", response);
free(response);
// Uses callApi() helper from authentication.mdx
std::string body = R"({"query":"query { stores { id name status } }","variables":{}})";
std::string response = callApi("POST", "/v1/graphql", body);
std::cout << response << std::endl;
// => {"data":{"stores":[{"id":"STO_2aUyqjCzEIiEcYMKj7TZtw","name":"My Store","status":"active"}]}}
MERCHANT_ID="MER_2aUyqjCzEIiEcYMKj7TZtw"
TIMESTAMP=$(date +%s)
BODY='{"query":"query { stores { id name status } }","variables":{}}'
BODY_HASH=$(echo -n "$BODY" | openssl dgst -sha256 -binary | base64 -w 0)
CANONICAL_REQUEST="POST
/v1/graphql
$TIMESTAMP
$BODY_HASH"

SIGNATURE=$(echo -n "$CANONICAL_REQUEST" | openssl dgst -sha256 -sign private_key.pem | base64 -w 0)

curl -X POST "https://api.waffo.ai/v1/graphql" \
  -H "Content-Type: application/json" \
  -H "X-Merchant-Id: $MERCHANT_ID" \
  -H "X-Timestamp: $TIMESTAMP" \
  -H "X-Signature: $SIGNATURE" \
  -d "$BODY"
MERCHANT_ID="MER_2aUyqjCzEIiEcYMKj7TZtw"
TIMESTAMP=$(date +%s)
BODY='{"query":"query { stores { id name status } }","variables":{}}'
BODY_HASH=$(echo -n "$BODY" | openssl dgst -sha256 -binary | base64 -w 0)
CANONICAL_REQUEST="POST
/v1/graphql
$TIMESTAMP
$BODY_HASH"

SIGNATURE=$(echo -n "$CANONICAL_REQUEST" | openssl dgst -sha256 -sign private_key.pem | base64 -w 0)

wget -qO- "https://api.waffo.ai/v1/graphql" \
  --header="Content-Type: application/json" \
  --header="X-Merchant-Id: $MERCHANT_ID" \
  --header="X-Timestamp: $TIMESTAMP" \
  --header="X-Signature: $SIGNATURE" \
  --post-data="$BODY"

状态码

状态码说明
200查询成功(GraphQL 错误在响应体的 errors 字段中)
400缺少查询 / 深度超限 / 无效环境 / 缺少或无效角色
401认证失败
403不允许的操作类型(仅支持 Query)
500内部服务器错误

Schema 内省

推荐: 使用标准 GraphQL 内省查询来发现完整 Schema。这确保您始终使用最新的类型和字段。
GraphQL 类型与 REST/SDK 类型不同。 例如,prices 在 REST 中是 Record<string, PriceInfo>(对象 map),但在 GraphQL 中是 [CurrencyPrice!]!{currency, priceInfo} 数组);metadata 在 REST 中是解析后的对象,但在 GraphQL 中是 JSON 字符串。请勿使用 SDK TypeScript 类型定义来构造 GraphQL 查询——始终使用内省或以下示例。

查询所有可用查询

query {
  __schema {
    queryType {
      fields {
        name
        description
        args {
          name
          type { name kind }
        }
      }
    }
  }
}

查询类型字段

query {
  __type(name: "Store") {
    name
    fields {
      name
      type { name kind ofType { name } }
    }
  }
}
API Key 认证授予您访问 18 种查询类型,包括单实体查询、带过滤的列表查询、计数查询和分析查询。

过滤

GraphQL 查询支持使用类型化过滤对象进行过滤:
类型运算符示例
StringFiltereq, ne, in, contains{ storeId: { eq: "STO_xxx" } }
DateTimeFiltereq, gt, lt, gte, lte{ createdAt: { gte: "2026-01-01" } }
IntFiltereq, gt, lt, gte, lte{ amount: { gte: 1000 } }
BooleanFiltereq{ isActive: { eq: true } }
query {
  onetimeProducts(
    filter: {
      storeId: { eq: "STO_3bVzrkD0FJjFdZNLk8Ualx" }
      status: { eq: "active" }
    }
  ) {
    id
    name
    prices
  }
}

分页

使用 limitoffset 进行分页。使用 *Count 查询获取总数。
query {
  onetimeProducts(
    filter: { storeId: { eq: "STO_3bVzrkD0FJjFdZNLk8Ualx" } }
    limit: 10
    offset: 0
  ) {
    id
    name
  }
  onetimeProductsCount(
    filter: { storeId: { eq: "STO_3bVzrkD0FJjFdZNLk8Ualx" } }
  )
}
参数类型说明
limitinteger返回的最大结果数
offsetinteger跳过的结果数

环境相关字段

API Key 的环境影响返回的商品数据:
  • version — 返回指定环境的版本
  • status — 返回指定环境中的状态
一个商品可能在 test 环境中是 active,但在 production 环境中是 inactive(如果尚未发布)。

查询示例

门店与商品

查询门店、一次性商品、订阅商品和商品版本

订单与支付

查询订单、订阅订单、支付和退款工单

数据分析

收入统计、支付分析、趋势分析和客户洞察