Saltar a contenido

Guía de integración de webhooks

Gift Card Hero envía solicitudes HTTP POST a tu servidor cuando ocurren eventos concretos de tarjetas de regalo. Usa los webhooks para mantener sincronizados los sistemas externos con la actividad de las tarjetas de regalo en tiempo real.


Configuración

  1. Ve a For developers en la navegación de la izquierda
  2. Marca Enable REST API y guarda. La configuración de webhooks solo aparece mientras la REST API está activada
  3. Haz clic en Generate Secret para crear el secreto de firma de webhooks

Generación del secreto de webhook

El secreto solo se muestra una vez

Copia el secreto y guárdalo de forma segura. Si lo pierdes, haz clic en Regenerate Secret para crear uno nuevo. El secreto anterior deja de funcionar de inmediato, así que actualiza también tu servidor.

  1. Introduce las URL de tus endpoints para cada tipo de webhook que quieras recibir y haz clic en Save en la barra de guardado

URL de los endpoints de webhook

Una URL de endpoint nueva o modificada debe empezar por https:// y apuntar a un servidor accesible desde internet. Las direcciones de una red privada (localhost, 127.0.0.1, 10.x.x.x, 192.168.x.x y similares) se rechazan al guardar. Una URL guardada antes de esta regla seguirá funcionando hasta que la cambies, pero solo se llamará si apunta a una dirección pública. Para probar con un servidor local, exponlo mediante un túnel como ngrok y usa la URL https pública que te dé.


Tipos de evento

Gift Card Hero tiene tres campos de URL de webhook:

Evento Valor del encabezado de tópico Cuándo se envía
Gift card order gift_card_order Gift Card Hero procesa las tarjetas de regalo de un pedido. El payload lista las tarjetas que pertenecen al pedido
Gift card payment gift_card_payment Se crea un pedido pagado total o parcialmente con una tarjeta de regalo
Gift card balance change gift_card_balance Por ahora no se envía

Webhook de cambio de saldo

El campo Gift card balance webhook URL aparece en la página, pero Gift Card Hero todavía no envía este evento. Para seguir los cambios de saldo hoy, consulta GET /gift-cards/transactions de forma periódica o usa el evento gift_card_payment para los pagos.

Los webhooks solo se envían mientras Enable REST API esté activado y la URL de ese evento esté rellenada.


Entrega

  • Método: POST
  • Tiempo de espera: 6 segundos
  • Intentos: hasta 5 intentos de entrega en total (el primero y hasta 4 reintentos), con retrasos crecientes exponencialmente que empiezan en unos 30 a 60 segundos
  • Redirecciones: no se siguen. Una respuesta 3xx cuenta como entrega fallida, así que usa la URL final de tu endpoint.

Si tu endpoint no devuelve una respuesta 2xx en 6 segundos, la entrega se considera fallida y se reintentará.


Encabezados

Cada solicitud de webhook incluye los siguientes encabezados:

Encabezado Valor
Content-Type application/json
User-Agent GiftHero-Webhooks/1.0
X-GiftHero-Topic El tipo de evento (por ejemplo, gift_card_order)
X-GiftHero-Signature Firma HMAC-SHA256 para la verificación. Solo se envía cuando has generado un secreto de webhook

Verificación de firma

El encabezado X-GiftHero-Signature contiene una firma HMAC-SHA256, codificada en hexadecimal y con el prefijo sha256=.

Importante: la firma se calcula sobre un objeto JSON que contiene solo { type, timestamp } del cuerpo del payload, NO sobre el cuerpo completo de la solicitud.

Pasos de verificación

  1. Analiza el cuerpo de la solicitud y extrae los campos type y timestamp
  2. Construye el payload de firma: JSON.stringify({ type, timestamp })
  3. Calcula el HMAC-SHA256 usando tu secreto de webhook como clave
  4. Codifica el resultado en hexadecimal y añade el prefijo sha256=
  5. Compara con el encabezado X-GiftHero-Signature usando una comparación de tiempo constante

Ejemplo (Node.js)

const crypto = require('crypto');

