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

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

La API de PayIn de Floid Perú permite recibir pagos cuenta a cuenta (C2A) de forma automática y segura.
A través de esta guía podrás:

  • Crear y administrar pagos con Floid.

  • Obtener actualizaciones de estado en tiempo real vía webhooks.

  • Integrar el flujo completo en tu aplicación mediante nuestro widget embebible.


1. Requisitos

Antes de comenzar, asegúrate de cumplir los siguientes requisitos:

  1. Cuenta Floid activa con acceso al Dashboard.
  2. API Key o Token Floid habilitado para Payins (solicítalo al equipo comercial).
  3. Entorno de desarrollo preparado para realizar solicitudes HTTPS (curl, axios, requests, etc.).
  4. Widget de pagos configurado para tu integración.

2. Diagrama

El flujo del pago para integrar el pago via payin tiene los siguientes pasos:

  1. El merchant crea el pago (endpoint /pe/payments/create).
  2. Floid genera el payment_token y la URL del widget de pago.
  3. El usuario final realiza la transferencia desde su banco.
  4. Floid recibe la confirmación bancaria y actualiza el estado del pago.
  5. El merchant recibe una notificación en su webhook configurado.


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}}/pe/payments/create

Postman Collection 🟠

Método: POST

Descripción: Crea un nuevo pago.

Body:

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

Obligatorios A continuación se detallan los campos obligatorios requeridos para el método. Para adecuaciones custom, el usuario puede referirse a los campos opcionales acorde al tipo de implementación que requiera.

ParámetroDescripción del CampoEjemploValidaciónTipo
amountMonto de la transacción o cantidad300Debe ser un número no negativofloat
currencyMoneda. Posibles valores:
PEN
USD
PENstring

Opcionales: Listados de campos opcionales al request para adecuaciones custom.

ParámetroDescripción del CampoEjemploValidaciónTipo
consumer_idDNI/ID del usuario. 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 DNI/ID.123456787 u 8 dígitosstring
consumer_id_typeTipo de documento del usuario. Posibles valores:
dni
ce (Carné de Extranjería)
pas (Pasaporte)
dni
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.https://redirect.floid.aiURL válidastring
webhook_urlURLa la que se enviará el resultado de la operación.https://webhook.floid.aiURL válida
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ónstring
bankDefine el banco a utilizar para realizar la transferencia y no permite que el usuario lo modifique. Posibles valores:
banco_bcp_personas banco_interbank_personas banco_pichincha_personas banco_alfin_personas banco_scotia_personas banco_bbva_personas banco_falabella_personas caja_arequipa_personas caja_huancayo_personas caja_piura_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 3: Cuenta de ahorro
int
bankId del banco del destinatario:
2: Banco De Crédito Del Perú 3: Interbank 7: Citibank Del Perú S.A., 9: Scotiabank Perú S.A.A., 11: BBVA Continental", 18: "Banco De La Nación", 23: "Banco De Comercio", 35: "Banco Pichincha", 38: "Banco Interamericano De Finanzas", 43: "Crediscotia Financiera S.A.", 49: "Mibanco, Banco De La Microempresa S.A.", 53: "Banco Gnb Peru", 54: "Banco Falabella Perù S.A.", 55: "Banco Ripley", 56: "Banco Santander Peru", 58: "Banco Azteca Del Perú S.A. - Alfin", 60: "ICBC Perú Bank", 91: "Compartamos Financiera S.A.", 800: "Caja Metropolitana", 801: "CMAC Piura", 802: "CMAC Trujillo", 803: "CMAC Arequipa", 805: "CMAC Sullana", 806: "CMAC Cusco", 808: "CMAC Huancayo", 809: "CMAC Ica", 811: "CMAC Maynas", 813: "CMAC Tacna"
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_accountNúmero de cuenta del receptor del pago.string
recipient_idRUC/DNI o identificador tributario del receptor.string
recipient_nameNombre del receptor.string
recipient_account_typeTipo de cuenta del receptor (1: corriente, 2: ahorro).int
recipient_account_type_nameNombre del tipo de cuenta del receptor.string
recipient_account_bankIdentificador numérico del banco del receptor.int
recipient_account_bank_nameNombre del banco del receptor.string
recipient_account_currencyMoneda de la cuenta del receptor (PEN o USD).string
amountMonto recibido en la cuenta del receptor.int
recipient_emailEmail asociado al receptor.string
expected_amountMonto total esperado para la transacción.string
origin_idRUC/DNI o identificador tributario del pagador.string
origin_account_bankIdentificador numérico del banco del pagador.int
origin_account_bank_nameNombre del banco del pagador.string
origin_accountNúmero de cuenta del pagador.string
origin_account_typeTipo de cuenta del pagador (1: corriente, 2: ahorro).int
origin_account_type_nameNombre del tipo de cuenta del pagador.string
dateFecha y hora de la transacción (YYYY/MM/DD HH:mm:ss).string

