Tarjetas
El objeto Card
{ "id": "card_xyz789abc012", "customer_id": "cust_qrs456tuv789", "provider": "dinelco", "status": "registered", "brand": "Visa", "last_four": "1096", "expires": "12/30", "registered_at": "2026-05-02T14:30:00+00:00"}Campos
| Campo | Tipo | Notas |
|---|---|---|
id | string | card_xxx. Inmutable. |
customer_id | string | public_id del customer asociado. |
provider | enum | dinelco. |
status | enum | pending | registered | invalid | deleted. |
brand | string? | Visa, Mastercard, etc. Disponible cuando registered. |
last_four | string? | Últimos 4 dígitos. Disponible cuando registered. |
expires | string? | MM/YY. Disponible cuando registered. |
El paymentToken se guarda encriptado del lado nuestro y nunca se devuelve en respuestas.
Endpoints
Iniciar catastro
POST /v1/cardsBody:
{ "provider": "dinelco", "customer_id": "user_42", "target_origin": [ "https://tu-checkout.com", "https://app.tu-checkout.com" ], "customer": { "name": "Juan", "lastname": "Pérez", "email": "juan@example.com", "phone": "+595981234567" }}| Campo | Requerido | Notas |
|---|---|---|
provider | sí | dinelco. |
customer_id | sí | Tu ID de cliente (external_id). La tarjeta queda asociada a este customer para cobros futuros. |
target_origin | sí (Dinelco) | Origen(es) del iframe (ver abajo). |
return_url | no (recomendado en mobile) | URL a la que redirige el proxy al terminar el 3DS, con ?status=X&card_id=Y. Acepta http/https o esquemas custom (fixapp://, com.fix.app://). Obligatorio si integrás desde una app móvil o PWA — ver guía mobile. Sin este campo, la comunicación de vuelta es por postMessage al parent del iframe. |
customer.name, customer.lastname, customer.email, customer.phone | sí la 1ª vez | Requeridos por Dinelco cuando el customer_id es nuevo (crea el cliente). En catastros posteriores del mismo customer_id son opcionales. Si faltan con un customer nuevo, Dinelco responde PROVIDER_ERROR. |
target_origin puede ser string (un origen) o array. Es requerido para Dinelco porque el iframe usa postMessage para comunicarse con tu página. Tenés que listar todos los dominios y subdominios desde donde podrías embeber el iframe (no se aceptan wildcards). Los dominios del gateway los agregamos nosotros. Más detalle en crear pago.
Respuesta — 201 Created:
{ "data": { "card_id": "card_xyz789", "status": "pending", "registration": { "checkout_url": "https://api.pay.ingalca.com/v1/checkout-pages/eyJpdiI6...", "expires_at": "2026-05-02T15:00:00+00:00" } }}checkout_url es la URL que embebés como <iframe src> en tu frontend. Servimos el HTML del catastro desde nuestro dominio y proxeamos al proveedor por atrás — nunca ves a Dinelco. El paso a paso está en la guía de catastro.
Listar tarjetas
GET /v1/cards?customer_id=user_42Query params:
| Param | Notas |
|---|---|
customer_id | Filtrar por external_id o public_id. |
status | Filtrar por estado. |
cursor, per_page | Paginación. |
Obtener una tarjeta
GET /v1/cards/{id}Cobrar con la tarjeta
POST /v1/cards/{id}/chargeBody:
{ "amount": 50000, "currency": "PYG", "reference": "ORDEN-12345", "metadata": { "order_id": 12345 }}reference es la clave de idempotencia — ver idempotencia. Un reenvío con la misma reference te devuelve el mismo pago (200) sin volver a cobrar.
Respuesta — 201 Created (o 200 si fue un replay idempotente). A diferencia del checkout, el cobro es sincrónico — la respuesta ya tiene el resultado:
{ "data": { "id": "pay_def456", "status": "confirmed", "amount": 50000, "currency": "PYG", "reference": "ORDEN-12345", "rejection_reason": null }}Si el cobro fue rechazado, status será failed y rejection_reason traerá el motivo. El objeto es el mismo Payment que en el resto de la API (no incluye provider_data en el cobro tokenizado).
Eliminar una tarjeta
DELETE /v1/cards/{id}Responde 204 No Content. Hace un borrado lógico: la tarjeta pasa a estado deleted, deja de aparecer en el listado y ya no se puede cobrar con ella. Si tenés webhooks configurados, emitimos card.deleted. Borrar una tarjeta ya deleted es idempotente (también 204, sin reemitir el webhook).