Overview
The Waffo Pancake GraphQL API provides read-only access to all your data. Use it to query merchants, stores, products, orders, payments, and more.
Authentication: API Key
The GraphQL API supports queries only. All write operations (create, update, delete) use the REST action endpoints.
Making a Request
import { WaffoPancake } from "@waffo/pancake-ts";
const client = new WaffoPancake({
merchantId: process.env.WAFFO_MERCHANT_ID!,
privateKey: process.env.WAFFO_PRIVATE_KEY!,
});
// Typed GraphQL queries
interface StoresQuery {
stores: Array<{ id: string; name: string; status: string }>;
}
const result = await client.graphql.query<StoresQuery>({
query: `{ stores { id name status } }`,
});
// result.stores is fully typed
Request Body
| Field | Type | Required | Description |
|---|
query | string | Yes | GraphQL query string |
variables | object | No | Query variables |
Available Queries
Stores
query {
stores {
id
name
status
createdAt
updatedAt
}
}
One-Time Products
query($storeId: String!) {
onetimeProducts(filter: { storeId: { eq: $storeId } }) {
id
name
description
prices
status
version
media
createdAt
updatedAt
}
}
Subscription Products
query($storeId: String!) {
subscriptionProducts(filter: { storeId: { eq: $storeId } }) {
id
name
description
billingPeriod
prices
status
version
createdAt
updatedAt
}
}
Orders
query {
orders {
id
status
currency
amount
buyerEmail
createdAt
}
}
Payments
query($paymentId: String!) {
payments(filter: { id: { eq: $paymentId } }) {
id
orderId
amount
currency
status
createdAt
}
}
Refund Tickets
query {
refundTickets {
id
paymentId
status
requestedAmount
reason
createdAt
}
}
Merchants
query {
merchants {
id
email
status
createdAt
}
}
Filtering
GraphQL queries support filters using typed filter objects:
Filter Types
| Type | Operators | Example |
|---|
StringFilter | eq, ne, in, contains | { storeId: { eq: "uuid" } } |
DateTimeFilter | eq, gt, lt, gte, lte | { createdAt: { gte: "2026-01-01" } } |
IntFilter | eq, gt, lt, gte, lte | { amount: { gte: 1000 } } |
BooleanFilter | eq | { isActive: { eq: true } } |
Example with Filters
query {
onetimeProducts(
filter: {
storeId: { eq: "store-uuid" }
status: { eq: "active" }
}
) {
id
name
prices
status
}
}
Use limit and offset for pagination. Use *Count queries to get total counts.
query {
onetimeProducts(
filter: { storeId: { eq: "store-uuid" } }
limit: 10
offset: 0
) {
id
name
}
onetimeProductsCount(
filter: { storeId: { eq: "store-uuid" } }
)
}
| Parameter | Type | Description |
|---|
limit | integer | Maximum number of results to return |
offset | integer | Number of results to skip |
Environment-Specific Fields
The X-Environment header affects which product data is returned:
version — Returns the version for the specified environment
status — Returns the status in the specified environment
A product may be active in test but inactive in production if it hasn’t been published yet.
Example: Full Product Query with Variables
curl -X POST https://waffo-pancake-auth-service.vercel.app/v1/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY_TOKEN" \
-d '{
"query": "query GetProducts($storeId: String!) { onetimeProducts(filter: { storeId: { eq: $storeId } }, limit: 20) { id name prices status version createdAt } onetimeProductsCount(filter: { storeId: { eq: $storeId } }) }",
"variables": { "storeId": "your-store-uuid" }
}'
SDK Example
// Query with variables and nested relationships
const result = await client.graphql.query<{
store: {
id: string;
name: string;
onetimeProducts: Array<{ id: string; name: string; prices: any }>;
subscriptionProducts: Array<{ id: string; name: string; billingPeriod: string }>;
};
}>({
query: `query ($id: ID!) {
store(id: $id) {
id name
onetimeProducts { id name prices status }
subscriptionProducts { id name billingPeriod status }
}
}`,
variables: { id: "store-uuid" },
});