openapi: 3.0.3
info:
  title: Palomma Rentals API
  version: 1.0.0
  description: API for creating and managing rental invoices and settlements.
  contact:
    name: Palomma
servers:
  - url: https://api.palomma.com/v1
    description: Production
  - url: https://sandbox.api.palomma.com/v1
    description: Sandbox
security:
  - bearerAuth: []
tags:
  - name: Invoices
    description: Create, retrieve, and list invoices.
  - name: Settlements
    description: Retrieve settlements by date and cycle.

paths:
  /invoices:
    post:
      tags: [Invoices]
      summary: Create invoice
      operationId: createInvoice
      description: Creates a new invoice for the authenticated merchant.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateInvoiceRequest"
            examples:
              createInvoice:
                summary: Minimum valid payload
                value:
                  reference: "INV-2026-0001"
                  amount: 1850000
                  description: "Canon de arrendamiento marzo 2026"
                  redirectUrl: "https://merchant.example.com/payments/return"
                  customerDocumentNumber: "900123456"
      responses:
        "200":
          description: Created invoice
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Invoice"
              examples:
                created:
                  value:
                    id: "01HQY8EW1H9YGH5PAV5Y2M9R3T"
                    reference: "INV-2026-0001"
                    status: "ready"
                    amount: 1850000
                    description: "Canon de arrendamiento marzo 2026"
                    contract: "00000"
                    expirationDate: "2026-03-11T16:37:14.007Z"
                    customerDocumentNumber: "900123456"
                    customerName: "Inmobiliaria Ejemplo SAS"
                    createdAt: "2026-03-11T16:32:14.007Z"
                    paymentUrl: "https://pagos.palomma.com/pay/merchant_123/01HQY8EW1H9YGH5PAV5Y2M9R3T"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "500":
          $ref: "#/components/responses/InternalServerError"

    get:
      tags: [Invoices]
      summary: List invoices
      operationId: listInvoices
      description: Returns a paginated list of invoices for the authenticated merchant.
      parameters:
        - in: query
          name: reference
          description: Filter by invoice reference.
          schema:
            type: string
          example: "INV-2026-0001"
        - in: query
          name: customerDocumentNumber
          description: Filter by customer document number.
          schema:
            type: string
          example: "900123456"
        - in: query
          name: contract
          description: Filter by contract identifier.
          schema:
            type: string
          example: "CTR-8842"
        - in: query
          name: paymentDate
          description: Filter by exact payment date.
          schema:
            type: string
            format: date
          example: "2026-03-11"
        - in: query
          name: settlementDate
          description: Filter by settlement date.
          schema:
            type: string
            format: date
          example: "2026-03-12"
        - in: query
          name: settlementCycle
          description: Filter by settlement cycle.
          schema:
            type: string
          example: "1"
        - in: query
          name: limit
          description: Number of results per page. Min 1, max 100.
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
          example: 20
        - in: query
          name: cursor
          description: Opaque cursor from a previous response to fetch the next page.
          schema:
            type: string
          example: "eyJwayI6InJlbnRhbHMj..."
      responses:
        "200":
          description: Paginated invoices list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListInvoicesResponse"
              examples:
                page:
                  value:
                    items:
                      - id: "01HQY8EW1H9YGH5PAV5Y2M9R3T"
                        reference: "INV-2026-0001"
                        status: "paid"
                        amount: 1850000
                        description: "Canon de arrendamiento marzo 2026"
                        contract: "CTR-8842"
                        customerDocumentNumber: "900123456"
                        createdAt: "2026-03-11T16:32:14.007Z"
                        paymentDate: "2026-03-11T18:01:03.219Z"
                        paymentMethod: "pse"
                        paymentSource: "link"
                        paymentAmount: 1850000
                        settlementDate: "2026-03-12"
                        settlementTime: "1"
                        paymentId: "payin_8JkM2P"
                        paymentUrl: "https://pagos.palomma.com/pay/merchant_123/01HQY8EW1H9YGH5PAV5Y2M9R3T"
                    cursor: "eyJwayI6InJlbnRhbHMj..."
                    count: 1
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /invoices/{id}:
    get:
      tags: [Invoices]
      summary: Get invoice by id
      operationId: getInvoice
      description: Retrieves a single invoice by its id.
      parameters:
        - in: path
          name: id
          required: true
          description: Invoice id.
          schema:
            type: string
          example: "01HQY8EW1H9YGH5PAV5Y2M9R3T"
      responses:
        "200":
          description: Invoice found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Invoice"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /settlements/{date}/{cycle}:
    get:
      tags: [Settlements]
      summary: Get settlement by date and cycle
      operationId: getSettlement
      description: Retrieves a single settlement by date and cycle.
      parameters:
        - in: path
          name: date
          required: true
          description: Settlement date in `YYYY-MM-DD` format.
          schema:
            type: string
            format: date
          example: "2026-03-12"
        - in: path
          name: cycle
          required: true
          description: Settlement cycle identifier.
          schema:
            type: string
          example: "1"
      responses:
        "200":
          description: Settlement found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Settlement"
              examples:
                settlement:
                  value:
                    date: "2026-03-12"
                    cycle: "1"
                    status: "paid"
                    numberOfInvoices: 24
                    amountCollected: 45200000
                    fees: 610000
                    feesPostpaid: false
                    adjustments: 0
                    gateway: false
                    paymentAmount: 44590000
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: "Send header: `Authorization: Bearer <apiKey>`."

  responses:
    BadRequest:
      description: Invalid request input
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            invalidBody:
              value:
                error: "Invalid JSON in request body"
            schemaError:
              value:
                error: "Amount must be an integer"
    Unauthorized:
      description: Invalid or missing bearer token
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          example:
            error: "Invalid or missing token"
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            invoiceNotFound:
              value:
                error: "Invoice not found"
            settlementNotFound:
              value:
                error: "Settlement not found"
    InternalServerError:
      description: Unexpected server error
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          example:
            error: "Internal Server Error"

  schemas:
    ErrorResponse:
      type: object
      required: [error]
      properties:
        error:
          type: string
          description: Human-readable error message.

    CreateInvoiceRequest:
      type: object
      required:
        - reference
        - amount
        - description
        - redirectUrl
        - customerDocumentNumber
      properties:
        reference:
          type: string
          minLength: 1
          description: Unique invoice reference for your records (e.g. `"INV-2026-0001"`).
        amount:
          type: integer
          minimum: 3000
          maximum: 550000000
          description: Invoice amount in COP. Must be between 3,000 and 550,000,000.
        description:
          type: string
          minLength: 1
          description: Invoice description shown to the customer.
        redirectUrl:
          type: string
          format: uri
          description: URL where the customer is redirected after completing the payment flow.
        customerDocumentNumber:
          type: string
          minLength: 1
          description: Customer's document or identification number.
        documentType:
          type: string
          description: "Customer's document type. One of: `cc` (cedula), `ce` (cedula de extranjeria), `nit` (NIT), `ti` (tarjeta de identidad), `ps` (pasaporte), `cif` (codigo de identificacion fiscal), `ne` (NIT extranjero), `rc` (registro civil), `ppt` (permiso de permanencia temporal)."
          enum: [cc, ce, nit, ti, ps, cif, ne, rc, ppt]
        customerName:
          type: string
          description: Customer's display name (optional).
        contract:
          type: string
          description: Contract identifier. Defaults to `"00000"` if not provided.
          default: "00000"

    Invoice:
      type: object
      required:
        - id
        - status
        - amount
        - description
        - contract
        - customerDocumentNumber
        - createdAt
        - paymentUrl
      properties:
        id:
          type: string
          description: Unique invoice identifier.
        reference:
          type: string
          description: Merchant-provided invoice reference.
        status:
          type: string
          description: "Invoice status: `ready` (payment link active), `paid`, `cancelled`, or `chargeback`."
          enum: [ready, paid, cancelled, chargeback]
        amount:
          type: number
          description: Invoice amount in COP.
        description:
          type: string
          description: Invoice description.
        contract:
          type: string
          description: Contract identifier.
        expirationDate:
          type: string
          description: Payment link expiration datetime (ISO 8601). Invoices expire 5 minutes after creation, so redirect the customer immediately. Once a transaction is in progress, it no longer expires until the transaction completes.
        customerDocumentNumber:
          type: string
          description: Customer's document number.
        customerName:
          type: string
          description: Customer's display name.
        createdAt:
          type: string
          description: Invoice creation datetime (ISO 8601).
        paymentDate:
          type: string
          format: date-time
          description: When the invoice was paid. Present on paid and chargeback invoices.
        paymentMethod:
          type: string
          enum: [pse, nequiButton, bancolombiaButton, breb, card]
          description: Payment method used. Present on paid and chargeback invoices.
        paymentSource:
          type: string
          enum: [whatsapp, portal, link]
          description: Channel through which payment was made. Present on paid and chargeback invoices.
        paymentAmount:
          type: number
          description: Amount actually paid in COP. Present on paid and chargeback invoices.
        settlementDate:
          type: string
          description: Expected settlement date (`YYYY-MM-DD`). Present on paid and chargeback invoices.
        settlementTime:
          type: string
          description: Expected settlement cycle. Present on paid and chargeback invoices.
        paymentId:
          type: string
          description: Payment identifier. Present on paid and chargeback invoices.
        paymentUrl:
          type: string
          format: uri
          description: Palomma hosted payment page URL for this invoice.

    ListInvoicesResponse:
      type: object
      required: [items, count]
      properties:
        items:
          type: array
          description: Invoices in the current page.
          items:
            $ref: "#/components/schemas/Invoice"
        cursor:
          type: string
          nullable: true
          description: Cursor for the next page. `null` when there are no more pages.
        count:
          type: integer
          description: Number of invoices returned in this page.

    Settlement:
      type: object
      required:
        - date
        - cycle
        - status
        - numberOfInvoices
        - amountCollected
        - fees
        - feesPostpaid
        - adjustments
        - gateway
        - paymentAmount
      properties:
        date:
          type: string
          description: Settlement date (`YYYY-MM-DD`).
        cycle:
          type: string
          description: Settlement cycle identifier.
        status:
          type: string
          enum: [processing, paid, credited, error]
          description: "Settlement status: `processing`, `paid`, `credited`, or `error`."
        numberOfInvoices:
          type: number
          description: Total number of invoices included in this settlement.
        amountCollected:
          type: number
          description: Gross amount collected in COP.
        fees:
          type: number
          description: Total fees deducted in COP.
        feesPostpaid:
          type: boolean
          description: Whether fees are billed separately (postpaid) for this settlement.
        adjustments:
          type: number
          description: Any adjustments applied to the settlement amount in COP.
        gateway:
          type: boolean
          description: Whether this is a gateway settlement.
        paymentAmount:
          type: number
          description: Net amount paid out in COP.
