API Bipop

Créez un ticket au moment où la commande est saisie en caisse, affichez son QR sur l'écran client ou le reçu, et sonnez le client d'un appel quand c'est prêt. Une API REST simple, en JSON.

https://heybipop.com/api/v1

Authentification

L'API est activée par Bipop pour votre établissement (formule Réseau). Le gérant crée ensuite ses clés dans Réglages › API et intégrations. Une clé n'est affichée qu'une fois : gardez-la dans votre serveur ou votre caisse, jamais dans une page web ou une application publique.

Chaque appel envoie la clé dans l'en-tête Authorization.

Authorization: Bearer bp_live_…

Tester une clé

Renvoie l'établissement auquel la clé appartient.

curl https://heybipop.com/api/v1/venue \
  -H "Authorization: Bearer bp_live_…"

Créer un ticket

label (facultatif) apparaît sur le comptoir, par exemple le numéro de commande de votre caisse. lang (fr, en ou ar) choisit la langue du ticket.

curl -X POST https://heybipop.com/api/v1/tickets \
  -H "Authorization: Bearer bp_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "label": "Commande 1042", "lang": "fr" }'
HTTP/1.1 201 Created

{
  "ticket": {
    "id": "6710f3c2a1b2c3d4e5f60718",
    "number": "A12",
    "code": "K7M2Q",
    "state": "PREPARING",
    "label": "Commande 1042",
    "url": "https://heybipop.com/t/Zx81…",
    "source": "api",
    "scanned": false,
    "notifications": false,
    "createdAt": "2026-10-18T12:04:31.000Z",
    "readyAt": null,
    "collectedAt": null,
    "cancelledAt": null,
    "rating": null
  }
}

Affichez ticket.url sous forme de QR code (écran client, reçu imprimé, ou envoyé par SMS). Le client le scanne et suit sa commande ; Bipop s'occupe des notifications.

Prévenir le client

Passer un ticket à READY fait sonner le téléphone du client, exactement comme le bouton « Prête » du comptoir. notified indique si au moins un appareil a reçu la notification.

curl -X PATCH https://heybipop.com/api/v1/tickets/6710f3c2a1b2c3d4e5f60718 \
  -H "Authorization: Bearer bp_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "state": "READY" }'

