API-integration
En praktisk guide med exempel att kopiera för att integrera Gibbonds GraphQL-API — från ett backoffice-system, en mobil- eller webbapp eller en annan försäljningskanal. Hela schemat finns i API-referensen.
På den här sidan
Pro-planen. Skapa en API-nyckel på sidan API-nycklar i Gibbonds admin och förvara den i en miljövariabel på servern. Exemplen nedan förutsätter att GIBBOND_API_KEY innehåller en WRITE-nyckel.
Så hänger delarna ihop
Det finns två typer av autentiseringsuppgifter, och det är viktigt att välja rätt:
- API-nyckel (
glk_live_…) — identifierar din backend. Den kan läsa och ändra alla medlemmars uppgifter och får därför bara finnas på din server. Använd den för kommunikation mellan servrar och för att skapa kundtoken. - Kundtoken — en kortlivad autentiseringsuppgift begränsad till en kund. Din backend skapar den med API-nyckeln och skickar den till en klient (webbläsare eller app). Klienten kan bara se och utföra åtgärder för den kunden, så tokenen kan skickas säkert till enheten.
Välj integrationssätt
| Du bygger… | Använd | Gå till |
|---|---|---|
| Ett backoffice-jobb, en ERP-synkronisering eller en headless-backend | API-nyckeln direkt | Från din backend |
| En mobil- eller ensidesapp som visar en medlem deras poäng | API-nyckel på servern → kundtoken på enheten | I en app |
| Ett kassasystem, en marknadsplats eller en headless-kassa där kunder ska tjäna poäng | API-nyckel, awardPointsForOrder | Från en annan kanal |
En hjälpfunktion för anrop
Alla anrop har samma format, så samla dem i en hjälpfunktion. Det här Node-exemplet använder inbyggd fetch (Node 18+):
// gibbond.js
const ENDPOINT = "https://app.gibbond.com/api/v1/graphql";
export async function gibbond(query, variables, token) {
const res = await fetch(ENDPOINT, {
method: "POST",
headers: {
"Authorization": "Bearer " + token,
"Content-Type": "application/json",
},
body: JSON.stringify({ query, variables }),
});
if (res.status === 429) {
const retryAfter = Number(res.headers.get("Retry-After") || 1);
const err = new Error("Rate limited");
err.retryAfter = retryAfter;
throw err;
}
const json = await res.json();
if (json.errors && json.errors.length) {
const code = json.errors[0].extensions && json.errors[0].extensions.code;
throw new Error(code + ": " + json.errors[0].message);
}
return json.data;
} Mönster 1 — från din backend (server till server)
Med en WRITE-nyckel kan du utföra åtgärder för alla medlemmar i din butik. Registrera en kund, läs deras uppgifter och tilldela poäng:
import { gibbond } from "./gibbond.js";
const KEY = process.env.GIBBOND_API_KEY;
const id = "gid://shopify/Customer/123456789";
// Enroll a customer (idempotent — safe to call again).
await gibbond(
"mutation($id: ID!, $email: String) { enrollCustomer(customerId: $id, email: $email) { ok customer { enrolled } } }",
{ id, email: "ada@example.com" },
KEY,
);
// Read their balance and tier.
const { customer } = await gibbond(
"query($id: ID!) { customer(id: $id) { balance pending lifetime tier { name multiplier } } }",
{ id },
KEY,
);
// Grant points. idempotencyKey makes retries safe — the same key never double-applies.
await gibbond(
"mutation($id: ID!, $pts: Int!, $k: String) { awardPoints(customerId: $id, points: $pts, reason: \"Newsletter signup\", idempotencyKey: $k) { ok pointsApplied balance { balance } } }",
{ id, pts: 100, k: "newsletter-123456789" },
KEY,
); Ett negativt belopp för awardPoints och anrop till clawbackPoints kräver en ADMIN-nyckel — använd separata, noggrant skyddade autentiseringsuppgifter för dessa flöden.
Mönster 2 — i en mobil- eller webbapp
Lägg aldrig API-nyckeln i en app. Skapa i stället en liten slutpunkt på din egen server som skapar en kundtoken för den inloggade användaren. Låt sedan appen kommunicera direkt med Gibbond med tokenen.
Varifrån kommer kundens GID?
En kundtoken binds till det GID du skickar till mintCustomerToken — du ansvarar alltså för att skapa den för rätt kund. Gibbond autentiserar din backend via API-nyckeln, men autentiserar inte slutkunden. Innan tokenen skapas måste din server redan veta och kunna lita på vilken Shopify-kund som är inloggad. Det kan fastställas på tre sätt, i prioritetsordning:
| Så loggar appen in kunden | Varifrån GID hämtas |
|---|---|
| Shopify Customer Account API (rekommenderas) | Logga in kunden med Shopifys OAuth-baserade Customer Account API. Din backend använder den resulterande tokenen för att hämta den verifierade kunden och läsa deras GID. Identiteten är signerad av Shopify genom hela kedjan. |
| Ett gränssnitt inbyggt i Shopify | Om upplevelsen körs i Shopify (en appinbäddning i temat eller ett tillägg för kundkontot) tillhandahåller Shopify redan den signerade identiteten — app-proxyns logged_in_customer_id eller fältet sub i kundkontots sessionstoken. Läs värdet på servern och använd detta GID. |
| Din egen inloggning | En kanal med egna konton (en anpassad app eller ett kassasystem) kopplar användaren till ett Shopify-kund-GID med en mappning som du sparade när kunden skapades. Du ansvarar för kopplingen, så skydda den här vägen noggrant. |
Rekommenderat: Customer Account API. För en headless-butik eller mobilapp autentiserar du kunder med Shopifys Customer Account API och hämtar GID från Shopifys verifierade token. Då är hela kedjan — kund → Shopify-verifierad identitet → din backend → skapad kundtoken — tillförlitlig från början, utan någon GID-mappning att skydda. Kontrollera detta i mellanprogramvaran requireAuth nedan.
Om ditt gränssnitt redan körs inom Shopifys session (ett tema-, kassa- eller kundkontoblock) behöver du vanligtvis inte detta API — butikens appblock och integrationen för kundkonton verifierar Shopify-identiteten åt dig. Använd kundtoken när du arbetar utanför det sammanhanget.
På din server
Din egen autentisering anger vilken Shopify-kund som är inloggad (deras GID). Skapa en token för kunden:
import express from "express";
import { gibbond } from "./gibbond.js";
const app = express();
// requireAuth is YOUR session middleware; it sets req.customerGid.
app.post("/loyalty/session", requireAuth, async (req, res) => {
const data = await gibbond(
"mutation($id: ID!) { mintCustomerToken(customerId: $id, ttlSeconds: 900) { token expiresAt } }",
{ id: req.customerGid },
process.env.GIBBOND_API_KEY, // WRITE key, server-side only
);
// Hand the app the token, when it expires, and the id it is bound to.
res.json({
token: data.mintCustomerToken.token,
expiresAt: data.mintCustomerToken.expiresAt,
customerId: req.customerGid,
});
}); I appen
Hämta en token från din server och anropa sedan Gibbond direkt. Frågan me avser kunden som tokenen tillhör — inget id behövs:
// 1. Get a short-lived token from YOUR backend.
const session = await fetch("/loyalty/session", { method: "POST" }).then(r => r.json());
// 2. Call Gibbond with the customer token.
async function loyalty(query, variables) {
const res = await fetch("https://app.gibbond.com/api/v1/graphql", {
method: "POST",
headers: {
"Authorization": "Bearer " + session.token,
"Content-Type": "application/json",
},
body: JSON.stringify({ query, variables }),
});
return (await res.json()).data;
}
// Show the member their points, tier, and reward codes.
const { me } = await loyalty("{ me { name balance lifetime tier { name multiplier } } }");
const { activeCodes } = await loyalty(
"query($id: ID!) { activeCodes(customerId: $id) { code rewardName status expiresAt } }",
{ id: session.customerId },
);
renderRewardsScreen(me, activeCodes); Lös in belöningar i appen
En kundtoken kan lösa in en belöning för sin egen kund — ingen handlar-nyckel behövs på enheten. Mutationen returnerar en engångsrabattkod som kan användas i kassan:
const { redeemReward } = await loyalty(
"mutation($id: ID!, $reward: ID!) { redeemReward(customerId: $id, rewardId: $reward) { ok code { code rewardName pointsSpent expiresAt } } }",
{ id: session.customerId, reward: "gid_or_reward_id_from_rewards_query" },
);
if (redeemReward.ok) applyDiscountCode(redeemReward.code.code); Token är giltiga i 15 minuter som standard (ställ in ttlSeconds upp till 24 timmar). Om ett anrop returnerar UNAUTHENTICATED, anropa /loyalty/session igen för en ny token och försök på nytt.
Mönster 3 — tjäna poäng från en annan försäljningskanal
När en beställning sker utanför din Shopify-kassa — i ett kassasystem, på en marknadsplats eller i en headless-butik — rapporterar du den med awardPointsForOrder. Gibbond tillämpar medlemmens nivåmultiplikator, aktiva Boosts och milstolpar precis som för en Shopify-beställning. Anropet är idempotent för orderId, så omförsök är säkra:
await gibbond(
`mutation($input: OrderInput!) {
awardPointsForOrder(input: $input) {
ok
pointsApplied
balance { balance lifetime }
}
}`,
{
input: {
orderId: "pos-2026-000123",
customerId: "gid://shopify/Customer/123456789",
customerEmail: "ada@example.com",
orderName: "POS #000123",
lineItems: [
{ productId: "gid://shopify/Product/55", collectionIds: ["gid://shopify/Collection/9"], lineTotal: 42.0 },
{ lineTotal: 8.5 },
],
},
},
process.env.GIBBOND_API_KEY,
); Varje orderrad har ett valfritt productId, valfria collectionIds och ett obligatoriskt lineTotal — produkt- och kollektionsspecifika Boosts och undantag fungerar därför som för Shopify-beställningar. För att bekräfta poäng senare (t.ex. efter att beställningen har distribuerats), anropa confirmPoints(customerId, orderId); för att återföra dem vid en återbetalning, anropa clawbackPoints med en ADMIN-nyckel.
Fel, omförsök och idempotens
- Koder. Fel returneras i en GraphQL-array med namnet
errors; läserrors[0].extensions.code—UNAUTHENTICATED(401),FORBIDDEN(403, fel behörighetsomfång),RATE_LIMITED(429),BAD_USER_INPUT(400),NOT_FOUND(404). - Anropsbegränsningar. 600 anrop per minut per autentiseringsuppgift. Vid
429, vänta det antal sekunder som anges iRetry-After-headern och försök sedan igen. - Idempotens. Skicka en
idempotencyKeytillawardPointsoch ett stabiltorderIdtillawardPointsForOrder. Samma nyckel eller beställning tillämpas aldrig dubbelt — du kan därför försöka igen vid nätverksfel. - Utgången token. Om en kundtoken ger
UNAUTHENTICATED, skapa en ny och försök igen.
Säkerhetschecklista
- Förvara API-nycklar enbart som hemligheter på servern — aldrig i app-paket, webbläsarkod eller versionshantering.
- Använd en kundtoken för allt som körs på en enhet; aldrig en API-nyckel.
- Ge varje integration lägsta nödvändiga behörighetsomfång (en
READ-nyckel för instrumentpaneler,WRITEför att tjäna och lösa in poäng,ADMINbara för återbetalningar och korrigeringar). - Byt ut nyckeln i admin så snart den kan ha läckt — återkallandet gäller omedelbart.
- Skapa kundtoken med kortast möjliga praktiska
ttlSeconds.
Hela listan över typer, frågor, mutationer och fält finns i API-referensen.