Integración del POS con
Dos contratos de API y una guía paso a paso. Tu POS recibe órdenes por webhook firmado con HMAC, las confirma por REST y avanza el estado hasta la entrega.
Contratos API
Lenguajes soportados
Bits HMAC-SHA
Tres recursos, una integración
La integración con BipBip se compone de dos contratos de API complementarios y una guía paso a paso para unirlos.
Webhook Spec
BipBip envía cada orden nueva al POS vía POST /v1/order/{remoteId}. La firma HMAC se verifica y la respuesta es 200 OK.
REST API Reference
El POS llama a BipBip para aceptar, rechazar, avanzar el estado y consultar órdenes. La autenticación usa X-Bipbip-Api-Key y cada mutación incluye un Idempotency-Key.
Guía de integración
Quickstart paso a paso con código real en 4 lenguajes, verificación HMAC con samples probados, troubleshooting y glosario completo de términos del contrato.
Leer la guía →Diseñado para integraciones confiables
Firma HMAC-SHA256
Cada webhook se firma con HMAC-SHA256 sobre {timestamp}.{rawBody}. Los requests mayores a 5 minutos se rechazan para bloquear replays.
Entrega at-least-once
Cada intento lleva el mismo X-Bipbip-Delivery-Id. Ese UUID permite deduplicar y tolerar reintentos sin crear órdenes duplicadas.
Idempotency-Key obligatoria
Cada mutación REST incluye un UUID único por intento lógico. 24h de caché, reintentos seguros sin efectos dobles.
Samples en 4 lenguajes
Node.js, Python, C# y PHP. Todos usan solo librería estándar — sin dependencias externas. Listos para copy-paste.
Máquina de estados clara
pending → preparing (secuencia automática al aceptar) → ready → handed_over. rejected y cancelled son terminales. Sin ambigüedades.
Versionado en el path
Todo corre bajo /v1/. Cuando llegue v2 las dos versiones pueden correr en paralelo durante la migración — sin breaking changes sorpresivos.
Verificación HMAC en cada webhook
BipBip firma cada request con HMAC-SHA256 sobre {timestamp}.{rawBody}. El raw body se captura crudo, el timestamp se valida (máx. 300s / 5 min de skew) y la comparación se hace en tiempo constante.
- Solo librería estándar — sin dependencias externas
-
timingSafeEqual/compare_digest/hash_equals - El raw body se captura antes de
JSON.parse
// HMAC-SHA256 verification — Node.js (built-in crypto) const crypto = require('crypto'); function verifyBipBipSignature(secret, timestamp, rawBody, signature) { // Reject requests older than 5 minutes (replay protection) const now = Math.floor(Date.now() / 1000); if (Math.abs(now - parseInt(timestamp, 10)) > 300) return false; // Sign the RAW body — never JSON.parse + re-serialize const message = `${timestamp}.${rawBody}`; const computed = crypto .createHmac('sha256', secret) .update(message, 'utf8') .digest('hex'); const expected = `sha256=${computed}`; // Timing-safe comparison (never use === on signatures) const a = Buffer.from(expected, 'utf8'); const b = Buffer.from(signature, 'utf8'); if (a.length !== b.length) return false; return crypto.timingSafeEqual(a, b); }
# HMAC-SHA256 verification — Python (stdlib only) import hmac, hashlib, time def verify_bipbip_signature(secret: str, timestamp: str, raw_body: bytes, signature: str) -> bool: # Reject requests older than 5 minutes if abs(int(time.time()) - int(timestamp)) > 300: return False # Build the exact message BipBip signed: "{ts}.{rawBody}" message = f"{timestamp}.".encode("utf-8") + raw_body computed = hmac.new(secret.encode("utf-8"), message, hashlib.sha256).hexdigest() expected = f"sha256={computed}" # Timing-safe comparison return hmac.compare_digest(expected, signature)
// HMAC-SHA256 verification — C# (.NET 6+) using System.Security.Cryptography; using System.Text; public static bool VerifyBipBipSignature(string secret, string timestamp, byte[] rawBody, string signature) { // Reject requests older than 5 minutes var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); if (Math.Abs(now - long.Parse(timestamp)) > 300) return false; var prefix = Encoding.UTF8.GetBytes($"{timestamp}."); var message = prefix.Concat(rawBody).ToArray(); using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret)); var computed = Convert.ToHexString(hmac.ComputeHash(message)).ToLowerInvariant(); var expected = Encoding.UTF8.GetBytes($"sha256={computed}"); var received = Encoding.UTF8.GetBytes(signature); return CryptographicOperations.FixedTimeEquals(expected, received); }
// HMAC-SHA256 verification — PHP 7.2+ function verify_bipbip_signature(string $secret, string $timestamp, string $rawBody, string $signature): bool { // Reject requests older than 5 minutes if (abs(time() - (int)$timestamp) > 300) return false; // Sign the raw body — never re-serialize the parsed JSON $message = $timestamp . '.' . $rawBody; $computed = hash_hmac('sha256', $message, $secret); $expected = 'sha256=' . $computed; // Constant-time comparison to avoid timing oracles return hash_equals($expected, $signature); }
Los 4 pasos para estar en vivo
De "credenciales obtenidas" a "primera orden recibida y confirmada" sin intervención del equipo BipBip.
Implementar el webhook
Tu POS expone POST /v1/order/{remoteId}. Captura el raw body antes de parsear el JSON.
Verificar la firma HMAC
Recomputa HMAC-SHA256 sobre {timestamp}.{rawBody} y compara en tiempo constante.
Responder con remoteOrderId
La respuesta es HTTP 200 con { "remoteOrderId": "..." }. Sin ese campo BipBip reintenta.
Aceptar por REST API
POST /api/v1/Orders/{orderKey}/accept con X-Bipbip-Api-Key e Idempotency-Key.
Antes de arrancar
BipBip entrega estos elementos durante el onboarding
- HMAC Secret (una por cuenta)
- API Key (
X-Bipbip-Api-Key) - remoteId (uno por tienda)
- Base URL registrada (pública)
Todo listo para arrancar la integración
El equipo BipBip entrega credenciales y habilita el piloto en producción durante el onboarding.