Guía para integración de Pagos cuenta a cuenta con Floid (Chile)

Pasos a seguir para la rápida integración de nuestra interfaz de pagos cuenta a cuenta

Esta documentación para desarrolladores proporciona toda la información necesaria para integrar el servicio de Payins en tus proyectos.


1. Requisitos

  • Solicita la creación de tu cuenta para acceder al Dashboard de Floid
  • Una clave API o Token de Floid habilitada con el servicio de payins. Para activar esto debes contactarte con el equipo comercial de Floid.
  • Entorno de Desarrollo: Configura tu entorno de desarrollo con las bibliotecas necesarias para realizar solicitudes HTTPs.
  • Solicita la creación de un Widget de pagos

2. Diagrama


3. Autorización de la API

La autenticación se realiza mediante un token de API. Este token debe ser incluido en los encabezados de todas las solicitudes.

Encabezados de Autenticación

Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json

4.Endpoint

Host Producción: https://api.floid.app`

Create Payin

URL: {{HOST}}/cl/payments/create

Postman Collection 🟠

Método: POST

Descripción: Crea un nuevo pago.

Body:

{
    "amount" : 1000,
    "consumer_id": 111111111,
    "webhook_url": "https://webhook.site/a23003ad-18ab-47f5-9777-56537f7756d8"
}

Obligatorios

ParámetroLargo del CampoDescripción del CampoEjemploValidaciónTipo
amountN/AMonto de la transacción o cantidad300Debe ser un número no negativofloat

Opcionales

ParámetroDescripción del CampoEjemploValidaciónTipo
consumer_idRUT del usuario sin puntos ni guiones. Si se indica, no se permitirá cambiar en el widget y por lo tanto el pago deberá ser realizado por una cuenta bancaria asociada a este RUT.111111111Debe ser un RUT válidostring
store_credentialsVariable para permitir el guardado o no de la credenciales.falseboolean
token_passwordString devuelto si se inició un pago con store_credentials: true.def50200c5cfd43dg4...string
sandboxPara crea un pago en ambiente de pruebafalseboolean
redirect_urlURL a la que se redirigirá al cliente cuando el proceso haya finalizado. Se agregará un parámetro 'status' donde status=2 indica éxito y status=3 indica error. - Éxito: https://redirect.floid.ai?status=2
- Error: https://redirect.floid.ai?status=3
URL válidastring
webhook_urlURL a la que se enviará el resultado de la operación. Se puede enviar como string simple o como objeto con headers adicionales.Ejemplos:

- String simple: https://webhook.floid.ai
- Con headers: {
"url": "https://webhook.floid.ai",
"headers": {
"x-api-key": "superkey"
}
}
URL válida o objeto con estructura url + headers
expiration_dateHora y fecha de expiración del flujo. En caso de no incluirse, el tiempo de expiración por defecto es de 30 minutos desde su creación. El formato debe ser
YYYY-MM-DD hh:mm:ss
2030-01-01 10:00:30fechastring
customInformación que se devuelve al webhook al finalizar la operación (max 1000 caracteres)string
bankDefine el banco a utilizar para realizar la transferencia y no permite que el usuario lo modifique. Posibles valores:
banco_chile_personas banco_estado_personas banco_bci_personas banco_itau_personas banco_santander_personas banco_falabella_personas banco_scotia_personas banco_ripley_personas banco_bice_personas
string
recipientDatos del destinatario (ver tabla datos recipient)object

Datos recipient

ParámetroDescripción del CampoTipo
accountNúmero de cuenta del destinatario.int
idRUT sin puntos ni guiones del destinatario.string
nameNombre del destinatario.string
account_typeTipo de cuenta del destinatario:
1: Cuenta corriente 2: Cuenta vista 3: Cuenta de ahorro
int
bankId del banco del destinatario:
1: Banco De Chile - Edwards 9: Banco Internacional 12: Banco Del Estado De Chile 14: Scotiabank 16: BCI (Bco de Credito e Inv) 17: Banco Do Brasil S.a. 27: Itau-corpbanca 28: Banco Bice 31: Hsbc Bank 37: Banco Santander 39: Itau Chile 49: Banco Security 51: Banco Falabella 53: Banco Ripley 55: Banco Consorcio 57: Banco Paris 504: Bbva (Bco Bilbao Vizcaya Arg) 672: Coopeuch 729: Prepago Los Heroes 730: Tenpo Prepago S.a. 732: Tapp Caja Los Andes 875: Mercado Pago
int

