Saltearse al contenido

Pago con tarjeta tokenizada

Útil cuando querés cobrar al mismo cliente varias veces sin pedirle la tarjeta en cada compra. Ej. suscripciones, recompra rápida, una sola compra dividida en cuotas internas.

El flow tiene dos etapas: catastro (una vez por cliente, abre un iframe) y charge (cada cobro, server-to-server con el token guardado).

Diagrama del catastro

sequenceDiagram
    autonumber
    participant Cliente
    participant TuApp as Tu app
    participant Ingalca as INGALCA Pay
    participant Dinelco

    TuApp->>Ingalca: POST /v1/cards
{customer.customerId} Ingalca->>Dinelco: Crear sesión registry Dinelco-->>Ingalca: integrity_token + session_id Ingalca-->>TuApp: card_xxx + integrity_token + validate_url TuApp-->>Cliente: Embed iframe (validate_url) Cliente->>Dinelco: Tipear tarjeta + 3DS OTP Dinelco-->>Ingalca: Callback con paymentToken Ingalca->>Ingalca: Marcar card registered Ingalca->>TuApp: webhook card.registered (con token_id) TuApp-->>Cliente: "Tarjeta guardada"

Paso 1 — iniciar catastro

Ventana de terminal
curl -X POST https://api.pay.ingalca.com/v1/cards \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"provider": "dinelco",
"target_origin": [
"https://tu-checkout.com",
"https://app.tu-checkout.com"
],
"customer": {
"customerId": "user_42",
"name": "Juan",
"lastname": "Pérez",
"email": "juan@example.com",
"phone": "+595981234567"
}
}'

Respuesta:

{
"data": {
"card_id": "card_xyz789",
"status": "pending",
"registration": {
"integrity_token": "eyJhbGc...",
"session_id": 123456789,
"validate_url": "https://test-checkout.dinelco.com.py:50106/registry?token=eyJhbGc..."
}
}
}

Paso 2 — embeber el iframe

En tu frontend:

<iframe
src="<validate_url>"
width="100%"
height="600"
style="border: 0"
allow="payment"
></iframe>

El cliente tipea la tarjeta dentro del iframe (que sirve directamente desde Dinelco — vos nunca ves los datos sensibles). Al pasar 3DS, Dinelco le pega un callback a INGALCA Pay con el paymentToken.

Paso 3 — recibir webhook de catastro

{
"event_type": "card.registered",
"data": {
"card_id": "card_xyz789",
"customer_id": "user_42",
"status": "registered",
"provider": "dinelco",
"brand": "Visa",
"last_four": "1096",
"expires": "12/30"
}
}

Ya podés cobrar con esta card.

Diagrama del charge

sequenceDiagram
    autonumber
    participant TuApp as Tu app
    participant Ingalca as INGALCA Pay
    participant Dinelco

    TuApp->>Ingalca: POST /v1/cards/{card_id}/charge
{amount, reference} Ingalca->>Dinelco: POST api/v3/payment
(con tokenId) Dinelco-->>Ingalca: status + responseCode Ingalca-->>TuApp: payment confirmed o failed Ingalca->>TuApp: webhook payment.confirmed o payment.failed

Paso 4 — cobrar

Ventana de terminal
curl -X POST https://api.pay.ingalca.com/v1/cards/card_xyz789/charge \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"amount": 50000,
"reference": "SUSCRIPCION-MAY-2026"
}'

A diferencia del checkout, el cobro es sincrónico — la respuesta ya tiene el resultado:

{
"data": {
"id": "pay_def456",
"status": "confirmed",
"amount": 50000,
"provider_data": {
"operation_number": "0000123456",
"authorization_number": "ABC123"
}
}
}

Estados de la tarjeta

stateDiagram-v2
    [*] --> pending: POST /v1/cards
    pending --> registered: callback OK + 3DS pasado
    pending --> invalid: callback rechazado
    registered --> deleted: DELETE /v1/cards/{id}*
    invalid --> [*]
    deleted --> [*]

* Hoy DELETE devuelve 501 — Dinelco no expone endpoint de unregister. Si querés “borrar” una tarjeta, marcala como inactiva en tu app y dejá de usarla; INGALCA Pay no la va a cobrar si no se la pedís.

Notas

  • El paymentToken se guarda encriptado del lado nuestro y nunca se devuelve en respuestas. Vos solo manejás el card_id (card_xxx).
  • 3DS es obligatorio en el catastro de Dinelco — el cliente siempre pasa por el OTP.
  • El customerId que mandamos a Dinelco es nuestro public_id interno (cust_xxx), no el external_id que vos enviás. Esto evita colisiones cross-tenant en sandboxes compartidos.