Subir deudas y recibir pagos

Crear customer

📘

Esta sección explica el proceso de creación de Customers a través de la API REST de Toku. También puedes verlo en la documentación de la API aquí.

El primer paso para habilitar los pagos para tus clientes es registrarlos. A continuación se explica la creación de Customers utilizando la API REST de Toku.

Qué es un Customer

Un Customer contiene la información de la persona, junto con sus medios de contacto. La creación de un Customer genera un id único de la forma cus_lq1wGjwgFyqQm4ACZx0QjE84qKm8fff, el cual se envía en la respuesta de la API. Este id debe ser guardado, ya que se utiliza luego para la creación de Invoices para ese Customer, y para identificar las acciones que lleve a cabo el Customer en el Portal de Pagos, explicados en secciones posteriores.

Crear un Customer - POST /customer

A traves de un request POST a la API se puede crear un Customer, para lo que existen los siguientes parámetros:

Nombre

Tipo

Descripción

Requerido

goverment_id

string

Identificador personal del Customer según su nacionalidad. Por ejemplo: para Chile RUT, para México CURP.

:radio-button: Si

mail

string

Correo que se utilizará para contactar al Customer.

:radio-button: Si

name

string

Nombre por el cual nos referimos al Customer en los mensajes.

:white-circle: No

phone_number

string

Número de teléfono del Customer para contactarlo por SMS y Whatsapp

:white-circle: No

pac_mandate_id

string

Identificador del mandato que se pondrá al inscribir el PAC asociado al customer.

:white-circle: No

default_agent

string

Correo del asistente que tendrá asignado por defecto responder al Customer en caso de que este responda algún mensaje.

:white-circle: No

send_mail

boolean

Flag que nos indica si quieres mandar automáticamente un correo al crear el customer. Se le enviará con la secuencia "Invitación inscripción medio de pago"

:white-circle: No

📘

External_id <> Goverment_id

En caso de no contar con el identificador nacional del cliente es posible utilizar el campo mail o un parámetro diferente que identifique de forma única al cliente, el que se denominará external_id. Este campo reemplace a la columna goverment_id requerida por default. Esta configuración debe realizarse por el equipo de Toku.

Formato del request y la respuesta que genera

El Body del request debe ser de la siguiente forma:

{
  "goverment_id": "18579878K",
  "mail": "[email protected]",
  "name": "Jon Snow",
  "phone_number": "+56987654321",
  "pac_mandate_id": "196579888",
  "default_agent": "[email protected]",
   "send_mail": true
}

La respuesta recibida es de la forma:

{
  "id": "cus_lq1wGjwgFyqQm4ACZx0QjE84qKm8fffa",
  "goverment_id": "18579878K",
  "mail": "[email protected]",
  "name": "Jon Snow",
  "phone_number": "+56987654321",
  "pac_mandate_id": "196579888",
  "default_agent": "[email protected]",
}

Recuerda que debes capturar el campo id incluido en esta respuesta ya que será el código al que se asociara la deuda y con el que podrás identificar los eventos que ocurran en Toku.

Asociar Invoices a Customers

📘

Esta sección explica el proceso de creación de Invoices a través de la API REST de Toku. También puedes verlo en la documentación de la API aquí.

Tras tener registrados los nuestros clientes en Toku como Customers y haber guardado sus ids, podemos cargar deudas asociados a ellos, a las que llamaremos Invoices . A continuación se explica la creación de Invoices utilizando la API REST de Toku.

Qué es un Invoice

Un Invoice contiene la información de una deuda. La creación de un Invoice requiere del id único del Customer para poder relacionarlo a sus datos de contacto, el cual tiene la forma cus_lq1wGjwgFyqQm4ACZx0QjE84qKm8fff. Este ID debe ser capturado al crear el Customer en Toku, explicado en el paso previo de esta guía.

Crear un Invoice - POST /invoices

Al momento de crear un Invoice a traves de una request POST a la API en Toku existen campos obligatorios, campos opcionales y adicionalmente existe un campo para asociar valores adicionales específicos a la deuda.

Parametros para crear Invoice

Nombre

Tipo

Descripción

Requerido

customer

string

ID del Customer entregado en su creación.

:radio-button: Si

product_id

string

Identificador interno del producto que genera el Invoice. Puede ser un número de contrato o de propuesta.

:radio-button: Si

due_date

date

Fecha de vencimiento del Invoice, en formato YYYY-MM-DD.

:white-circle: No

amount

float

Monto adeudado en la CLP por default. En caso de tratarse de otra moneda, esta debe estar definida en la webapp de Toku.

:white-circle: No

is_paid

boolean

Indica si el Invoice se encuentra pagado o no.

:white-circle: No

is_void

boolean

Indica si el Invoice se encuentra anulado o no. Los Invoices anulados se tratan como si hubiesen sido borrados.