Respuesta Exitosa:

ParámetroDescripciónTipo
CodeCódigo HTTP del request.Int
payment_tokenIdentificador único para cada pago.String
payment_urlURL para ingresar al pagoString

Ejemplo

{
    "code": 200,
    "payment_token": "fc74b16d-9a07-4ee9-b1b4-3763bd23a4fd",
    "payment_url": "https://payments.floid.app/?id=fc74b16d-9a07-4ee9-b1b4-3763bd23a4fd"
}

Check Payment

URL: {{HOST}}/cl/payments/check

Postman Collection 🟠

Método: POST

Descripción: Consulta por el estado de un pago.

Hay 2 formas de consultar, la primera es por payment_token:

Body :

{
	"payment_token": "xxx-xxx-xxx-xxx-xxx"
}


ParámetroDescripción del CampoValidaciónTipo
payment_tokenToken de pago entregado por el método createpayment_token existentestring

La segunda es por rango de fechas:

{
    "start_date": "2024-10-22 00:00:00",
    "end_date": "2024-10-22 23:59:59",
    "filter_by": "last_date"
}

ParámetroDescripción del CampoEjemploValidaciónTipo
start_dateFecha inicial a consultar por un grupo de pagos (formato YYYY-MM-dd HH:mm:ss)2024-10-22 00:00:00fechastring
end_dateFecha final a consultar por un grupo de pagos (formato YYYY-MM-dd HH:mm:ss), no puede superar los 30 días2024-10-22 23:59:59fechastring

Opcionales

ParámetroDescripción del CampoEjemploValidaciónTipo
filter_byParámetro bajo el cual se desea filtrar las fechas ingresadas. Opciones: created_at(por defecto), last_datelast_datecreated_at o last_datestring

Respuesta Exitosa:

ParámetroDescripciónTipo
codeCódigo HTTP del request.int
payment_tokenIdentificador único para cada pago.string
statusEstado del pago (ver en estados de pagos)string
stepEl paso en el que va el pago (ver en pasos del pago)string
last_dateLa fecha de la última interacción del usuario con el pagostring
expiredSi el pago está expirado (no se terminó el proceso en el tiempo establecido)string
transfer_dataobject

transfer_data:

ParámetroDescripciónTipo
recipient_emailemail del receptorstring
recipient_accountcuenta del receptorstring
recipient_idrut del receptorstring
recipient_namenombre del receptorstring
recipient_account_typetipo de cuenta del receptorint
recipient_account_type_namenombre del tipo de cuenta del receptorstring
recipient_account_bankbanco del receptorint
recipient_account_bank_namenombre del banco del receptorint
recipient_account_currencymoneda de la cuenta del receptorstring
amountmonto del pagoint
origin_idrut del clientestring
origin_account_bankbanco del clienteint
origin_account_bank_namenombre del banco del clientestring
origin_accountcuenta del clienteint
origin_account_typetipo de cuenta del clienteint
origin_account_type_namenombre del tipo de cuenta del clientestring
datefecha del pagostring

Ejemplo

{
    "code": 200,
    "payment_token": "0b37d9a9-d33d-4316-bbfb-b21519b11921",
    "status": "SUCCESS",
    "step": "FINISHED",
    "last_date": "2025-01-07 17:03:54",
    "transfer_data": {
        "recipient_email": "[email protected]",
        "recipient_account": "123456789",
        "recipient_id": "222222222",
        "recipient_name": "Emepresa Spa",
        "recipient_account_type": 1,
        "recipient_account_type_name": "corriente",
        "recipient_account_bank": 12,
        "recipient_account_bank_name": "Banco Del Estado De Chile",
        "recipient_account_currency": "CLP",
        "amount": 5000,
        "origin_id": "11.111.111-1",
        "origin_account_bank": 51,
        "origin_account_bank_name": "Banco Falabella",
        "origin_account": 12345678901,
        "origin_account_type": 1,
        "origin_account_type_name": "corriente",
        "date": "2025-01-07 17:03:54"
    },
    "expired": false
}