function verifyWebhook(body, signature, secret) {
  const signingPayload = JSON.stringify({
    type: body.type,
    timestamp: body.timestamp
  });

  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(signingPayload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Esquemas del payload

Todos los cuerpos de solicitud tienen el mismo envoltorio. Los detalles del evento están dentro de data:

{
  "type": "gift_card_order",
  "timestamp": "2026-03-15T10:30:00.000Z",
  "data": { }
}

Gift card order (gift_card_order)

{
  "type": "gift_card_order",
  "timestamp": "2026-03-15T10:30:00.000Z",
  "data": {
    "order": {
      "id": 5551234567890,
      "name": "#1042",
      "email": "buyer@example.com",
      "createdAt": "2026-03-15T10:30:00.000Z",
      "lineItems": [
        {
          "id": 11198765432100,
          "title": "Gift Card",
          "quantity": 1,
          "sku": "GC-50",
          "variantId": 44556677
        }
      ]
    },
    "giftCards": [
      {
        "id": 987654321,
        "balance": "50.00",
        "currency": "USD",
        "lastCharacters": "ab12",
        "initialValue": "50.00",
        "customer": { "id": 123, "email": "buyer@example.com", "name": "Alex Buyer" },
        "recipient": { "id": 456, "email": "friend@example.com", "name": "Sam Friend" },
        "code": "abcd1234efgh5678",
        "lineItemId": 11198765432100,
        "sku": "GC-50"
      }
    ]
  }
}

Gift card payment (gift_card_payment)

Cada entrada de giftCards también incluye la transaction que pagó el pedido.

{
  "type": "gift_card_payment",
  "timestamp": "2026-03-16T14:22:00.000Z",
  "data": {
    "order": {
      "id": 5551234567891,
      "name": "#1043",
      "email": "shopper@example.com",
      "createdAt": "2026-03-16T14:22:00.000Z",
      "lineItems": [
        { "id": 11198765432200, "title": "Running Shoes", "quantity": 1, "sku": "SHOE-9" }
      ]
    },
    "giftCards": [
      {
        "id": 987654321,
        "balance": "0.00",
        "currency": "USD",
        "lastCharacters": "ab12",
        "initialValue": "50.00",
        "customer": null,
        "recipient": null,
        "transaction": {
          "id": "gid://shopify/OrderTransaction/123456789",
          "amount": "50.00",
          "currency": "USD",
          "type": "debit",
          "createdAt": "2026-03-16T14:22:00.000Z"
        }
      }
    ]
  }
}

Notas sobre los campos

  • data.order y data.giftCards son los campos en los que debes basarte. data también repite algunos campos del pedido en su nivel superior (orderId, orderName, orderEmail, createdAt, lineItems) y contiene campos internos (storeId, shop, jobType). No dependas de ellos.
  • balance es el saldo de la tarjeta en el momento en que se construye el webhook, no cuando se hizo el pedido.
  • code es el código completo de la tarjeta de regalo. Solo se incluye cuando Gift Card Hero tiene el código registrado, y se omite en caso contrario. Trátalo como una contraseña y asegúrate de que tu endpoint esté protegido.
  • lineItemId y sku se incluyen cuando la tarjeta se puede asociar a una línea del pedido.
  • Las entradas de lineItems contienen id, title, quantity, sku y variantId (sin precio).
  • Si no se pueden cargar los detalles de una tarjeta, su entrada se reduce a id, importes en cero y un lastCharacters vacío. Vuelve a leer la tarjeta con la REST API cuando veas esto.

Buenas prácticas

  • Responde 2xx rápido: confirma el webhook de inmediato y procesa el payload de forma asíncrona. Las respuestas que tarden más de 6 segundos se consideran fallidas.
  • Gestiona los duplicados: el mismo evento puede llegar más de una vez por los reintentos. Usa los IDs del pedido y de la tarjeta de regalo de los datos del evento para deduplicar. El timestamp es la hora de cada intento, así que no es una clave estable.
  • Verifica las firmas HMAC: verifica siempre el encabezado X-GiftHero-Signature antes de procesar cualquier payload de webhook. Rechaza las solicitudes con firmas no válidas.
  • Usa claves de idempotencia: diseña tu gestor de webhooks para que sea idempotente, de modo que procesar dos veces el mismo evento dé el mismo resultado.
  • Supervisa los fallos: si tu endpoint falla de forma constante, Gift Card Hero deja de reintentar tras 5 intentos en total. Revisa con regularidad los registros de tu servidor y el estado de tu endpoint.