:white-circle: No

link_payment

string

URL en el que se debe pagar el Invoice. Dejar en blanco en caso de usar el portal de pagos de Toku. Incluir solo en el case de que poseas tu propio procesador de pagos.

:white-circle: No

metadata

json

Valores adicionales específicos de cada deuda. Son tratados como valores de texto y que no pueden tener más de 256 caracteres cada uno. Debes agregarlos en la webapp de Toku antes de poder utilizarlos aquí.

:white-circle: No

❗️

Importante

link_payment es un campo opcional, el cual no debe enviarse en caso de utilizar el Portal de Pagos proporcionado por Toku. Solo debe enviarse en caso de utilizar un portal de pagos externo.

El Body del request debe ser de la siguiente forma:

{
  "customer": "cus_lq1wGjwgFyqQm4ACZx0QjE84qKm8fffa",
  "is_paid": false,
  "is_void": false,
  "amount": 1000,
  "product_id": "92792",
  "due_date": "2021-03-04",
  "link_payment": "https://portal.pagos.com/tu-empresa",
  "metadata": {
    "car_brand": "Toyota",
    "car_model": "Yaris"
  }
}

Como ves, el campo customer permite asociar este Invoice a los datos de contacto del Customer, y se usará para notificarte acciones tales como inscripciones o pagos realizados.

La respuesta recibida es de la forma:

{
  "customer": "cus_lq1wGjwgFyqQm4ACZx0QjE84qKm8fffa",
  "is_paid": false,
  "is_void": false,
  "amount": 1000,
  "product_id": "92792",
  "due_date": "2021-03-04",
  "link_payment": "https://portal.pagos.com/tu-empresa",
  "metadata": {
    "car_brand": "Toyota",
    "car_model": "Yaris"
  },
  "id": "in_5tswGjwgAxrQm4ACZx0QjE84qKm8fgsw"
}

El campo id identifica al Invoice creado, y es de la forma in_5tswGjwgAxrQm4ACZx0QjE84qKm8fgsw. Puede ser utilizado para consultar el estado de un Invoice en Toku o para anular el mismo en caso de que ya no deba ser cobrado.

Escuchar via Webhook

Inscripción de Webhook Endpoints

A continuación, te explicamos cómo inscribir un Webhook Endpoint a través de una request POST a la API.

POST /webhook_endpoints

Parámetros para crear Webhook Endpoint

Nombre

Tipo

Descripción

Necesario

enabled_events

list

Lista de eventos a la que se suscribe este Webhook Endpoint.

:radio-button: Si

url

string

URL de tu endpoint, al cual se le notificarán los eventos mediante requests POST.

:radio-button: Si

status

string

Estado del Webhook Endpoint. Si es enabled, enviará notificaciones de los eventos suscritos. En caso contrario definir como disabled.

:white-circle: No

Luego de inscrito, puedes hacer una request PUT /webhook_endpoints/{id} para hacer las siguientes modificaciones:

  • Editar la lista de eventos, enviando el parámetro enabled_events
  • Deshabilitar el endpoint para no seguir recibiendo eventos, enviando el parametro statuscomo disabled

🚧

Importante

Luego de cada creación de Webhook Endpoints, se deben almacenar los campos id y secret, los cuales son utilizados para las verificaciones de seguridad explicadas en la siguiente sección.

Recibir Eventos en Webhook Endpoints

Una vez inscrito un Webhook Endpoint, Toku notificará los eventos suscritos. Lo hará a través de una request POST a la URL suscrita. Debes tener habilitado este endpoint para poder recibir y almacenar la información que se le envíe. A continuación, listamos los parámetros con los que Toku enviará las requests POST a tus Webhook Endpoints.

Parámetros enviados en un evento a un Webhook Endpoint

Nombre

Tipo

Descripción

Requerido

id

'int`

ID del evento.

:radio-button: Si

event_type

string

Tipo de evento.

:radio-button: Si

  • object

json

Valores adicionales específicos de cada evento.

:radio-button: Si

Toku-Signature

string

Firma para verificar validez del evento.

:radio-button: Si

❗️

Importante

El parámetro Toku-Signature se incluye en el Header de la request POST, a diferencia del resto de los parámetros incluidos en el Body. Este puede ser utilizado para comprobar que la notificación proviene de Toku y no de un tercero. Es de la forma t=1618960495,s=c896f1eb1438c706f4eb8b59d5453582b44a4cb442fd23ed9eb2690e1f9213b7, y su construcción se explica en la siguiente sección.

🚧

Atención

  • El nombre del parámetro object cambiará dependiendo del event_type. Corresponderá a la primera mitad del nombre del evento. Para el evento payment_method.attached , object será payment_method, y para los eventos payment_intent.succeeded y payment_intent.payment_failed, object será payment_intent. Esto quedará más claro en los ejemplos que se exponen a continuación.