{
    "code": 200,
    "caseid": "38c4a0ed-b462-429f-8cda-2158e26fdd06",
    "msg": "OK",
    "data": [
        {
            "payment_token": "0b37d9a9-d33d-4316-bbfb-b21519b11922",
            "status": "SUCCESS",
            "step": "FINISHED",
            "last_date": "2025-01-07 17:03:54",
            "transfer_data": {
                "recipient_email": "[email protected]",
                "recipient_account": "123456789",
                "recipient_id": "222222222",
                "recipient_name": "Emepresa Spa",
                "recipient_account_type": 1,
                "recipient_account_type_name": "corriente",
                "recipient_account_bank": 12,
                "recipient_account_bank_name": "Banco Del Estado De Chile",
                "recipient_account_currency": "CLP",
                "amount": 5000,
                "origin_id": "11.111.111-1",
                "origin_account_bank": 51,
                "origin_account_bank_name": "Banco Falabella",
                "origin_account": 12345678901,
                "origin_account_type": 1,
                "origin_account_type_name": "corriente",
                "date": "2025-01-07 17:03:54"
            },
            "expired": true
        },
        {
            "payment_token": "0b37d9a9-d33d-4316-bbfb-b21519b11923",
            "status": "SUCCESS",
            "step": "FINISHED",
            "last_date": "2025-01-07 18:03:54",
            "transfer_data": {
                "recipient_email": "[email protected]",
                "recipient_account": "123456789",
                "recipient_id": "222222222",
                "recipient_name": "Emepresa Spa",
                "recipient_account_type": 1,
                "recipient_account_type_name": "corriente",
                "recipient_account_bank": 12,
                "recipient_account_bank_name": "Banco Del Estado De Chile",
                "recipient_account_currency": "CLP",
                "amount": 6000,
                "origin_id": "11.111.111-1",
                "origin_account_bank": 51,
                "origin_account_bank_name": "Banco Falabella",
                "origin_account": 12345678901,
                "origin_account_type": 1,
                "origin_account_type_name": "corriente",
                "date": "2025-01-07 18:03:54"
            },
            "expired": true
        }
    ]
}

Posibles estados para status :

  • NOT_STARTED: El usuario no ha iniciado el proceso de pago.
  • PENDING : El usuario ya comenzó el proceso de pago.
  • SUCCESS: La transferencia se realizó con éxito.
  • FAILED: El proceso de pago falló.
  • CLOSED : El payment token está inhabilitado porque el cliente cerró el flujo o porque se produjo un error que no aplica para reintento.
  • EXPIRED: El plazo de 30 minutos para realizar la transferencia ha expirado.
  • Errores que no aplican para reintento:
    MAX_FAILED_ATTEMPTS: El usuario tuvo dos intentos fallidos de inicio de sesión, por lo que Floid realiza un bloqueo preventivo por 24 horas.
  • LOCKED_CREDENTIALS: Las credenciales proveídas se encuentran bloqueadas en el banco consultado.
  • NO_VERIFICATION_METHOD: El usuario no cuenta con un medio válido para verificar transferencias.
  • TRANSFER_AMOUNT_LIMIT: El monto de la transacci´øn supera el límite permitido por el banco.

Posibles estados para step:

  • LANDING: El usuario no ha iniciado el proceso de pago.
  • ENTER_CREDENTIALS: El usuario ha enviado sus credenciales.
  • SELECT_ACCOUNT: El usuario seleccionó la cuenta a utilizar.
  • AUTH_METHOD: El usuario seleccionó el método de verificación a utilizar.
  • VALIDATION: El usuario envió el 2fa.
  • FINISHED: El proceso ha finalizado.

last_date: Corresponde a la fecha de la última operación realizada por el usuario en el widget. Si aparece valor null significa que el usuario no realizó el ingreso de credenciales.

Posibles códigos de error