Ejemplo

{
  "code": 200,
  "status": "SUCCESS",
  "step": "FINISHED",
  "transfer_data": {
    "recipient_account": "054354357934790273094723",
    "recipient_id": "22222222222",
    "recipient_name": "Floid",
    "recipient_account_type": 1,
    "recipient_account_type_name": "corriente",
    "recipient_account_bank": 58,
    "recipient_account_bank_name": "banco_alfin_personas",
    "recipient_account_currency": "PEN",
    "amount": 1,
    "recipient_email": "[email protected]",
    "expected_amount": "1.00",
    "origin_id": "21231321321",
    "origin_account_bank": 806,
    "origin_account_bank_name": "CMAC Cusco",
    "origin_account": "435124123123123",
    "origin_account_type": 2,
    "origin_account_type_name": "ahorro",
    "date": "2013/05/2025 16:26:30"
  },
  "payment_id": "75f182a48f291142babd67651c14c2cf1",
  "message": "Transferencia realizada con éxito, validada por servicio Alfin",
  "payment_token": "f70e4dd8-4988-4c61-a002-05380cc1f5da",
  "amount": "1.00",
  "date": "2025-10-09T13:13:31.702Z",
  "iat": 1760022811
}

{
    "code": 200,
    "caseid": "d2e45c25-a884-48a5-b532-0aa0bc88d1c5",
    "msg": "OK",
    "data": [
        {
            "payment_token": "57b234c2-1cd4-4404-b609-d3d91fc11b4e",
            "status": "SUCCESS",
            "step": "FINISHED",
            "created_at": "2025-10-07 10:34:48",
            "last_date": "2025-10-07 10:35:29",
            "transfer_data": {
                "recipient_email": "[email protected]",
                "recipient_account": "50103506037",
                "recipient_id": "153150001",
                "recipient_name": "Cuenta 1",
                "recipient_account_type": 2,
                "recipient_account_type_name": "vista",
                "recipient_account_bank": 51,
                "recipient_account_bank_name": "Banco Falabella",
                "recipient_account_currency": "CLP",
                "amount": 1,
                "origin_id": "15.315.000-1",
                "origin_account_bank": 51,
                "origin_account_bank_name": "Banco Falabella",
                "origin_account": 50103506037,
                "origin_account_type": 2,
                "origin_account_type_name": "vista",
                "date": "2025-10-07 10:35:29"
            },
            "expired": false
        },
        {
            "payment_token": "4accc42d-8616-446e-a0b8-ce7b859e54ff",
            "status": "PENDING",
            "step": "SELECT_ACCOUNT",
            "created_at": "2025-10-07 10:38:04",
            "last_date": "2025-10-07 10:38:40",
            "transfer_data": {
                "recipient_email": "[email protected]",
                "recipient_account": "50103506037",
                "recipient_id": "153150001",
                "recipient_name": "Cuenta 1",
                "recipient_account_type": 2,
                "recipient_account_type_name": "vista",
                "recipient_account_bank": 51,
                "recipient_account_bank_name": "Banco Falabella",
                "recipient_account_currency": "CLP",
                "amount": 1,
                "origin_id": "15.315.000-1",
                "origin_account_bank": 51,
                "origin_account_bank_name": "Banco Falabella",
                "origin_account": 50103506037,
                "origin_account_type": 2,
                "origin_account_type_name": "vista"
            },
            "expired": false
        }
    ]
}

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": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7Im5hbWUiOiJOT01CUkUgQ0xJRU5URSIsIm9wZXJhdGlvbl9udW1iZXIiOiIxNTgxMDQifSwiY29kZSI6MjAwLCJtZXNzYWdlIjoiVHJhbnNmZXJlbmNpYSByZWFsaXphZGEgY29uIGV4aXRvLiIsInRyYW5zZmVyX2RhdGEiOnsicmVjaXBpZW50X2VtYWlsIjoiY29ycmVvQGRlc3Rpbm8ucGUiLCJyZWNpcGllbnRfYWNjb3VudCI6IjUzMzAwMDU5MzY0IiwicmVjaXBpZW50X2lkIjoiMjIyMjIyMjIyIiwicmVjaXBpZW50X25hbWUiOiJFbXByZXNhIFNQQSIsInJlY2lwaWVudF9hY2NvdW50X3R5cGUiOjEsInJlY2lwaWVudF9hY2NvdW50X3R5cGVfbmFtZSI6ImNvcnJpZW50ZSIsInJlY2lwaWVudF9hY2NvdW50X2JhbmsiOjIsInJlY2lwaWVudF9hY2NvdW50X2JhbmtfbmFtZSI6IkJhbmNvIERlIENyw6lkaXRvIERlbCBQZXLDuiIsInJlY2lwaWVudF9hY2NvdW50X2N1cnJlbmN5IjoiQ0xQIiwiYW1vdW50Ijo1MDAwLCJvcmlnaW5faWQiOiIxMTExMTExMTEiLCJvcmlnaW5fYWNjb3VudF9iYW5rIjoyLCJvcmlnaW5fYWNjb3VudF9iYW5rX25hbWUiOiJCYW5jbyBEZSBDcsOpZGl0byBEZWwgUGVyw7oiLCJvcmlnaW5fYWNjb3VudCI6MTIzNDU2Nzg5MDEsIm9yaWdpbl9hY2NvdW50X3R5cGUiOjEsIm9yaWdpbl9hY2NvdW50X3R5cGVfbmFtZSI6ImNvcnJpZW50ZSIsImRhdGUiOiIyMDI1LTAxLTA3IDE3OjAzOjU2In0sInN0YXR1cyI6IlNVQ0NFU1MiLCJzdGVwIjoiRklOSVNIRUQiLCJwYXltZW50X2lkIjoiNGVjNDFhNjMzZGY5MTdkMTc2NzUxOWQ2YTc0ZTgwZWIyIiwicGF5bWVudF90b2tlbiI6IjBkMjczOTlmLTI0OWYtNGEyZS1iOTA0LTJlYjVjYzljYTkwMyIsImFtb3VudCI6IjUwMC4wMCIsImRhdGUiOiIyMDI1LTAxLTA3VDIwOjAzOjU3LjUwOVoiLCJjdXN0b20iOiJwYXJhbWV0cm9fY3VzdG9tIiwiaWF0IjoxNzM2MjgwMjM3fQ.qZ3UHhO2tktmT_-tXX6i5rB4QQjIcHnFxmDgRUW93oo"
}

El cual es un JWT que contiene lo siguiente:

{
  "data": 
    "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": 2,
    "recipient_account_bank_name": "Banco De Crédito Del Perú",
    "recipient_account_currency": "CLP",
    "amount": 5000,
    "origin_id": "111111111",
    "origin_account_bank": 2,
    "origin_account_bank_name": "Banco De Crédito Del Perú",
    "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": "500.00",
  "date": "2025-01-07T20:03:57.509Z",
  "custom": "parametro_custom",
  "iat": 1736280237
}