Verificar que los eventos sean enviados por Toku

Toku firma cada evento enviado a tus Webhook Endpoints con el campo Toku-Signature en el header del request POST al momento de notificar un evento. Esta es una firma que te permite verificar que es Toku y no un tercero quien envía la notificación.

Para verificar la firma, es necesario que poseas el secret relacionado al Webhook Endpoint, el cual se retorna al momento de su creación.

El header Toku-Signature contiene un timestamp y una firma, separados por una coma ,. El timestamp viene precedido de t=, y la firma viene precedida de s=. Un ejemplo de firma es:

't=1618960495,s=c896f1eb1438c706f4eb8b59d5453582b44a4cb442fd23ed9eb2690e1f9213b7'

Las firmas enviadas por Toku son códigos HMAC, generados al firmar el id del request con la función de hash SHA-256, en el momento indicado por el timestamp. Se utiliza como key de la función de hash el secret del Webhook Endpoint.

A continuación, explicamos los pasos a llevar a cabo para validar la firma del evento. Utilizamos como ejemplo el siguiente evento:

{
    "id": "evt_MOnNVXKNYDCZXzI9slA3smhASQmuRleM",
    "event_type": "payment_method.attached",
    "payment_method": {
        "id": "pm_9tN0ZtjUDjS1qi8qZQ3uJHJbwtcXYH9d",
        "customer": "cus_lq1wGjwgFyqQm4ACZx0QjE84qKm8fffa",
        "gateway": "transbank_oneclick",
        "card_type": "Visa",
        "card_number": "XXXXXXXXXXXX6623",
        "status": "chargeable"
    }
}

Los ejemplos de código utilizan el lenguaje Python.

Extraer el timestamp y la firma desde el header.

Separa el valor del header en una lista utilizando el carácter , como separador. Luego, separa cada elemento de la lista utilizando el separador = para obtener un par prefijo-valor. Finalmente, obtén los valores correspondientes de cada prefijo.

header_value = request.headers.get('Toku-Signature')
timestamp, event_signature = [x.split('=')[1] for x in header_value.split(',')]

Construir el mensaje que se firmará

El mensaje a firmar se compone al concatenar el valor del timestamp, el carácter . y el campo id, el cual se encuentra en el body del request.

message = '{}.{}'.format(timestamp, event_id)

En el caso del ejemplo, el mensaje sería:

'1618960495.evt_MOnNVXKNYDCZXzI9slA3smhASQmuRleM'

Generar tu firma

Firma el mensaje utilizando la función SHA-256 y el secret de tu Webhook Endpoint como llave.

import hmac
from hashlib import sha256

encoded_secret = YOUR_WEBHOOK_ENDPOINT_SECRET.encode('utf-8')
encoded_message = message.encode('utf-8')
hmac_object = hmac.new(encoded_secret, msg=encoded_message, digestmod=sha256)
signature = hmac_object.hexdigest()

Comparar las firmas

Finalmente, compara la firma 'Toku-Signature' presente en el header con la obtenida al firmar el evento. Si ambas firmas coinciden, entonces el evento ha sido enviado por Toku.

import hmac

valid_signature = hmac.compare_digest(signature, event_signature)

Previene un ataque de reinyección

Para evitar un ataque de reproducción de mensajes, recomendamos que utilices una marca de tiempo. Al recibir y obtener el timestamp de un evento, verifica que este se encuentre dentro de tu rango de tolerancia. De no ser así, puedes descartar el evento.

{
  "enabled_events": [
    "payment_method.attached",
        "payment_intent.succeeded"
  ],
  "status": "enabled",
  "url": "https://prueba.com"
}

La respuesta recibida es de la forma:

{
  "enabled_events": [
    "payment_method.attached",
        "payment_intent.succeeded"
  ],
  "status": "enabled",
  "url": "https://prueba.com",
    "id": "whe_oJJDbbiXBgwOEzpIBzJMWAids_5xgmHS",
    "secret": "whesec_DTouU4ek2-tMhBO9sBUZNVC8tIIJuZsn"
}

Opcional: Verificar pagos diariamente

Por distintas razones algún servidor se puede caer y no queda registrado el webhook. Para asegurarse, como sistema de protección para detectar pagos se recomienda hacer una consulta diaria de los pagos realizados.

Aquí en API Reference. Esto requiere 4 campos en el body:

  • page -> Cantidad de páginas, se recomienda que sea 1 por simplicidad del archivo.
  • page_size -> Cantidad de pagos que van a venir por página. Se recomienda que sea un número suficientemente alto para que siempre puedan aparecer todos los pagos del día.
  • start_date -> Día anterior al hacer este request
  • end_date -> Día anterior al hacer este request (debe ser el mismo día que start para consultar por solo un día)

Esta request entrega una lista de pagos que se deben chequear con los webhooks recibidos durante el día.