Los siguientes errores pueden encontrarse tanto en la respuesta del endpoint /check como en el dashboard de Floid. Los verás bajo la llave error_code.

  • SERVICE_UNAVAILABLE: Error de servicio.
  • INVALID_2FA_TOKEN: El token de verificación entregado por el usuario es incorrecto.
  • INVALID_CREDENTIALS: Las credenciales ingresadas son incorrectas.
  • TRANSFER_ERROR: Error de servicio ocurrido durante la transferencia.
  • BANK_DOWN: El servicio del banco está caído.
  • WEBSITE_ERROR: El sitio del banco presentó problemas.
  • BEPASS_ERROR: Error en la validación a través de BE Pass (Banco Estado).
  • SECOND_TRANSFER_ERROR: No se puede realizar una segunda transferencia a un destinatario nuevo durante 24 horas.
  • VERIFICATION_METHOD_ERROR: El método de verificación seleccionado no es válido.
  • LOCKED_DEVICE: El método de verificación se encuentra bloqueado por el banco.
  • TRANSFER_TIMEOUT: Error de servicio. No se ha recibido respuesta en el plazo establecido.
  • INSUFFICIENT_BALANCE: El monto disponible no es suficiente para realizar la transferencia.
  • CONFIRMATION_FAILED: No se ha podido validar si la transferencia fue realizada exitosamente. Se recomienda en estos casos validar con el equipo de Floid y/o revisar los comprobantes recibidos al email.
  • MAX_FAILED_ATTEMPTS: Se ha alcanzado el máximo número de intentos de login exitosos.
  • NO_VERIFICATION_METHODS: El usuario no tiene métodos de validación disponibles en el banco.
  • INVALID_ACCOUNT_NUMBER: El número de cuenta de origen seleccionado es inválido. Error probablemente relacionado a un error de servicio.
  • SMS_ERROR: El sms ingresado es incorrecto.
  • MINIMUM_TRANSFER_AMOUNT: El monto de la transferencia es menor al mínimo establecido por el banco.
  • EXPIRED_CREDENTIALS: Las credenciales han expirado y necesitan ser renovadas en el portal del banco.
  • KEYPASS_EXPIRED: El tiempo para validar la transferencia en KeyPass (Scotiabank) ha finalizado.
  • TRANSFER_CANCELLED: La transferencia ha sido cancelada por el usuario en la aplicación.
  • BANK_ERROR: El banco ha presentado problemas realizando la operación.
  • SESSION_EXPIRED: La sesión del banco ha expirado.
  • MAX_DAILY_TOTAL_AMOUNT: Máximo diario de transferencias.
  • MAX_DAILY_AMOUNT: El monto excede el límite diario a un destinatario.
  • MAX_DAILY_TRANSFERS: Máximo diario de transferencias para este destinatario.
  • MAX_DAILY_2FA_TRIES: Máximo diario de intentos para ingresar la clave dinámica.
  • TRANSFER_AMOUNT_LIMIT: El monto de la transacción supera el límite permitido por el banco.

5. Manejo de Errores

Estructura de Respuesta de Error

{
  "code": Int,
  "error_type": "string",
  "error_code": "string",
  "error_message": "string",
  "display_message": "string",
  "caseid": "string"
}
ParámetroDescripciónTipo
codeCódigo HTTP del error.Int
error_typeCódigo específico del error definido por Floid.String
error_codeCódigo específico del error definido por Floid. Se puede usar programáticamente.String
error_messageMensaje que entrega detalles sobre el error. Puede cambiar con el tiempo por lo que no debe ser usado programáticamente.String
display_messageMensaje con detalles del error que puede ser mostrado al usuario en tu front-end . Puede cambiar con el tiempo por lo que no debe ser usado programáticamente.String
caseidIdentificador único para cada request que se realiza a la API de Floid. Se generará al inicio de la consulta y será parte del response.String

Ejemplos

