{
  "openapi": "3.1.0",
  "info": {
    "title": "KUTI API",
    "version": "1.0.0",
    "description": "API de pagos en Perú: QR interoperable (Yape/Plin), pago de servicios (institución KUTI), checkout, saldo, liquidaciones, webhooks, SDKs (Node/PHP/Python) y plugin WooCommerce 1.0.0. Base URL https://api.kuti.pe/v1.\n\nEspecificación generada automáticamente desde la documentación (https://docs.kuti.pe). Compatible con Postman, Insomnia y Bruno.\n\nVariables sugeridas:\n- `baseUrl`: https://api.kuti.pe/v1\n- `bearerToken`: kuti_live_… (reemplaza por tu secret key real)",
    "contact": {
      "name": "Consultia Digital S.A.C.",
      "email": "soporte@kuti.pe",
      "url": "https://www.kuti.pe"
    }
  },
  "servers": [
    {
      "url": "https://api.kuti.pe/v1",
      "description": "api.kuti.pe/v1"
    }
  ],
  "tags": [
    {
      "name": "Balance",
      "description": "Endpoints de /balance"
    },
    {
      "name": "Balance Transactions",
      "description": "Endpoints de /balance-transactions"
    },
    {
      "name": "Checkout Sessions",
      "description": "Endpoints de /checkout-sessions"
    },
    {
      "name": "Customers",
      "description": "Endpoints de /customers"
    },
    {
      "name": "Events",
      "description": "Endpoints de /events"
    },
    {
      "name": "Fee Preview",
      "description": "Endpoints de /fee-preview"
    },
    {
      "name": "Merchants",
      "description": "Endpoints de /merchants"
    },
    {
      "name": "Payment Intents",
      "description": "Endpoints de /payment-intents"
    },
    {
      "name": "Payout Accounts",
      "description": "Endpoints de /payout-accounts"
    },
    {
      "name": "Payout Settings",
      "description": "Endpoints de /payout-settings"
    },
    {
      "name": "Payouts",
      "description": "Endpoints de /payouts"
    },
    {
      "name": "Webhook Deliveries",
      "description": "Endpoints de /webhook-deliveries"
    },
    {
      "name": "Webhook Endpoints",
      "description": "Endpoints de /webhook-endpoints"
    }
  ],
  "paths": {
    "/balance": {
      "get": {
        "operationId": "get-balance",
        "summary": "Consultar saldo",
        "description": "Saldo actual del negocio: lo pendiente de depositar y lo ya depositado en tu cuenta bancaria.\n\npending_deposit = cobrado que aún no llegó a tu banco. deposited = histórico de lo ya depositado. El modo (test/live) lo define tu API key.",
        "tags": [
          "Balance"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": {
                    "currency": "PEN",
                    "pending_deposit": {
                      "amount": "1250.50",
                      "currency": "PEN"
                    },
                    "deposited": {
                      "amount": "8900.00",
                      "currency": "PEN"
                    },
                    "by_status": {
                      "PENDING": {
                        "amount": "200.00",
                        "currency": "PEN"
                      },
                      "AVAILABLE": {
                        "amount": "1050.50",
                        "currency": "PEN"
                      },
                      "IN_PAYOUT": {
                        "amount": "0.00",
                        "currency": "PEN"
                      },
                      "PAID": {
                        "amount": "8900.00",
                        "currency": "PEN"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/balance-transactions": {
      "get": {
        "operationId": "get-balance-transactions",
        "summary": "Movimientos del saldo",
        "description": "Ledger del negocio: cada cobro, reembolso, payout o contracargo que afecta el saldo, con desglose de comisión.\n\ntype: PAYMENT, REFUND, PAYOUT, ADJUSTMENT, CHARGEBACK. status: PENDING, AVAILABLE, IN_PAYOUT, PAID. Filtra por payout_id para ver lo incluido en un depósito.",
        "tags": [
          "Balance Transactions"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "btxn_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "type": "PAYMENT",
                      "status": "AVAILABLE",
                      "currency": "PEN",
                      "payment_method": "INTEROPERABLE_QR",
                      "source_type": "PAYMENT",
                      "source_id": "pay_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "gross": {
                        "amount": "50.00",
                        "currency": "PEN"
                      },
                      "fee": {
                        "amount": "-1.77",
                        "currency": "PEN"
                      },
                      "fee_tax": {
                        "amount": "-0.27",
                        "currency": "PEN"
                      },
                      "net": {
                        "amount": "48.23",
                        "currency": "PEN"
                      },
                      "available_on": "2026-09-06T00:00:00Z",
                      "available_confirmed": true,
                      "created_at": "2026-09-04T10:48:59.556906Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "per_page": 25,
                    "total": 1,
                    "total_pages": 1,
                    "has_more": false
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "PAYMENT | REFUND | PAYOUT | ADJUSTMENT | CHARGEBACK.",
            "schema": {
              "description": "PAYMENT | REFUND | PAYOUT | ADJUSTMENT | CHARGEBACK.",
              "type": "string"
            }
          },
          {
            "name": "payout_id",
            "in": "query",
            "required": false,
            "description": "Solo movimientos de ese payout (pyt_…).",
            "schema": {
              "description": "Solo movimientos de ese payout (pyt_…).",
              "example": "pyt_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
              "type": "string"
            },
            "example": "pyt_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Página (1-based).",
            "schema": {
              "description": "Página (1-based).",
              "example": 1,
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "description": "Elementos por página (1–100) o all.",
            "schema": {
              "description": "Elementos por página (1–100) o all.",
              "example": 25,
              "type": "string"
            },
            "example": 25
          }
        ]
      }
    },
    "/checkout-sessions": {
      "post": {
        "operationId": "post-checkout-sessions",
        "summary": "Crear sesión de checkout",
        "description": "Crea una sesión de checkout (cargo único) y el payment intent asociado. Devuelve checkout_url para Checkout.js o pay.kuti.pe.\n\nAutoriza con secret o publishable key. amount.currency: solo PEN por ahora. Idempotency-Key recomendada. El checkout_url ya incluye el client_secret para abrir el modal/embed.",
        "tags": [
          "Checkout Sessions"
        ],
        "responses": {
          "201": {
            "description": "201",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "cs_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "merchant_id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "payment_intent_id": "pi_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "amount": {
                      "amount": "249.90",
                      "currency": "PEN"
                    },
                    "status": "OPEN",
                    "description": "Pedido #1042",
                    "client_secret": "cs_secret_ab12cd34ef56",
                    "checkout_url": "https://pay.kuti.pe/embed?cs=cs_secret_ab12cd34ef56",
                    "payment_method": {
                      "qr": {
                        "type": "INTEROPERABLE_QR",
                        "payload": "00020101021226...",
                        "expires_at": "2026-09-05T23:59:59Z"
                      },
                      "payment_code": {
                        "type": "BANK_TRANSFER",
                        "code": "41041172",
                        "expires_at": "2026-09-05T23:59:59Z"
                      }
                    },
                    "created_at": "2026-09-04T10:48:59.556906Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Validación",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Validation failed.",
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Validation failed.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount": {
                    "description": "Monto a cobrar.",
                    "type": "object",
                    "properties": {
                      "amount": {
                        "description": "Decimal como string.",
                        "example": 249.9,
                        "type": "string"
                      },
                      "currency": {
                        "description": "Solo PEN por ahora.",
                        "example": "PEN",
                        "type": "string"
                      }
                    },
                    "required": [
                      "amount",
                      "currency"
                    ]
                  },
                  "payment_method_types": {
                    "description": "INTEROPERABLE_QR y/o BANK_TRANSFER.",
                    "example": [
                      "INTEROPERABLE_QR",
                      "BANK_TRANSFER"
                    ],
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "customer": {
                    "description": "Opcional. Orden: id (cus_… existente) → external_id → name/email/phone (crea cliente). Si envías id, se ignora el resto.",
                    "type": "object",
                    "properties": {
                      "id": {
                        "description": "Customer existente (cus_…). Preferido si ya lo creaste con POST /customers.",
                        "example": "cus_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                        "type": "string"
                      },
                      "external_id": {
                        "description": "Id en tu sistema.",
                        "example": "cust_erp_4821",
                        "type": "string"
                      },
                      "name": {
                        "description": "Nombre completo.",
                        "example": "María López",
                        "type": "string"
                      },
                      "email": {
                        "description": "Correo.",
                        "example": "maria@example.com",
                        "type": "string"
                      },
                      "phone": {
                        "description": "E.164.",
                        "example": "+51987654321",
                        "type": "string"
                      }
                    }
                  },
                  "description": {
                    "description": "Texto del cobro.",
                    "example": "Pedido #1042",
                    "type": "string"
                  },
                  "external_reference": {
                    "description": "Referencia en tu sistema.",
                    "example": "order-1042",
                    "type": "string"
                  },
                  "success_url": {
                    "description": "URL a la que redirigir tras pagar (opcional).",
                    "example": "https://tienda.pe/pago/ok",
                    "type": "string"
                  },
                  "expires_at": {
                    "description": "Vencimiento (UTC ISO-8601).",
                    "type": "string"
                  },
                  "metadata": {
                    "description": "Pares string→string libres.",
                    "type": "object",
                    "additionalProperties": true
                  }
                },
                "required": [
                  "amount",
                  "payment_method_types"
                ]
              },
              "example": {
                "amount": {
                  "amount": "249.90",
                  "currency": "PEN"
                },
                "payment_method_types": [
                  "INTEROPERABLE_QR",
                  "BANK_TRANSFER"
                ],
                "customer": {
                  "name": "María López",
                  "email": "maria@example.com",
                  "phone": "+51987654321"
                },
                "description": "Pedido #1042",
                "external_reference": "order-1042"
              }
            }
          }
        }
      }
    },
    "/checkout-sessions/{id}": {
      "get": {
        "operationId": "get-checkout-session",
        "summary": "Detalle de sesión de checkout",
        "description": "Consulta el estado de una sesión. Público: autentica con client_secret (query o X-Kuti-Token).\n\nPúblico: no uses Authorization Bearer. Autoriza con el client_secret de la sesión — query ?client_secret=… o header X-Kuti-Token (mismo valor; el header tiene prioridad).",
        "tags": [
          "Checkout Sessions"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "cs_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "merchant_id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "payment_intent_id": "pi_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "amount": {
                      "amount": "249.90",
                      "currency": "PEN"
                    },
                    "status": "COMPLETED",
                    "checkout_url": "https://pay.kuti.pe/embed?cs=cs_secret_ab12cd34ef56",
                    "created_at": "2026-09-04T10:48:59.556906Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No autorizado"
          },
          "404": {
            "description": "No encontrada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "The requested checkout session does not exist.",
                  "error": {
                    "code": "CHECKOUT_SESSION_NOT_FOUND",
                    "message": "The requested checkout session does not exist.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "client_secret",
            "in": "query",
            "required": false,
            "description": "Secret de la sesión (si no usas X-Kuti-Token).",
            "schema": {
              "description": "Secret de la sesión (si no usas X-Kuti-Token).",
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id de la sesión (cs_…).",
            "schema": {
              "type": "string",
              "example": "cs_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
            }
          }
        ]
      }
    },
    "/customers": {
      "get": {
        "operationId": "get-customers",
        "summary": "Listar clientes",
        "description": "Lista customers del merchant autenticado, con búsqueda y paginación.\n\nper_page acepta un entero 1–100 o el literal all. q busca en nombre, razón social, correo, documento o external_id.",
        "tags": [
          "Customers"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "cus_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "merchant_id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "external_id": "cust_erp_4821",
                      "type": "INDIVIDUAL",
                      "first_name": "María",
                      "last_name": "López",
                      "document": {
                        "country": "PE",
                        "type": "DNI",
                        "value": "45678912"
                      },
                      "email": "maria@example.com",
                      "phone": "+51987654321",
                      "created_at": "2026-09-04T10:48:59.556906Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "per_page": 25,
                    "total": 1,
                    "total_pages": 1,
                    "has_more": false
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "An unexpected error occurred.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "An unexpected error occurred.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Búsqueda por nombre, razón social, correo, documento o external_id.",
            "schema": {
              "description": "Búsqueda por nombre, razón social, correo, documento o external_id.",
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Página (1-based).",
            "schema": {
              "description": "Página (1-based).",
              "example": 1,
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "description": "Elementos por página (1–100) o all.",
            "schema": {
              "description": "Elementos por página (1–100) o all.",
              "example": 25,
              "type": "string"
            },
            "example": 25
          }
        ]
      },
      "post": {
        "operationId": "post-customers",
        "summary": "Crear cliente",
        "description": "Crea un customer (pagador) para el merchant autenticado por tu API key.\n\ntype es obligatorio: INDIVIDUAL (persona) o COMPANY (empresa). Persona usa first_name/last_name; empresa usa company_name. Puedes enviar Idempotency-Key (UUID v4).",
        "tags": [
          "Customers"
        ],
        "responses": {
          "201": {
            "description": "201",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "message": "Customer created",
                  "data": {
                    "id": "cus_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "merchant_id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "external_id": "cust_erp_4821",
                    "type": "INDIVIDUAL",
                    "first_name": "María",
                    "last_name": "López",
                    "document": {
                      "country": "PE",
                      "type": "DNI",
                      "value": "45678912"
                    },
                    "email": "maria@example.com",
                    "phone": "+51987654321",
                    "created_at": "2026-09-04T10:48:59.556906Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Conflicto",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "A customer with this external_id already exists.",
                  "error": {
                    "code": "CONFLICT",
                    "message": "A customer with this external_id already exists.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Validación",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Validation failed.",
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Validation failed.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "details": [
                      {
                        "field": "type",
                        "code": "REQUIRED",
                        "message": "type is required."
                      }
                    ]
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "An unexpected error occurred.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "An unexpected error occurred.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type": {
                    "description": "INDIVIDUAL o COMPANY.",
                    "example": "INDIVIDUAL",
                    "type": "string"
                  },
                  "external_id": {
                    "description": "Id en tu sistema (ERP, CRM, …).",
                    "example": "cust_erp_4821",
                    "type": "string"
                  },
                  "first_name": {
                    "description": "Nombres (INDIVIDUAL).",
                    "example": "María",
                    "type": "string"
                  },
                  "last_name": {
                    "description": "Apellidos (INDIVIDUAL).",
                    "example": "López",
                    "type": "string"
                  },
                  "company_name": {
                    "description": "Razón social (COMPANY).",
                    "type": "string"
                  },
                  "document": {
                    "description": "Documento de identidad.",
                    "type": "object",
                    "properties": {
                      "country": {
                        "description": "ISO 3166-1 alpha-2.",
                        "example": "PE",
                        "type": "string"
                      },
                      "type": {
                        "description": "DNI, RUC, CE, PASSPORT, …",
                        "example": "DNI",
                        "type": "string"
                      },
                      "value": {
                        "description": "Número del documento.",
                        "example": 45678912,
                        "type": "string"
                      }
                    }
                  },
                  "email": {
                    "description": "Correo.",
                    "example": "maria@example.com",
                    "type": "string"
                  },
                  "phone": {
                    "description": "Teléfono E.164.",
                    "example": "+51987654321",
                    "type": "string"
                  },
                  "merchant_id": {
                    "description": "Opcional. Si se envía debe coincidir con el merchant de la key.",
                    "example": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "type": "string"
                  },
                  "metadata": {
                    "description": "Pares string→string libres.",
                    "type": "object",
                    "additionalProperties": true
                  }
                },
                "required": [
                  "type"
                ]
              },
              "example": {
                "type": "INDIVIDUAL",
                "external_id": "cust_erp_4821",
                "first_name": "María",
                "last_name": "López",
                "document": {
                  "country": "PE",
                  "type": "DNI",
                  "value": "45678912"
                },
                "email": "maria@example.com",
                "phone": "+51987654321"
              }
            }
          }
        }
      }
    },
    "/customers/{id}": {
      "delete": {
        "operationId": "delete-customer",
        "summary": "Borrar cliente",
        "description": "Borra o archiva un customer. Si no tiene cobros se elimina; si tiene, se archiva y desaparece de listados.\n\nSi no tiene cobros: deleted=true, archived=false. Si tiene cobros: deleted=false, archived=true y payment_intents_count > 0 (desaparece de listados; los cobros siguen resolviendo al cliente).",
        "tags": [
          "Customers"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "deleted": true,
                  "archived": false,
                  "payment_intents_count": 0
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "No encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "The requested customer does not exist.",
                  "error": {
                    "code": "CUSTOMER_NOT_FOUND",
                    "message": "The requested customer does not exist.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "doc_url": "https://docs.kuti.pe/errors/CUSTOMER_NOT_FOUND"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "An unexpected error occurred.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "An unexpected error occurred.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id del customer en el path.",
            "schema": {
              "type": "string",
              "example": "cus_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
            }
          }
        ]
      },
      "get": {
        "operationId": "get-customer",
        "summary": "Detalle de cliente",
        "description": "Obtiene un customer por id (cus_…). Incluye payment_intents_count.\n\nSolo puedes leer clientes de tu merchant (el de la API key).",
        "tags": [
          "Customers"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "cus_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "merchant_id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "external_id": "cust_erp_4821",
                    "type": "INDIVIDUAL",
                    "first_name": "María",
                    "last_name": "López",
                    "document": {
                      "country": "PE",
                      "type": "DNI",
                      "value": "45678912"
                    },
                    "email": "maria@example.com",
                    "phone": "+51987654321",
                    "payment_intents_count": 3,
                    "created_at": "2026-09-04T10:48:59.556906Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "No encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "The requested customer does not exist.",
                  "error": {
                    "code": "CUSTOMER_NOT_FOUND",
                    "message": "The requested customer does not exist.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "doc_url": "https://docs.kuti.pe/errors/CUSTOMER_NOT_FOUND"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "An unexpected error occurred.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "An unexpected error occurred.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id del customer en el path.",
            "schema": {
              "type": "string",
              "example": "cus_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
            }
          }
        ]
      },
      "patch": {
        "operationId": "patch-customer",
        "summary": "Editar cliente",
        "description": "Edita nombre, razón social, correo o teléfono. Solo los campos enviados se modifican.\n\nEl tipo (INDIVIDUAL/COMPANY) y el documento no se pueden cambiar. Enviar \"\" borra el valor.",
        "tags": [
          "Customers"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "message": "Customer updated",
                  "data": {
                    "id": "cus_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "merchant_id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "external_id": "cust_erp_4821",
                    "type": "INDIVIDUAL",
                    "first_name": "María",
                    "last_name": "López Torres",
                    "document": {
                      "country": "PE",
                      "type": "DNI",
                      "value": "45678912"
                    },
                    "email": "maria.lopez@example.com",
                    "phone": "+51987654321",
                    "created_at": "2026-09-04T10:48:59.556906Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "No encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "The requested customer does not exist.",
                  "error": {
                    "code": "CUSTOMER_NOT_FOUND",
                    "message": "The requested customer does not exist.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "doc_url": "https://docs.kuti.pe/errors/CUSTOMER_NOT_FOUND"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Validación",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Validation failed.",
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Validation failed.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "details": [
                      {
                        "field": "email",
                        "code": "INVALID_FORMAT",
                        "message": "Must be a valid email address."
                      }
                    ]
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "An unexpected error occurred.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "An unexpected error occurred.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id del customer en el path.",
            "schema": {
              "type": "string",
              "example": "cus_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Id del customer en el path.",
                    "example": "cus_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "type": "string"
                  },
                  "first_name": {
                    "description": "Nombres.",
                    "example": "María",
                    "type": "string"
                  },
                  "last_name": {
                    "description": "Apellidos.",
                    "example": "López Torres",
                    "type": "string"
                  },
                  "company_name": {
                    "description": "Razón social (COMPANY).",
                    "type": "string"
                  },
                  "email": {
                    "description": "Correo.",
                    "example": "maria.lopez@example.com",
                    "type": "string"
                  },
                  "phone": {
                    "description": "Teléfono E.164.",
                    "example": "+51987654321",
                    "type": "string"
                  }
                },
                "required": [
                  "id"
                ]
              },
              "example": {
                "last_name": "López Torres",
                "email": "maria.lopez@example.com",
                "phone": "+51987654321"
              }
            }
          }
        }
      }
    },
    "/events": {
      "get": {
        "operationId": "get-events",
        "summary": "Listar eventos",
        "description": "Lista los eventos de tu negocio. Del más reciente al más antiguo. Mismo modo (test/live) que tu API key.\n\nFiltra por type (p. ej. payment.succeeded). Útil para reconciliar o depurar entregas.",
        "tags": [
          "Events"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "evt_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "type": "payment.succeeded",
                      "merchant_id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "created_at": "2026-09-04T10:48:59.556906Z",
                      "data": {
                        "payment_intent": {
                          "id": "pi_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                          "merchant_id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                          "amount": {
                            "amount": "50.00",
                            "currency": "PEN"
                          },
                          "status": "SUCCEEDED",
                          "description": "Pedido #1042",
                          "customer": {
                            "id": "cus_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                            "type": "INDIVIDUAL",
                            "first_name": "María",
                            "last_name": "López",
                            "name": "María López",
                            "document_type": "DNI",
                            "document_value": "45678912",
                            "email": "maria@example.com"
                          }
                        }
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "per_page": 25,
                    "total": 1,
                    "total_pages": 1,
                    "has_more": false
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Tipo de evento.",
            "schema": {
              "description": "Tipo de evento.",
              "example": "payment.succeeded",
              "type": "string"
            },
            "example": "payment.succeeded"
          },
          {
            "name": "aggregate_id",
            "in": "query",
            "required": false,
            "description": "Solo eventos de ese recurso (p. ej. pi_… o cus_…).",
            "schema": {
              "description": "Solo eventos de ese recurso (p. ej. pi_… o cus_…).",
              "example": "pi_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
              "type": "string"
            },
            "example": "pi_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Página (1-based).",
            "schema": {
              "description": "Página (1-based).",
              "example": 1,
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "description": "Elementos por página (1–100) o all.",
            "schema": {
              "description": "Elementos por página (1–100) o all.",
              "example": 25,
              "type": "string"
            },
            "example": 25
          }
        ]
      }
    },
    "/events/{id}": {
      "get": {
        "operationId": "get-event",
        "summary": "Detalle del evento",
        "description": "Obtiene un evento por id (evt_…). Misma forma que el body del webhook. Payloads de cada tipo: guía Webhooks → Cómo funcionan.",
        "tags": [
          "Events"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "evt_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "type": "payment.succeeded",
                    "merchant_id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "created_at": "2026-09-04T10:48:59.556906Z",
                    "data": {
                      "payment_intent": {
                        "id": "pi_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                        "merchant_id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                        "amount": {
                          "amount": "50.00",
                          "currency": "PEN"
                        },
                        "status": "SUCCEEDED",
                        "description": "Pedido #1042",
                        "customer": {
                          "id": "cus_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                          "type": "INDIVIDUAL",
                          "first_name": "María",
                          "last_name": "López",
                          "name": "María López",
                          "document_type": "DNI",
                          "document_value": "45678912",
                          "email": "maria@example.com"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "No encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "The requested event does not exist.",
                  "error": {
                    "code": "EVENT_NOT_FOUND",
                    "message": "The requested event does not exist.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id del evento.",
            "schema": {
              "type": "string",
              "example": "evt_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
            }
          }
        ]
      }
    },
    "/events/{id}/deliveries": {
      "get": {
        "operationId": "get-event-deliveries",
        "summary": "Entregas de un evento",
        "description": "Lista los intentos de entrega de un evento a tus webhooks (éxito, fallo, reintentos).\n\nstatus de entrega: PENDING, SUCCEEDED, FAILED, DEAD. attempt_history va del más reciente al más antiguo.",
        "tags": [
          "Events"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "whd_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "event_id": "evt_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "webhook_endpoint_id": "we_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "endpoint_url": "https://merchant.example.com/webhooks/kuti",
                      "status": "SUCCEEDED",
                      "attempts": 1,
                      "last_http_status": 200,
                      "delivered_at": "2026-09-04T10:49:01.100000Z",
                      "attempt_history": [
                        {
                          "id": "wda_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                          "attempt_number": 1,
                          "attempted_at": "2026-09-04T10:49:01.100000Z",
                          "ok": true,
                          "http_status": 200
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "No encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "The requested event does not exist.",
                  "error": {
                    "code": "EVENT_NOT_FOUND",
                    "message": "The requested event does not exist.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id del evento (evt_…).",
            "schema": {
              "type": "string",
              "example": "evt_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
            }
          }
        ]
      }
    },
    "/fee-preview": {
      "get": {
        "operationId": "get-fee-preview",
        "summary": "Cotizar comisión",
        "description": "Estima la comisión de un cobro sin crearlo: tu cliente paga X, tú recibes Y.\n\nNo persiste nada. Usa el plan de comisiones vigente del negocio. fee es negativa (IGV incluido).",
        "tags": [
          "Fee Preview"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": {
                    "gross": {
                      "amount": "100.00",
                      "currency": "PEN"
                    },
                    "fee": {
                      "amount": "-3.54",
                      "currency": "PEN"
                    },
                    "fee_tax": {
                      "amount": "-0.54",
                      "currency": "PEN"
                    },
                    "net": {
                      "amount": "96.46",
                      "currency": "PEN"
                    },
                    "available_in_days": 2
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Validación",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Validation failed.",
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Validation failed.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "details": [
                      {
                        "field": "amount",
                        "code": "REQUIRED",
                        "message": "amount is required."
                      }
                    ]
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "amount",
            "in": "query",
            "required": true,
            "description": "Monto bruto (decimal como string).",
            "schema": {
              "description": "Monto bruto (decimal como string).",
              "example": 100,
              "type": "string"
            },
            "example": 100
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "Solo PEN por ahora. Default PEN.",
            "schema": {
              "description": "Solo PEN por ahora. Default PEN.",
              "example": "PEN",
              "type": "string"
            },
            "example": "PEN"
          },
          {
            "name": "payment_method",
            "in": "query",
            "required": false,
            "description": "INTEROPERABLE_QR o BANK_TRANSFER. Si se omite, tarifa base del plan.",
            "schema": {
              "description": "INTEROPERABLE_QR o BANK_TRANSFER. Si se omite, tarifa base del plan.",
              "type": "string"
            }
          }
        ]
      }
    },
    "/merchants": {
      "get": {
        "operationId": "get-merchants",
        "summary": "Listar negocios",
        "description": "Lista merchants con paginación por offset. Del más reciente al más antiguo según el orden del servidor.\n\nper_page acepta un entero 1–100 o el literal all para traer todos en una sola página (total_pages = 1).",
        "tags": [
          "Merchants"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "legal_name": "Cafetería Andina S.A.C.",
                      "trade_name": "Café Andina",
                      "tax_id": {
                        "country": "PE",
                        "type": "RUC",
                        "value": "20123456789"
                      },
                      "country": "PE",
                      "default_currency": "PEN",
                      "email": "pagos@cafeandina.pe",
                      "phone": "+51999999999",
                      "status": "ACTIVE",
                      "created_at": "2026-09-04T10:48:59.556906Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "per_page": 25,
                    "total": 1,
                    "total_pages": 1,
                    "has_more": false
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "An unexpected error occurred.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "An unexpected error occurred.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Página (1-based).",
            "schema": {
              "description": "Página (1-based).",
              "example": 1,
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "description": "Elementos por página (1–100) o all.",
            "schema": {
              "description": "Elementos por página (1–100) o all.",
              "example": 25,
              "type": "string"
            },
            "example": 25
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Busca por razón social, nombre comercial o RUC (coincidencia parcial).",
            "schema": {
              "description": "Busca por razón social, nombre comercial o RUC (coincidencia parcial).",
              "type": "string"
            }
          }
        ]
      },
      "post": {
        "operationId": "post-merchants",
        "summary": "Crear negocio",
        "description": "Crea un merchant a partir de un RUC. La razón social, el país (PE), la moneda (PEN) y la dirección fiscal se consultan en SUNAT y no se envían en el body.\n\nSolo tax_id.value es obligatorio. No envíes legal_name, country, address ni default_currency: salen de SUNAT. Si el RUC no existe, responde 422. Puedes enviar Idempotency-Key (UUID v4) para reintentos seguros.",
        "tags": [
          "Merchants"
        ],
        "responses": {
          "201": {
            "description": "201",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "message": "Merchant created",
                  "data": {
                    "id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "legal_name": "Cafetería Andina S.A.C.",
                    "trade_name": "Café Andina",
                    "tax_id": {
                      "country": "PE",
                      "type": "RUC",
                      "value": "20123456789"
                    },
                    "country": "PE",
                    "default_currency": "PEN",
                    "email": "pagos@cafeandina.pe",
                    "phone": "+51999999999",
                    "status": "ACTIVE",
                    "address": {
                      "line": "AV. AREQUIPA NRO. 123 URB. SANTA BEATRIZ",
                      "district": "LIMA",
                      "province": "LIMA",
                      "region": "LIMA",
                      "ubigeo": "150101"
                    },
                    "created_at": "2026-09-04T10:48:59.556906Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "409": {
            "description": "RUC ya registrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "A merchant with this tax id already exists",
                  "error": {
                    "code": "MERCHANT_ALREADY_EXISTS",
                    "message": "A merchant with this tax id already exists",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Formato de RUC inválido",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "El RUC debe tener 11 dígitos y empezar en 10, 15, 17 o 20.",
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "El RUC debe tener 11 dígitos y empezar en 10, 15, 17 o 20.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "details": [
                      {
                        "field": "tax_id.value",
                        "code": "INVALID",
                        "message": "El RUC debe tener 11 dígitos y empezar en 10, 15, 17 o 20."
                      }
                    ]
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "An unexpected error occurred.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "An unexpected error occurred.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tax_id": {
                    "description": "RUC del negocio. País y tipo se fijan a PE / RUC.",
                    "type": "object",
                    "properties": {
                      "value": {
                        "description": "RUC peruano de 11 dígitos (empieza en 10, 15, 17 o 20).",
                        "example": 20123456789,
                        "type": "string"
                      }
                    },
                    "required": [
                      "value"
                    ]
                  },
                  "trade_name": {
                    "description": "Nombre comercial.",
                    "example": "Café Andina",
                    "type": "string"
                  },
                  "email": {
                    "description": "Correo de contacto.",
                    "example": "pagos@cafeandina.pe",
                    "type": "string"
                  },
                  "phone": {
                    "description": "Teléfono E.164.",
                    "example": "+51999999999",
                    "type": "string"
                  }
                },
                "required": [
                  "tax_id"
                ]
              },
              "example": {
                "tax_id": {
                  "value": "20123456789"
                },
                "trade_name": "Café Andina",
                "email": "pagos@cafeandina.pe",
                "phone": "+51999999999"
              }
            }
          }
        }
      }
    },
    "/merchants/{id}": {
      "get": {
        "operationId": "get-merchant",
        "summary": "Detalle de negocio",
        "description": "Obtiene un merchant por id. Solo puedes leer el negocio asociado a tu API key.\n\nEl id tiene el formato mer_… (p. ej. mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3).",
        "tags": [
          "Merchants"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "legal_name": "Cafetería Andina S.A.C.",
                    "trade_name": "Café Andina",
                    "tax_id": {
                      "country": "PE",
                      "type": "RUC",
                      "value": "20123456789"
                    },
                    "country": "PE",
                    "default_currency": "PEN",
                    "email": "pagos@cafeandina.pe",
                    "phone": "+51999999999",
                    "status": "ACTIVE",
                    "address": {
                      "line": "AV. AREQUIPA NRO. 123 URB. SANTA BEATRIZ",
                      "district": "LIMA",
                      "province": "LIMA",
                      "region": "LIMA",
                      "ubigeo": "150101"
                    },
                    "created_at": "2026-09-04T10:48:59.556906Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "No encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "The requested merchant does not exist.",
                  "error": {
                    "code": "MERCHANT_NOT_FOUND",
                    "message": "The requested merchant does not exist.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "doc_url": "https://docs.kuti.pe/errors/MERCHANT_NOT_FOUND"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "An unexpected error occurred.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "An unexpected error occurred.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id del merchant en el path.",
            "schema": {
              "type": "string",
              "example": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
            }
          }
        ]
      },
      "patch": {
        "operationId": "patch-merchant",
        "summary": "Editar negocio",
        "description": "Edita datos del negocio: razón social, nombre comercial, contacto y dirección. Solo los campos enviados se modifican.\n\nEl RUC, el país y la moneda no se pueden cambiar. Enviar \"\" borra el valor (excepto legal_name).",
        "tags": [
          "Merchants"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "message": "Merchant updated",
                  "data": {
                    "id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "legal_name": "Cafetería Andina S.A.C.",
                    "trade_name": "Café Andina Miraflores",
                    "tax_id": {
                      "country": "PE",
                      "type": "RUC",
                      "value": "20123456789"
                    },
                    "country": "PE",
                    "default_currency": "PEN",
                    "email": "hola@cafeandina.pe",
                    "phone": "+51987654321",
                    "status": "ACTIVE",
                    "created_at": "2026-09-04T10:48:59.556906Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No autorizado"
          },
          "403": {
            "description": "Sin permiso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "You cannot act on behalf of another merchant",
                  "error": {
                    "code": "FORBIDDEN_MERCHANT_ACCESS",
                    "message": "You cannot act on behalf of another merchant",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "No encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "The requested merchant does not exist.",
                  "error": {
                    "code": "MERCHANT_NOT_FOUND",
                    "message": "The requested merchant does not exist.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "doc_url": "https://docs.kuti.pe/errors/MERCHANT_NOT_FOUND"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Validación",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Validation failed.",
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Validation failed.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "details": [
                      {
                        "field": "email",
                        "code": "INVALID_FORMAT",
                        "message": "Must be a valid email address."
                      }
                    ]
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "An unexpected error occurred.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "An unexpected error occurred.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id del merchant en el path.",
            "schema": {
              "type": "string",
              "example": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Id del merchant en el path.",
                    "example": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "type": "string"
                  },
                  "legal_name": {
                    "description": "Razón social.",
                    "type": "string"
                  },
                  "trade_name": {
                    "description": "Nombre comercial.",
                    "type": "string"
                  },
                  "email": {
                    "description": "Correo de contacto.",
                    "example": "pagos@cafeandina.pe",
                    "type": "string"
                  },
                  "phone": {
                    "description": "Teléfono E.164.",
                    "example": "+51987654321",
                    "type": "string"
                  },
                  "address": {
                    "description": "Dirección fiscal.",
                    "type": "object",
                    "properties": {
                      "line": {
                        "description": "Calle y número.",
                        "type": "string"
                      },
                      "district": {
                        "description": "Distrito.",
                        "type": "string"
                      },
                      "province": {
                        "description": "Provincia.",
                        "type": "string"
                      },
                      "region": {
                        "description": "Región / departamento.",
                        "type": "string"
                      },
                      "ubigeo": {
                        "description": "Código ubigeo.",
                        "type": "string"
                      }
                    }
                  }
                },
                "required": [
                  "id"
                ]
              },
              "example": {
                "trade_name": "Café Andina Miraflores",
                "phone": "+51987654321",
                "email": "hola@cafeandina.pe"
              }
            }
          }
        }
      }
    },
    "/payment-intents": {
      "get": {
        "operationId": "get-payment-intents",
        "summary": "Listar cobros",
        "description": "Lista los payment intents (cobros) del merchant autenticado. Del más reciente al más antiguo.\n\nstatus: REQUIRES_PAYMENT_METHOD, PENDING, PROCESSING, SUCCEEDED, FAILED, CANCELLED, EXPIRED. El modo (test/live) lo define tu API key.",
        "tags": [
          "Payment Intents"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "pi_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "merchant_id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "livemode": true,
                      "customer": {
                        "id": "cus_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                        "type": "INDIVIDUAL",
                        "first_name": "María",
                        "last_name": "López",
                        "name": "María López"
                      },
                      "amount": {
                        "amount": "50.00",
                        "currency": "PEN"
                      },
                      "status": "PENDING",
                      "payment_method_types": [
                        "INTEROPERABLE_QR"
                      ],
                      "checkout_url": "https://pay.kuti.pe/c/A3F9K2P7QM",
                      "description": "Pedido #1042",
                      "created_at": "2026-09-04T10:48:59.556906Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "per_page": 25,
                    "total": 1,
                    "total_pages": 1,
                    "has_more": false
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filtra por estado del cobro.",
            "schema": {
              "description": "Filtra por estado del cobro.",
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Busca por cliente: nombre, documento, correo o teléfono.",
            "schema": {
              "description": "Busca por cliente: nombre, documento, correo o teléfono.",
              "type": "string"
            }
          },
          {
            "name": "customer_id",
            "in": "query",
            "required": false,
            "description": "Solo cobros de este cliente (cus_…).",
            "schema": {
              "description": "Solo cobros de este cliente (cus_…).",
              "type": "string"
            }
          },
          {
            "name": "created_from",
            "in": "query",
            "required": false,
            "description": "Desde (UTC ISO-8601), inclusive.",
            "schema": {
              "description": "Desde (UTC ISO-8601), inclusive.",
              "example": "2026-09-01T00:00:00Z",
              "type": "string"
            },
            "example": "2026-09-01T00:00:00Z"
          },
          {
            "name": "created_to",
            "in": "query",
            "required": false,
            "description": "Hasta (UTC ISO-8601), inclusive.",
            "schema": {
              "description": "Hasta (UTC ISO-8601), inclusive.",
              "example": "2026-09-30T23:59:59Z",
              "type": "string"
            },
            "example": "2026-09-30T23:59:59Z"
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Página (1-based).",
            "schema": {
              "description": "Página (1-based).",
              "example": 1,
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "description": "Elementos por página (1–100) o all.",
            "schema": {
              "description": "Elementos por página (1–100) o all.",
              "example": 25,
              "type": "string"
            },
            "example": 25
          }
        ]
      },
      "post": {
        "operationId": "post-payment-intents",
        "summary": "Crear cobro",
        "description": "Crea un Payment Intent que representa un cobro único por un monto determinado. Puedes indicar qué métodos de pago estarán disponibles para el pagador. KUTI devuelve los datos necesarios para cada método habilitado y un único checkout_url.\n\nSolo PEN · amount como string · en banca: institución KUTI. Preferí customer.id; si no, type + datos. Idempotency-Key recomendada.",
        "tags": [
          "Payment Intents"
        ],
        "responses": {
          "201": {
            "description": "201",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "message": "Payment intent created",
                  "data": {
                    "id": "pi_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "merchant_id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "livemode": true,
                    "customer": {
                      "id": "cus_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "type": "INDIVIDUAL",
                      "first_name": "María",
                      "last_name": "López",
                      "name": "María López",
                      "document_type": "DNI",
                      "document_value": "45678912",
                      "email": "maria@example.com"
                    },
                    "amount": {
                      "amount": "50.00",
                      "currency": "PEN"
                    },
                    "status": "PENDING",
                    "payment_method_types": [
                      "INTEROPERABLE_QR",
                      "BANK_TRANSFER"
                    ],
                    "payment_method": {
                      "qr": {
                        "type": "INTEROPERABLE_QR",
                        "payload": "00020101021226...",
                        "expires_at": "2026-09-05T23:59:59Z"
                      },
                      "payment_code": {
                        "type": "BANK_TRANSFER",
                        "code": "41041172",
                        "expires_at": "2026-09-05T23:59:59Z"
                      }
                    },
                    "checkout_url": "https://pay.kuti.pe/c/A3F9K2P7QM",
                    "client_secret": "pi_01J8…_secret_ab12cd34ef56gh78ij90kl12",
                    "description": "Pedido #1042",
                    "external_reference": "order-1042",
                    "fee_preview": {
                      "gross": {
                        "amount": "50.00",
                        "currency": "PEN"
                      },
                      "fee": {
                        "amount": "-1.77",
                        "currency": "PEN"
                      },
                      "fee_tax": {
                        "amount": "-0.27",
                        "currency": "PEN"
                      },
                      "net": {
                        "amount": "48.23",
                        "currency": "PEN"
                      },
                      "available_in_days": 2
                    },
                    "created_at": "2026-09-04T10:48:59.556906Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Validación",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Validation failed.",
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Validation failed.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "details": [
                      {
                        "field": "payment_method_types",
                        "code": "REQUIRED",
                        "message": "payment_method_types is required."
                      }
                    ]
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount": {
                    "description": "Monto a cobrar.",
                    "type": "object",
                    "properties": {
                      "amount": {
                        "description": "Decimal como string.",
                        "example": 50,
                        "type": "string"
                      },
                      "currency": {
                        "description": "Solo PEN por ahora.",
                        "example": "PEN",
                        "type": "string"
                      }
                    },
                    "required": [
                      "amount",
                      "currency"
                    ]
                  },
                  "payment_method_types": {
                    "description": "INTEROPERABLE_QR (Yape/Plin/billeteras) y/o BANK_TRANSFER (pago de servicios → institución KUTI).",
                    "example": [
                      "INTEROPERABLE_QR",
                      "BANK_TRANSFER"
                    ],
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "customer": {
                    "description": "Cliente del cobro (objeto). Orden: id (existente) → external_id → documento → crea uno nuevo. Si envías id, se ignora el resto.",
                    "type": "object",
                    "properties": {
                      "id": {
                        "description": "Customer existente (cus_…). Si viene, se ignora el resto.",
                        "example": "cus_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                        "type": "string"
                      },
                      "type": {
                        "description": "INDIVIDUAL (persona) o COMPANY (empresa). Obligatorio al crear uno nuevo.",
                        "example": "INDIVIDUAL",
                        "type": "string"
                      },
                      "given_name": {
                        "description": "Nombres. Requerido si type = INDIVIDUAL.",
                        "example": "María",
                        "type": "string"
                      },
                      "family_name": {
                        "description": "Apellidos. Requerido si type = INDIVIDUAL.",
                        "example": "López",
                        "type": "string"
                      },
                      "legal_name": {
                        "description": "Razón social. Requerido si type = COMPANY.",
                        "type": "string"
                      },
                      "email": {
                        "description": "Correo.",
                        "example": "maria@example.com",
                        "type": "string"
                      },
                      "phone": {
                        "description": "Teléfono E.164.",
                        "example": "+51987654321",
                        "type": "string"
                      },
                      "external_id": {
                        "description": "Id en tu sistema. Si ya existe un customer con ese external_id, se reutiliza.",
                        "example": "cust_erp_4821",
                        "type": "string"
                      },
                      "document": {
                        "description": "Documento.",
                        "type": "object",
                        "properties": {
                          "type": {
                            "description": "DNI, RUC, CE, …",
                            "example": "DNI",
                            "type": "string"
                          },
                          "number": {
                            "description": "Número.",
                            "example": 45678912,
                            "type": "string"
                          }
                        }
                      }
                    }
                  },
                  "receivable_id": {
                    "description": "Cuenta por cobrar (rcv_…) a la que se imputa este cobro.",
                    "example": "rcv_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "type": "string"
                  },
                  "category_id": {
                    "description": "Categoría de cobro opcional (collection-categories).",
                    "type": "string"
                  },
                  "requires_customer_info": {
                    "description": "Si true y no hay customer: el checkout pide nombre/correo al pagador antes de pagar. Default false.",
                    "type": "boolean"
                  },
                  "description": {
                    "description": "Texto del cobro.",
                    "example": "Pedido #1042",
                    "type": "string"
                  },
                  "external_reference": {
                    "description": "Referencia en tu sistema.",
                    "example": "order-1042",
                    "type": "string"
                  },
                  "expires_at": {
                    "description": "Vencimiento del cobro (UTC ISO-8601).",
                    "example": "2026-09-05T23:59:59Z",
                    "type": "string"
                  },
                  "merchant_id": {
                    "description": "Opcional. Debe coincidir con el merchant de la key.",
                    "type": "string"
                  },
                  "metadata": {
                    "description": "Pares string→string libres.",
                    "type": "object",
                    "additionalProperties": true
                  }
                },
                "required": [
                  "amount",
                  "payment_method_types"
                ]
              },
              "example": {
                "amount": {
                  "amount": "50.00",
                  "currency": "PEN"
                },
                "payment_method_types": [
                  "INTEROPERABLE_QR",
                  "BANK_TRANSFER"
                ],
                "customer": {
                  "type": "INDIVIDUAL",
                  "given_name": "María",
                  "family_name": "López",
                  "email": "maria@example.com",
                  "phone": "+51987654321",
                  "document": {
                    "type": "DNI",
                    "number": "45678912"
                  }
                },
                "description": "Pedido #1042",
                "external_reference": "order-1042"
              }
            }
          }
        }
      }
    },
    "/payment-intents/{id}": {
      "get": {
        "operationId": "get-payment-intent",
        "summary": "Detalle del cobro",
        "description": "Obtiene un payment intent por id. Incluye datos para pagar, fee_preview y, si ya fue pagado, paid_with + settlement.\n\nclient_secret permite operar el cobro desde el frontend (Checkout.js) sin exponer tu secret key. Si status=SUCCEEDED, usa paid_with (no payment_method) para mostrar cómo se pagó.",
        "tags": [
          "Payment Intents"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "pi_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "merchant_id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "livemode": true,
                    "customer": {
                      "id": "cus_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "type": "INDIVIDUAL",
                      "first_name": "María",
                      "last_name": "López",
                      "name": "María López",
                      "document_type": "DNI",
                      "document_value": "45678912",
                      "email": "maria@example.com"
                    },
                    "category_id": null,
                    "amount": {
                      "amount": "50.00",
                      "currency": "PEN"
                    },
                    "status": "SUCCEEDED",
                    "payment_method_types": [
                      "INTEROPERABLE_QR",
                      "BANK_TRANSFER"
                    ],
                    "paid_with": {
                      "method_type": "INTEROPERABLE_QR",
                      "paid_at": "2026-09-04T10:55:12.000Z"
                    },
                    "payment_id": "pay_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "checkout_url": "https://pay.kuti.pe/c/A3F9K2P7QM",
                    "client_secret": "pi_01J8…_secret_ab12cd34ef56gh78ij90kl12",
                    "description": "Pedido #1042",
                    "external_reference": "order-1042",
                    "requires_customer_info": false,
                    "fee_preview": {
                      "gross": {
                        "amount": "50.00",
                        "currency": "PEN"
                      },
                      "fee": {
                        "amount": "-1.77",
                        "currency": "PEN"
                      },
                      "fee_tax": {
                        "amount": "-0.27",
                        "currency": "PEN"
                      },
                      "net": {
                        "amount": "48.23",
                        "currency": "PEN"
                      },
                      "available_in_days": 2
                    },
                    "settlement": {
                      "balance_transaction_id": "btxn_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "status": "AVAILABLE",
                      "gross": {
                        "amount": "50.00",
                        "currency": "PEN"
                      },
                      "fee": {
                        "amount": "-1.77",
                        "currency": "PEN"
                      },
                      "fee_tax": {
                        "amount": "-0.27",
                        "currency": "PEN"
                      },
                      "net": {
                        "amount": "48.23",
                        "currency": "PEN"
                      },
                      "available_on": "2026-09-06T00:00:00Z",
                      "available_confirmed": true,
                      "payout_id": "pyt_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                    },
                    "created_at": "2026-09-04T10:48:59.556906Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "No encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "The requested payment intent does not exist.",
                  "error": {
                    "code": "PAYMENT_INTENT_NOT_FOUND",
                    "message": "The requested payment intent does not exist.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id del cobro en el path (pi_…).",
            "schema": {
              "type": "string",
              "example": "pi_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
            }
          }
        ]
      }
    },
    "/payment-intents/{id}/cancel": {
      "post": {
        "operationId": "post-payment-intent-cancel",
        "summary": "Anular cobro",
        "description": "Cancela un payment intent. Pasa a status CANCELLED.\n\nSi el cobro ya está pagado, procesando o en un estado que no admite anulación, responde 409.",
        "tags": [
          "Payment Intents"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "message": "Payment intent cancelled",
                  "data": {
                    "id": "pi_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "merchant_id": "mer_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "livemode": true,
                    "customer": {
                      "id": "cus_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "type": "INDIVIDUAL",
                      "first_name": "María",
                      "last_name": "López",
                      "name": "María López"
                    },
                    "amount": {
                      "amount": "50.00",
                      "currency": "PEN"
                    },
                    "status": "CANCELLED",
                    "payment_method_types": [
                      "INTEROPERABLE_QR"
                    ],
                    "description": "Pedido #1042",
                    "created_at": "2026-09-04T10:48:59.556906Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "No encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "The requested payment intent does not exist.",
                  "error": {
                    "code": "PAYMENT_INTENT_NOT_FOUND",
                    "message": "The requested payment intent does not exist.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "409": {
            "description": "No se puede anular",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Payment intent cannot be cancelled in its current status.",
                  "error": {
                    "code": "CONFLICT",
                    "message": "Payment intent cannot be cancelled in its current status.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id del cobro en el path (pi_…).",
            "schema": {
              "type": "string",
              "example": "pi_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Id del cobro en el path (pi_…).",
                    "example": "pi_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "type": "string"
                  }
                },
                "required": [
                  "id"
                ]
              }
            }
          }
        }
      }
    },
    "/payment-intents/{id}/send-whatsapp": {
      "post": {
        "operationId": "post-payment-intent-send-whatsapp",
        "summary": "Enviar link por WhatsApp",
        "description": "Envía el link de pago del cobro por WhatsApp (plantilla fija). Responde 204 si se envió.\n\nEste envío consume 1 moneda de tu saldo WhatsApp. Si el cobro no tiene cliente con teléfono, phone es obligatorio. customer_name personaliza el mensaje.",
        "tags": [
          "Payment Intents"
        ],
        "responses": {
          "204": {
            "description": "204",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "message": "No content (204)"
                }
              }
            }
          },
          "401": {
            "description": "No autorizado"
          },
          "404": {
            "description": "Cobro no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "The requested payment intent does not exist.",
                  "error": {
                    "code": "PAYMENT_INTENT_NOT_FOUND",
                    "message": "The requested payment intent does not exist.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Sin monedas WhatsApp",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "No tienes monedas de WhatsApp. Compra un pack o pide créditos a soporte.",
                  "error": {
                    "code": "WHATSAPP_CREDITS_INSUFFICIENT",
                    "message": "No tienes monedas de WhatsApp. Compra un pack o pide créditos a soporte.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Falta teléfono",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Validation failed.",
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Validation failed.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "details": [
                      {
                        "field": "phone",
                        "code": "REQUIRED",
                        "message": "phone is required when the customer has no phone."
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id del cobro en el path (pi_…).",
            "schema": {
              "type": "string",
              "example": "pi_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Id del cobro en el path (pi_…).",
                    "example": "pi_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "type": "string"
                  },
                  "phone": {
                    "description": "E.164. Obligatorio si el cobro no tiene cliente con teléfono.",
                    "example": "+51987654321",
                    "type": "string"
                  },
                  "customer_name": {
                    "description": "Nombre para el mensaje. Opcional.",
                    "example": "Ana Torres",
                    "type": "string"
                  }
                },
                "required": [
                  "id"
                ]
              },
              "example": {
                "phone": "+51987654321",
                "customer_name": "Ana Torres"
              }
            }
          }
        }
      }
    },
    "/payout-accounts": {
      "get": {
        "operationId": "get-payout-accounts",
        "summary": "Listar cuentas bancarias",
        "description": "Lista las cuentas de liquidación (destino de los pagos a tu cuenta) del modo actual.",
        "tags": [
          "Payout Accounts"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "pacc_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "bank_code": "BCP",
                      "account_type": "CHECKING",
                      "currency": "PEN",
                      "cci_masked": "••••1234",
                      "holder_name": "ZIZEHOST S.A.C.",
                      "holder_doc_type": "RUC",
                      "holder_doc_num": "20123456789",
                      "is_default": true,
                      "status": "ACTIVE",
                      "created_at": "2026-09-01T12:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      },
      "post": {
        "operationId": "post-payout-accounts",
        "summary": "Registrar cuenta bancaria",
        "description": "Registra una cuenta bancaria de liquidación. El titular lo toma KUTI del negocio (razón social + RUC).\n\ncci debe ser 20 dígitos. account_type: CHECKING o SAVINGS.",
        "tags": [
          "Payout Accounts"
        ],
        "responses": {
          "201": {
            "description": "201",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "message": "Payout account created",
                  "data": {
                    "id": "pacc_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "bank_code": "BCP",
                    "account_type": "CHECKING",
                    "currency": "PEN",
                    "cci_masked": "••••4567",
                    "holder_name": "ZIZEHOST S.A.C.",
                    "holder_doc_type": "RUC",
                    "holder_doc_num": "20123456789",
                    "is_default": true,
                    "status": "ACTIVE",
                    "created_at": "2026-09-04T10:48:59.556906Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Validación",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Validation failed.",
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Validation failed.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "details": [
                      {
                        "field": "cci",
                        "code": "INVALID_FORMAT",
                        "message": "cci must be 20 digits."
                      }
                    ]
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "bank_code": {
                    "description": "Código del banco.",
                    "example": "BCP",
                    "type": "string"
                  },
                  "account_type": {
                    "description": "CHECKING o SAVINGS.",
                    "example": "CHECKING",
                    "type": "string"
                  },
                  "cci": {
                    "description": "CCI de 20 dígitos.",
                    "example": "00212345678901234567",
                    "type": "string"
                  },
                  "make_default": {
                    "description": "Si true, queda como cuenta predeterminada. Default false.",
                    "type": "boolean"
                  }
                },
                "required": [
                  "bank_code",
                  "account_type",
                  "cci"
                ]
              },
              "example": {
                "bank_code": "BCP",
                "account_type": "CHECKING",
                "cci": "00212345678901234567",
                "make_default": true
              }
            }
          }
        }
      }
    },
    "/payout-settings": {
      "get": {
        "operationId": "get-payout-settings",
        "summary": "Preferencias de liquidación",
        "description": "Consulta el calendario y umbrales de los pagos a tu cuenta.\n\nschedule: PROVIDER (calendario del proveedor), DAILY, WEEKLY o MANUAL.",
        "tags": [
          "Payout Settings"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": {
                    "schedule": "PROVIDER",
                    "weekly_anchor": null,
                    "delay_days": 2,
                    "min_amount": "0.00"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      },
      "put": {
        "operationId": "put-payout-settings",
        "summary": "Actualizar preferencias",
        "description": "Actualiza el calendario y umbrales de liquidación hacia tu cuenta bancaria.",
        "tags": [
          "Payout Settings"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "message": "Payout settings updated",
                  "data": {
                    "schedule": "DAILY",
                    "weekly_anchor": null,
                    "delay_days": 2,
                    "min_amount": "50.00"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Validación",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Validation failed.",
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Validation failed.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "details": [
                      {
                        "field": "schedule",
                        "code": "INVALID",
                        "message": "schedule must be one of PROVIDER, DAILY, WEEKLY, MANUAL."
                      }
                    ]
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "schedule": {
                    "description": "PROVIDER | DAILY | WEEKLY | MANUAL.",
                    "example": "DAILY",
                    "type": "string"
                  },
                  "weekly_anchor": {
                    "description": "Día de la semana si schedule es WEEKLY (1=lunes … 7=domingo).",
                    "example": 1,
                    "type": "integer"
                  },
                  "delay_days": {
                    "description": "Días estimados hasta disponibilidad.",
                    "example": 2,
                    "type": "integer"
                  },
                  "min_amount": {
                    "description": "Monto mínimo para liquidar.",
                    "example": 50,
                    "type": "string"
                  }
                }
              },
              "example": {
                "schedule": "DAILY",
                "delay_days": 2,
                "min_amount": "50.00"
              }
            }
          }
        }
      }
    },
    "/payouts": {
      "get": {
        "operationId": "get-payouts",
        "summary": "Listar pagos a tu cuenta",
        "description": "Lista las transferencias del saldo de KUTI hacia tu cuenta bancaria (payouts).\n\nstatus: PENDING, IN_TRANSIT, PAID, FAILED, CANCELED. Del más reciente al más antiguo.",
        "tags": [
          "Payouts"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "pyt_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "source": "PROVIDER",
                      "amount": {
                        "amount": "1250.50",
                        "currency": "PEN"
                      },
                      "gross_amount": {
                        "amount": "1280.00",
                        "currency": "PEN"
                      },
                      "fee_amount": {
                        "amount": "-29.50",
                        "currency": "PEN"
                      },
                      "destination_bank": "BCP",
                      "destination_account_masked": "••••••••9012",
                      "status": "PAID",
                      "payout_account_id": "pacc_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "arrival_expected_on": "2026-09-05",
                      "initiated_at": "2026-09-04T18:00:00Z",
                      "paid_at": "2026-09-05T10:15:00Z",
                      "created_at": "2026-09-04T18:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "per_page": 25,
                    "total": 1,
                    "total_pages": 1,
                    "has_more": false
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "PENDING | IN_TRANSIT | PAID | FAILED | CANCELED.",
            "schema": {
              "description": "PENDING | IN_TRANSIT | PAID | FAILED | CANCELED.",
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Página (1-based).",
            "schema": {
              "description": "Página (1-based).",
              "example": 1,
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "description": "Elementos por página (1–100) o all.",
            "schema": {
              "description": "Elementos por página (1–100) o all.",
              "example": 25,
              "type": "string"
            },
            "example": 25
          }
        ]
      }
    },
    "/payouts/{id}": {
      "get": {
        "operationId": "get-payout",
        "summary": "Detalle del pago a tu cuenta",
        "description": "Obtiene un payout por id (pyt_…): monto, estado y cuenta destino.",
        "tags": [
          "Payouts"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "pyt_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "source": "PROVIDER",
                    "amount": {
                      "amount": "1250.50",
                      "currency": "PEN"
                    },
                    "gross_amount": {
                      "amount": "1280.00",
                      "currency": "PEN"
                    },
                    "fee_amount": {
                      "amount": "-29.50",
                      "currency": "PEN"
                    },
                    "destination_bank": "BCP",
                    "destination_account_masked": "••••••••9012",
                    "status": "PAID",
                    "payout_account_id": "pacc_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "statement_descriptor": "KUTI",
                    "arrival_expected_on": "2026-09-05",
                    "initiated_at": "2026-09-04T18:00:00Z",
                    "paid_at": "2026-09-05T10:15:00Z",
                    "created_at": "2026-09-04T18:00:00Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "No encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "The requested payout does not exist.",
                  "error": {
                    "code": "PAYOUT_NOT_FOUND",
                    "message": "The requested payout does not exist.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id del payout.",
            "schema": {
              "type": "string",
              "example": "pyt_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
            }
          }
        ]
      }
    },
    "/payouts/{id}/transactions": {
      "get": {
        "operationId": "get-payout-transactions",
        "summary": "Movimientos de un payout",
        "description": "Lista los movimientos del ledger incluidos en un pago a tu cuenta.",
        "tags": [
          "Payouts"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "btxn_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "type": "PAYMENT",
                      "status": "PAID",
                      "currency": "PEN",
                      "source_type": "PAYMENT",
                      "source_id": "pay_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "gross": {
                        "amount": "50.00",
                        "currency": "PEN"
                      },
                      "fee": {
                        "amount": "-1.77",
                        "currency": "PEN"
                      },
                      "fee_tax": {
                        "amount": "-0.27",
                        "currency": "PEN"
                      },
                      "net": {
                        "amount": "48.23",
                        "currency": "PEN"
                      },
                      "payout_id": "pyt_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "created_at": "2026-09-04T10:48:59.556906Z"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "No encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "The requested payout does not exist.",
                  "error": {
                    "code": "PAYOUT_NOT_FOUND",
                    "message": "The requested payout does not exist.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id del payout (pyt_…).",
            "schema": {
              "type": "string",
              "example": "pyt_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
            }
          }
        ]
      }
    },
    "/webhook-deliveries/{id}/retry": {
      "post": {
        "operationId": "post-webhook-delivery-retry",
        "summary": "Reintentar entrega",
        "description": "Reencola una entrega de webhook para envío inmediato.\n\nÚtil si tu endpoint falló y ya lo corregiste. El id es whd_… (no el evt_…).",
        "tags": [
          "Webhook Deliveries"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "message": "Webhook delivery requeued",
                  "data": {
                    "id": "whd_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "event_id": "evt_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "webhook_endpoint_id": "we_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "endpoint_url": "https://merchant.example.com/webhooks/kuti",
                    "status": "PENDING",
                    "attempts": 2,
                    "next_attempt_at": "2026-09-04T11:00:00.000000Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "No encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "The requested webhook delivery does not exist.",
                  "error": {
                    "code": "WEBHOOK_DELIVERY_NOT_FOUND",
                    "message": "The requested webhook delivery does not exist.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id de la entrega (whd_…).",
            "schema": {
              "type": "string",
              "example": "whd_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Id de la entrega (whd_…).",
                    "example": "whd_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "type": "string"
                  }
                },
                "required": [
                  "id"
                ]
              }
            }
          }
        }
      }
    },
    "/webhook-endpoints": {
      "get": {
        "operationId": "get-webhook-endpoints",
        "summary": "Listar endpoints",
        "description": "Lista los webhook endpoints del merchant en el modo de tu API key (test o live).\n\nNo incluye signing_secret (solo se muestra al crear). No mezcla endpoints de test y live.",
        "tags": [
          "Webhook Endpoints"
        ],
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "we_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                      "url": "https://merchant.example.com/webhooks/kuti",
                      "description": "Producción",
                      "enabled_events": [
                        "payment.succeeded",
                        "payment.failed"
                      ],
                      "status": "ENABLED",
                      "livemode": true,
                      "created_at": "2026-09-04T10:48:59.556906Z"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      },
      "post": {
        "operationId": "post-webhook-endpoints",
        "summary": "Crear endpoint",
        "description": "Registra una URL HTTPS para recibir eventos firmados de KUTI.\n\nsigning_secret se devuelve SOLO en esta respuesta. El endpoint queda ligado al modo de tu API key (test o live). events: lista de tipos o [\"*\"] para todos.",
        "tags": [
          "Webhook Endpoints"
        ],
        "responses": {
          "201": {
            "description": "201",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "message": "Webhook endpoint created",
                  "data": {
                    "id": "we_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "url": "https://merchant.example.com/webhooks/kuti",
                    "description": "Producción",
                    "enabled_events": [
                      "payment.succeeded",
                      "payment.failed"
                    ],
                    "status": "ENABLED",
                    "livemode": true,
                    "signing_secret": "whsec_a1b2c3d4e5f6…",
                    "created_at": "2026-09-04T10:48:59.556906Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Validación",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Validation failed.",
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Validation failed.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3",
                    "details": [
                      {
                        "field": "url",
                        "code": "INVALID_FORMAT",
                        "message": "url must be HTTPS."
                      }
                    ]
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "description": "URL HTTPS de tu servidor.",
                    "example": "https://merchant.example.com/webhooks/kuti",
                    "type": "string"
                  },
                  "events": {
                    "description": "Tipos a suscribir, o [\"*\"] para todos.",
                    "example": [
                      "payment.succeeded",
                      "payment.failed"
                    ],
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "description": {
                    "description": "Etiqueta interna.",
                    "example": "Producción",
                    "type": "string"
                  }
                },
                "required": [
                  "url",
                  "events"
                ]
              },
              "example": {
                "url": "https://merchant.example.com/webhooks/kuti",
                "description": "Producción",
                "events": [
                  "payment.succeeded",
                  "payment.failed"
                ]
              }
            }
          }
        }
      }
    },
    "/webhook-endpoints/{id}": {
      "delete": {
        "operationId": "delete-webhook-endpoint",
        "summary": "Eliminar endpoint",
        "description": "Elimina un webhook endpoint. Deja de recibir entregas.\n\nResponde 204 sin body si se eliminó.",
        "tags": [
          "Webhook Endpoints"
        ],
        "responses": {
          "204": {
            "description": "204",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            }
          },
          "401": {
            "description": "Credenciales inválidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Missing or invalid credentials.",
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Missing or invalid credentials.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "No encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "The requested webhook endpoint does not exist.",
                  "error": {
                    "code": "WEBHOOK_ENDPOINT_NOT_FOUND",
                    "message": "The requested webhook endpoint does not exist.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "Internal server error.",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error.",
                    "request_id": "req_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id del endpoint (we_…).",
            "schema": {
              "type": "string",
              "example": "we_01J8Z3K4M5N6P7Q8R9S0T1U2V3"
            }
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API Key",
        "description": "Secret key de developer. En Postman/Insomnia/Bruno usa la variable bearerToken (ejemplo: kuti_live_…). Prueba: kuti_test_… · Producción: kuti_live_…"
      },
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Kuti-Token",
        "description": "API key en header X-Kuti-Token. Ejemplo: kuti_live_…"
      }
    }
  },
  "x-collection-variables": [
    {
      "key": "baseUrl",
      "value": "https://api.kuti.pe/v1"
    },
    {
      "key": "bearerToken",
      "value": "kuti_live_…"
    }
  ]
}