API-integrasjon
En praktisk veiledning med eksempler du kan kopiere, for integrasjon med Gibbonds GraphQL-API — fra et administrasjonssystem, en mobil- eller nettapp eller en annen salgskanal. Se API-referansen for hele skjemaet.
På denne siden
Pro-abonnement. Opprett en API-nøkkel på siden API-nøkler i Gibbond-administrasjonen, og lagre den i en miljøvariabel på serveren. Eksemplene nedenfor forutsetter at GIBBOND_API_KEY inneholder en WRITE-nøkkel.
Slik henger delene sammen
Det finnes to typer påloggingsopplysninger, og det er viktig å velge riktig:
- API-nøkkel (
glk_live_…) — identifiserer din backend. Den kan lese og endre alle medlemmenes data og skal derfor bare finnes på serveren din. Bruk den til kommunikasjon mellom servere og til å utstede kundetokener. - Kundetoken — kortvarige påloggingsopplysninger begrenset til én kunde. Din backend utsteder tokenet med API-nøkkelen og sender det til en klient (nettleser eller app). Klienten kan bare se og utføre handlinger for denne kunden, så tokenet kan trygt sendes til enheten.
Velg integrasjonsmønster
| Du bygger… | Bruk | Gå til |
|---|---|---|
| En administrasjonsjobb, ERP-synkronisering eller headless-backend | API-nøkkelen direkte | Fra din backend |
| En mobilapp eller enkeltsideapp som viser et medlem poengene deres | API-nøkkel på serveren → kundetoken på enheten | I en app |
| Et kassasystem, en markedsplass eller en headless-kasse der kunder skal tjene poeng | API-nøkkel, awardPointsForOrder | Fra en annen kanal |
En hjelpefunksjon for forespørsler
Alle kall har samme format, så samle dem i en hjelpefunksjon. Dette Node-eksemplet bruker innebygd 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 — fra din backend (server til server)
Med en WRITE-nøkkel kan du utføre handlinger for alle medlemmer i butikken din. Meld inn en kunde, les kundens data og tildel poeng:
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,
); Et negativt beløp i awardPoints og kall til clawbackPoints krever en ADMIN-nøkkel — bruk separate, nøye beskyttede påloggingsopplysninger til disse forløpene.
Mønster 2 — i en mobil- eller nettapp
Legg aldri API-nøkkelen i en app. Opprett i stedet et lite endepunkt på din egen server som utsteder et kundetoken for den innloggede brukeren, og la appen kommunisere direkte med Gibbond med tokenet.
Hvor kommer kundens GID fra?
Et kundetoken bindes til GID-en du sender til mintCustomerToken — du er derfor ansvarlig for å utstede det til riktig kunde. Gibbond autentiserer din backend via API-nøkkelen, men autentiserer ikke sluttkunden. Før tokenet utstedes, må serveren din allerede vite og kunne stole på hvilken Shopify-kunde som er innlogget. Det kan fastslås på tre måter, i prioritert rekkefølge:
| Slik logger appen kunden inn | Hvor GID-en kommer fra |
|---|---|
| Shopify Customer Account API (anbefalt) | Logg kunden inn med Shopifys OAuth-baserte Customer Account API. Din backend bruker tokenet til å hente den verifiserte kunden og lese GID-en. Identiteten er signert av Shopify gjennom hele kjeden. |
| Et grensesnitt innebygd i Shopify | Hvis opplevelsen kjører i Shopify (en appinnbygging i temaet eller en UI-utvidelse for kundekontoer), leverer Shopify allerede den signerte identiteten — app-proxyens logged_in_customer_id eller feltet sub i et økttoken for kundekontoen. Les verdien på serveren og bruk denne GID-en. |
| Din egen innlogging | En kanal med egne kontoer (en tilpasset app eller et kassasystem) kobler brukeren til en Shopify-kundes GID via en kobling du lagret da kunden ble opprettet. Du går god for koblingen, så beskytt denne tilgangsveien nøye. |
Anbefalt: Customer Account API. For en headless-butikk eller mobilapp autentiserer du kunder med Shopifys Customer Account API og henter GID-en fra Shopifys verifiserte token. Da er hele kjeden — kunde → Shopify-verifisert identitet → din backend → utstedt kundetoken — pålitelig fra starten, uten en GID-kobling du må beskytte selv. Denne kontrollen hører hjemme i mellomvaren requireAuth nedenfor.
Hvis grensesnittet ditt allerede kjører innenfor Shopifys økt (en tema-, kasse- eller kundekontoblokk), trenger du vanligvis ikke dette API-et — butikkens appblokker og integrasjonen for kundekontoer verifiserer Shopify-identiteten for deg. Bruk kundetokener når du arbeider utenfor denne sammenhengen.
På serveren din
Din egen autentisering forteller deg hvilken Shopify-kunde som er innlogget (kundens GID). Utsted et token til 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
Hent et token fra serveren din og kall deretter Gibbond direkte. Spørringen me viser til kunden som tokenet tilhører — ingen id er nødvendig:
// 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 inn belønninger fra appen
Et kundetoken kan løse inn en belønning for sin egen kunde — ingen forhandlernøkkel trengs på enheten. Mutasjonen returnerer en engangsrabattkode som kan brukes i kassen:
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); Tokener er som standard gyldige i 15 minutter (sett ttlSeconds til opptil 24 timer). Hvis et kall returnerer UNAUTHENTICATED, kall /loyalty/session igjen for et nytt token og prøv på nytt.
Mønster 3 — tjen poeng fra en annen salgskanal
Når en bestilling skjer utenfor Shopify-kassen din — i et kassasystem, på en markedsplass eller i en headless-butikk — rapporterer du den med awardPointsForOrder. Gibbond bruker medlemmets nivåmultiplikator, aktive Boosts og milepæler akkurat som for en Shopify-bestilling. Kallet er idempotent for orderId, så nye forsøk er trygge:
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,
); Hver ordrelinje har et valgfritt productId, valgfrie collectionIds og et obligatorisk lineTotal — produkt- og samlingsspesifikke Boosts og unntak fungerer derfor som for Shopify-bestillinger. For å bekrefte poeng senere (f.eks. etter ordreoppfyllelse), kall confirmPoints(customerId, orderId); for å trekke dem tilbake ved en refusjon, kall clawbackPoints med en ADMIN-nøkkel.
Feil, nye forsøk og idempotens
- Koder. Feil returneres i en GraphQL-liste med navnet
errors; leserrors[0].extensions.code—UNAUTHENTICATED(401),FORBIDDEN(403, feil tilgangsomfang),RATE_LIMITED(429),BAD_USER_INPUT(400),NOT_FOUND(404). - Forespørselsgrenser. 600 forespørsler per minutt per påloggingsopplysning. Ved
429, vent antallet sekunder angitt i headerenRetry-Afterog prøv deretter igjen. - Idempotens. Send en
idempotencyKeytilawardPointsog en stabilorderIdtilawardPointsForOrder. Samme nøkkel eller bestilling blir aldri brukt dobbelt — du kan derfor prøve igjen ved nettverksfeil. - Tokenutløp. Hvis et kundetoken gir
UNAUTHENTICATED, utsted et nytt og prøv igjen.
Sikkerhetssjekkliste
- Oppbevar API-nøkler bare som hemmeligheter på serveren — aldri i app-pakker, nettleserkode eller versjonskontroll.
- Bruk et kundetoken til alt som kjører på en enhet; aldri en API-nøkkel.
- Gi hver integrasjon det laveste nødvendige tilgangsomfanget (en
READ-nøkkel for kontrollpaneler,WRITEfor opptjening og innløsning,ADMINbare for refusjoner og korrigeringer). - Bytt ut nøkkelen i administrasjonen så snart den kan ha lekket — tilbakekallingen gjelder umiddelbart.
- Utsted kundetokener med kortest mulig praktisk
ttlSeconds.
Hele listen over typer, spørringer, mutasjoner og felt finner du i API-referansen.