{ "ticket": { …, "state": "READY" }, "notified": true }
// Node.js 18+
const res = await fetch("https://heybipop.com/api/v1/tickets/" + id, {
  method: "PATCH",
  headers: { Authorization: `Bearer ${process.env.BIPOP_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({ state: "READY" }),
});
if (!res.ok) throw new Error((await res.json()).error);

Lister les tickets

Les tickets en cours. Ajoutez ?recent=1 pour inclure les 20 derniers tickets terminés.

curl "https://heybipop.com/api/v1/tickets?recent=1" \
  -H "Authorization: Bearer bp_live_…"

GET https://heybipop.com/api/v1/tickets/{id}

États d'un ticket

Un ticket naît PREPARING. Les transitions refusées renvoient 409.

PREPARINGEn préparation. Peut passer à READY ou CANCELLED.
READYPrête : le client est appelé. Peut passer à COLLECTED, revenir à PREPARING, ou CANCELLED.
COLLECTEDRécupérée. État final.
CANCELLEDAnnulée. État final ; un tampon fidélité éventuel est retiré.
EXPIREDAutomatique, 18 h après la création si le ticket est resté ouvert.

L'objet ticket

idIdentifiant à utiliser dans /api/v1/tickets/{id}.
numberNuméro affiché au client, par exemple A12.
codeCode court que le client peut taper au lieu de scanner.
statePREPARING, READY, COLLECTED, CANCELLED ou EXPIRED.
urlLien du ticket client, à afficher en QR code.
scannedLe client a ouvert son ticket.
notificationsLe client a activé les notifications.
createdAt, readyAt, collectedAt, cancelledAtHorodatages ISO 8601 (UTC), ou null.
ratingNote de 1 à 5 laissée par le client, ou null.

Erreurs

Les erreurs renvoient un code HTTP et un objet { error, message }.

HTTP/1.1 409 Conflict

{ "error": "invalid_transition", "message": "COLLECTED → READY" }
401 missing_api_key / invalid_api_keyClé absente, mal formée ou révoquée.
403 api_disabledL'API n'est pas activée pour cet établissement.
404 ticket_not_foundCe ticket n'existe pas pour cet établissement.
409 invalid_transitionChangement d'état impossible depuis l'état actuel.
429 rate_limitedPlus de 120 appels par minute avec la même clé.

Bonnes pratiques

120 appels par minute et par clé. Une clé par caisse ou par intégration : vous pourrez en révoquer une sans couper les autres.

Les appels PATCH sont idempotents : renvoyer READY sur un ticket déjà prêt ne sonne pas une deuxième fois.

Couper l'API depuis Bipop révoque toutes les clés de l'établissement.

Intégrations caisse (webhooks)

Le sens inverse : c'est la caisse qui appelle Bipop. Le gérant crée une connexion dans Réglages › API et intégrations et reçoit une URL privée à coller dans sa caisse. Pas de clé à gérer côté caisse : le secret est dans l'URL.

Chaque commande devient un ticket. Le même identifiant de commande ne crée jamais deux tickets, et un événement répété ne sonne pas deux fois : vos tentatives automatiques sont sans danger.

POST https://heybipop.com/api/integrations/generic/{token}
Content-Type: application/json

{
  "event": "order.created",
  "order": { "id": "1042", "number": "A12", "label": "Table 4" }
}
order.createdCrée le ticket (PREPARING).
order.readyPasse le ticket à READY et sonne le client. Crée le ticket s'il n'existait pas.
order.completedClôt un ticket prêt (COLLECTED).
order.cancelledAnnule le ticket.

Signature facultative : si un secret de signature est défini sur la connexion, envoyez X-Bipop-Signature: sha256=<HMAC SHA-256 hexadécimal du corps brut>. Sans signature valide, la réponse est 401. Une caisse qui ne peut pas écrire l'événement dans le corps peut l'ajouter à l'URL : ?event=order.ready.

// Node.js
import { createHmac } from "node:crypto";
const body = JSON.stringify({ event: "order.ready", order: { id: "1042" } });
await fetch(webhookUrl, {
  method: "POST",
  headers: {
    "content-type": "application/json",
    "x-bipop-signature": "sha256=" + createHmac("sha256", secret).update(body).digest("hex"),
  },
  body,
});

La réponse contient le ticket, au même format que l'API. Imprimez ticket.url en QR code sur le reçu : le client le scanne et attend tranquillement.

HTTP/1.1 200 OK

{ "ok": true, "handled": 1, "ticket": { "id": "…", "number": "A12", "state": "PREPARING", "url": "https://heybipop.com/t/…", … } }
Odoo PdV 17/18Natif, sans module : règles d'automatisation « Envoyer une notification webhook » sur pos.order (création) et sur l'écran de préparation (étape Prêt), avec ?event=created / ?event=ready dans l'URL.
LoyverseNatif : webhook receipts.update. Chaque vente crée un ticket, un reçu annulé l'annule. Signature X-Loyverse-Signature vérifiée avec le client secret de l'application OAuth.
CaisseManager, LaCaisse.ma, CapitaineSur demande auprès de l'éditeur, au format webhook Bipop ci-dessus.
Toute autre caisseSi elle sait appeler une URL, le format webhook Bipop suffit. Sinon, l'API REST par clé ci-dessus.

Éditeur de caisse ? Implémentez ce format une fois et tous vos clients restaurateurs peuvent activer Bipop en collant une URL. Écrivez-nous depuis la page contact pour être listé.