Emitir una gift card
POST/giftcardsProbar
La llamada la hace tu navegador, contra el servidor que elijas arriba. Si la documentación no está servida desde el mismo origen que la API, el navegador puede bloquear la respuesta por CORS: en ese caso abre estas páginas desde la propia API (/docs) o usa el curl de arriba.
const url = 'http://localhost:3000/v1/giftcards';const options = { method: 'POST', headers: {'x-api-key': '<x-api-key>', 'Content-Type': 'application/json'}, body: '{"externalId":"cacao-order-88213","brandId":"farmatodo","amount":2000,"expiresInDays":90,"beneficiaryName":"example","giftSender":"example","giftMessage":"example","sticker":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url http://localhost:3000/v1/giftcards \ --header 'Content-Type: application/json' \ --header 'x-api-key: <x-api-key>' \ --data '{ "externalId": "cacao-order-88213", "brandId": "farmatodo", "amount": 2000, "expiresInDays": 90, "beneficiaryName": "example", "giftSender": "example", "giftMessage": "example", "sticker": "example" }'Scope giftcards:write. Se paga con tu saldo en USD al emitirla: valor más tu margen. Con una key sk_test_ es de pruebas: no se canjea ni se cobra. externalId es tu id de la orden y es la idempotencia real: la misma orden nunca se emite ni se cobra dos veces.
El url lleva, después de #k=, la clave para gastar la tarjeta: quien tiene el enlace tiene el saldo. Sólo sale en el 201; no lo guardamos. Si lo pierdes, pídelo con GET /giftcards/{id}?includeLink=1.
Authorizations
Sección titulada «Authorizations»Parameters
Sección titulada «Parameters»Header Parameters
Sección titulada «Header Parameters»Único por operación. El alcance es tu cuenta y el modo de la key: una sk_test_ y una sk_live_ no comparten keys. Dura 24 h. Reintentar con la misma key y payload devuelve la respuesta original, con el mismo código HTTP y la cabecera Idempotent-Replayed: true; con otro payload da 409 idempotency_key_reused. Los campos secretos (el url de una gift card, una apiKey nueva, un webhookSecret) sólo llegan en la primera respuesta: al repetir llegan en null.
Request Bodyrequired
Sección titulada «Request Bodyrequired»object
Tu id de la orden
Example
cacao-order-88213Example
farmatodoCentavos de USD (2000 = $20,00), dentro del mínimo y máximo de la tienda
Example
2000Responses
Sección titulada «Responses»Ese externalId ya se había emitido: es la misma tarjeta (replay: true), no se cobra otra vez y url viene en null.
object
object
object
Centavos de USD
object
Centavos de USD
Lo que queda por gastar
object
Centavos de USD
pendiente → activa → usada (saldo en cero) o expirada. fallida es una emisión que no salió: su dinero ya volvió a tu saldo.
Si quien la recibió ya abrió el regalo
Sólo si está fallida
object
Sólo en la primera respuesta 201. Lleva la clave de gasto después de #k=: trátalo como dinero. En una repetición con la misma Idempotency-Key llega null: pídelo con GET /v1/giftcards/{id}?includeLink=1.
Sólo en el 200: ese externalId ya se había emitido
Example
{ "giftcard": { "externalId": "cacao-order-88213", "mode": "test", "brandId": "farmatodo", "amount": { "asset": "USD", "amount": "2000" }, "fee": { "asset": "USD", "amount": "2000" }, "balance": { "asset": "USD", "amount": "2000" }, "status": "pendiente", "error": { "code": "giftcards_unavailable" } }}Headers
Sección titulada «Headers»true cuando la respuesta es la repetición guardada de una petición anterior con la misma Idempotency-Key. No viene en la primera.
Emitida, con el url
object
object
object
Centavos de USD
object
Centavos de USD
Lo que queda por gastar
object
Centavos de USD
pendiente → activa → usada (saldo en cero) o expirada. fallida es una emisión que no salió: su dinero ya volvió a tu saldo.
Si quien la recibió ya abrió el regalo
Sólo si está fallida
object
Sólo en la primera respuesta 201. Lleva la clave de gasto después de #k=: trátalo como dinero. En una repetición con la misma Idempotency-Key llega null: pídelo con GET /v1/giftcards/{id}?includeLink=1.
Sólo en el 200: ese externalId ya se había emitido
Example
{ "giftcard": { "externalId": "cacao-order-88213", "mode": "test", "brandId": "farmatodo", "amount": { "asset": "USD", "amount": "2000" }, "fee": { "asset": "USD", "amount": "2000" }, "balance": { "asset": "USD", "amount": "2000" }, "status": "pendiente", "error": { "code": "giftcards_unavailable" } }}Headers
Sección titulada «Headers»true cuando la respuesta es la repetición guardada de una petición anterior con la misma Idempotency-Key. No viene en la primera.
No hubo respuesta a tiempo: queda pendiente con el dinero retenido y se resuelve sola (llega giftcard.issued o giftcard.failed). No la repitas con otro externalId.
object
object
object
Centavos de USD
object
Centavos de USD
Lo que queda por gastar
object
Centavos de USD
pendiente → activa → usada (saldo en cero) o expirada. fallida es una emisión que no salió: su dinero ya volvió a tu saldo.
Si quien la recibió ya abrió el regalo
Sólo si está fallida
object
Sólo en la primera respuesta 201. Lleva la clave de gasto después de #k=: trátalo como dinero. En una repetición con la misma Idempotency-Key llega null: pídelo con GET /v1/giftcards/{id}?includeLink=1.
Sólo en el 200: ese externalId ya se había emitido
Example
{ "giftcard": { "externalId": "cacao-order-88213", "mode": "test", "brandId": "farmatodo", "amount": { "asset": "USD", "amount": "2000" }, "fee": { "asset": "USD", "amount": "2000" }, "balance": { "asset": "USD", "amount": "2000" }, "status": "pendiente", "error": { "code": "giftcards_unavailable" } }}Headers
Sección titulada «Headers»true cuando la respuesta es la repetición guardada de una petición anterior con la misma Idempotency-Key. No viene en la primera.
invalid_amount (fuera de 100 a 50000) o validation_failed
object
object
Contexto estructurado del error cuando lo hay: qué límite se superó y de cuánto, qué campo es inválido, cuánto saldo había. No aparece en errores internos.
object
Código ESTABLE. Programa contra esto.
Example
{ "error": { "type": "invalid_request_error", "code": "insufficient_balance", "request_id": "req_8a0312ba896772bc441134cd" }}giftcards_program_suspended
object
object
Contexto estructurado del error cuando lo hay: qué límite se superó y de cuánto, qué campo es inválido, cuánto saldo había. No aparece en errores internos.
object
Código ESTABLE. Programa contra esto.
Example
{ "error": { "type": "invalid_request_error", "code": "insufficient_balance", "request_id": "req_8a0312ba896772bc441134cd" }}giftcard_external_id_reused: ese externalId ya se usó con otra tienda u otro monto
object
object
Contexto estructurado del error cuando lo hay: qué límite se superó y de cuánto, qué campo es inválido, cuánto saldo había. No aparece en errores internos.
object
Código ESTABLE. Programa contra esto.
Example
{ "error": { "type": "invalid_request_error", "code": "insufficient_balance", "request_id": "req_8a0312ba896772bc441134cd" }}insufficient_tenant_funds (no te alcanza el saldo en USD; no se cobró nada) o giftcard_brand_not_allowed (meta.allowedBrands)
object
object
Contexto estructurado del error cuando lo hay: qué límite se superó y de cuánto, qué campo es inválido, cuánto saldo había. No aparece en errores internos.
object
Código ESTABLE. Programa contra esto.
Example
{ "error": { "type": "invalid_request_error", "code": "insufficient_balance", "request_id": "req_8a0312ba896772bc441134cd" }}giftcards_unavailable: no se cobró nada; reintenta con el MISMO externalId
object
object
Contexto estructurado del error cuando lo hay: qué límite se superó y de cuánto, qué campo es inválido, cuánto saldo había. No aparece en errores internos.
object
Código ESTABLE. Programa contra esto.
Example
{ "error": { "type": "invalid_request_error", "code": "insufficient_balance", "request_id": "req_8a0312ba896772bc441134cd" }}