{
  "code": 400,
  "error_type": "PAYMENTS",
  "error_code": "INVALID_PAYMENT_TOKEN",
  "msg": "Token de pago inválido.",
  "error_message": "El token de pago no es válido",
  "display_message": "El token de pago no es válido",
  "caseid":"xxx-xxx-xxx-xxx-xxx"
}
{
  "code": 400,
  "error_type": "PAYMENTS",
  "error_code": "INVALID_PAYMENT_WIDGET",
  "msg": "Token de pago no tiene asociado un widget para el país y moneda.",
  "error_message": "El token de pago no tiene asociado un widget para el país y moneda.",
  "display_message": "El token de pago no tiene asociado un widget para el país y moneda.",
  "caseid":"xxx-xxx-xxx-xxx-xxx"
}
{
  "code": 400,
  "error_type": "PAYMENTS",
  "error_code": "INVALID_PAYMENT_ACCOUNT",
  "msg": "Token de pago no tiene asociada una cuenta recaudadora.",
  "error_message": "El token de pago no tiene asociada una cuenta recaudadora.",
  "display_message": "El token de pago no tiene asociada una cuenta recaudadora.",
  "caseid":"xxx-xxx-xxx-xxx-xxx"
}
{
  "code": 400,
  "error_type": "TRANSFER",
  "error_code": "INVALID_EXPIRATION_DATE",
  "error_message": "The specified expiration date does not have the proper format (YYYY-MM-DD hh:mm:ss) or is in the past.",
  "display_message": "La fecha de expiración especificada no cumple con el formato correcto (YYYY-MM-DD hh:mm:ss) o es anterior a la fecha actual.",
  "caseid":"xxx-xxx-xxx-xxx-xxx"
}
{
  "code": 400,
  "error_type": "API_ERROR",
  "error_code": "INVALID_REQUEST",
  "error_message": "The request is not valid. Check the body and headers and try again.",
  "display_message": "La request no es válida. Revisa el body y headers e intenta nuevamente. ' . $message . '",
  "caseid":"xxx-xxx-xxx-xxx-xxx"
}
{
  "code": 400,
  "error_type": "API_ERROR",
  "error_code": "INVALID_REQUEST_AMOUNT",
  "error_message": "The amount to be transferred must be different from 0",
  "display_message": "Monto a transferir debe ser distinto a 0",
  "caseid":"xxx-xxx-xxx-xxx-xxx"
}
{
  "code": 400,
  "error_type": "SERVICE_ERROR",
  "error_code": "SERVICE_UNAVAILABLE",
  "error_message": "The service is unavailable",
  "display_message": "The service is unavailable.",
  "caseid":"xxx-xxx-xxx-xxx-xxx"
}
{
  "code": 400,
  "error_type": "AUTH_ERROR",
  "error_code": "METHOD_NOT_AUTH",
  "error_message": "This method is not authorized",
  "display_message": "El metodo no está autorizado",
  "caseid":"xxx-xxx-xxx-xxx-xxx"
}

6. Webhooks

¿Cómo configurar y manejar webhooks para recibir notificaciones en tiempo real sobre cambios en los estados de los pagos?

Agrega al body de tu consulta el siguiente parámetro para recibir las notificaciones a tu webhook.

ParamétroDescripciónTipo
webhook_urlUrl del servicio donde se recibirán los datosString
{    
    "amount": 3,
    "webhook_url": "https://wwww.mywebhook.in"
}

Respuesta Exitosa:

{
  "payment": "mZXJlbmNpYSByZWFsaXphZGEgY29uIGV4aXRvLiIsInRyYW5zZmVyX2RhdGEiOnsicmVjaXBpZW50X2VtYWlsIjoiY29ycmVvQGRlc3Rpbm8uY2wiLCJyZWNpcGllbnRfYWNjb3VudCI6IjUzMzAwMDU5MzY0IiwicmVjaXBpZW50X2lkIjoiMjIyMjIyMjIyIiwicmVjaXBpZW50X25hbWUiOiJFbXByZXNhIFNQQSIsInJlY2lwaWVudF9hY2NvdW50X3R5cGUiOjEsInJlY2lwaWVudF9hY2NvdW50X3R5cGVfbmFtZSI6ImNvcnJpZW50ZSIsInJlY2lwaWVudF9hY2NvdW50X2JhbmsiOjEyLCJyZWNpcGllbnRfYWNjb3VudF9iYW5rX25hbWUiOiJCYW5jbyBEZWwgRXN0YWRvIERlIENoaWxlIiwicmVjaXBpZW50X2FjY291bnRfY3VycmVuY3kiOiJDTFAiLCJhbW91bnQiOjUwMDAsIm9yaWdpbl9pZCI6IjExMTExMTExMSIsIm9yaWdpbl9hY2NvdW50X2JhbmsiOjUxLCJvcmlnaW5fYWNjb3VudF9iYW5rX25hbWUiOiJCYW5jbyBGYWxhYmVsbGEiLCJvcmlnaW5fYWNjb3VudCI6MTIzNDU2Nzg5MDEsIm9yaWdpbl9hY2NvdW50X3R5cGUiOjEsIm9yaWdpbl9hY2NvdW50X3R5cGVfbmFtZSI6ImNvcnJpZW50ZSIsImRhdGUiOiIyMDI1LTAxLTA3IDE3OjAzOjU2In0sInN0YXR1cyI6IlNVQ0NFU1MiLCJzdGVwIjoiRklOSVNIRUQiLCJwYXltZW50X2lkIjoiNGVjNDFhNjMzZGY5MTdkMTc2NzUxOWQ2YTc0ZTgwZWIyIiwicGF5bWVudF90b2tlbiI6IjBkMjczOTlmLTI0OWYtNGEyZS1iOTA0LTJlYjVjYzljYTkwMyIsImFtb3VudCI6IjUwMDAuMDAiLCJkYXRlIjoiMjAyNS0wMS0wN1QyMDowMzo1Ny41MDlaIiwiY3VzdG9tIjoicGFyYW1ldHJvX2N1c3RvbSIsImlhdCI6MTczNjI4MDIzN30.UfCl8Bk0lZFuNmUa89twlHDK3_Ux7uxWn0Re0hs9dSo"
}

Que es un JWT que contiene lo siguiente:

{
  "data": {
    "name": "NOMBRE CLIENTE",
    "operation_number": "158104"
  },
  "code": 200,
  "message": "Transferencia realizada con exito.",
  "transfer_data": {
    "recipient_email": "[email protected]",
    "recipient_account": "53300059364",
    "recipient_id": "222222222",
    "recipient_name": "Empresa SPA",
    "recipient_account_type": 1,
    "recipient_account_type_name": "corriente",
    "recipient_account_bank": 12,
    "recipient_account_bank_name": "Banco Del Estado De Chile",
    "recipient_account_currency": "CLP",
    "amount": 5000,
    "origin_id": "111111111",
    "origin_account_bank": 51,
    "origin_account_bank_name": "Banco Falabella",
    "origin_account": 12345678901,
    "origin_account_type": 1,
    "origin_account_type_name": "corriente",
    "date": "2025-01-07 17:03:56"
  },
  "status": "SUCCESS",
  "step": "FINISHED",
  "payment_id": "4ec41a633df917d1767519d6a74e80eb2",
  "payment_token": "0d27399f-249f-4a2e-b904-2eb5cc9ca903",
  "amount": "5000.00",
  "date": "2025-01-07T20:03:57.509Z",
  "custom": "parametro_custom",
  "iat": 1736280237
}

*Notar que el campo data es variable (podrían venir más datos), porque son datos que el banco nos da y es diferente para cada banco.


7. Sandbox

Para sandbox, utilizar la siguiente información en el widget:
Bancos habilitados para sandbox:

  • Banco Estado
  • Banco de Chile
  • Banco Santander
  • Banco BCI

id :

  • 11111111-1 : El destinatario no existe, debe ser creado. Para crearlo existen dos métodos de verificación.
  • 22222222-2: El destinatario existe. Para validar la transferencia existen dos métodos de verificación.
  • 99999999-9: ERROR. El monto supera el valor máximo permitido por el banco para un nuevo destinatario. (error_code: TRANSFER_AMOUNT_LIMIT)

password: 1234
SMS: 1234
Tarjeta de Coord: 01-02-03
OBS: Las interacciones con las apps se aprueban automáticamente luego de 7 segundos