> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tupana.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Emitir DTE manualmente

> Transiciona la sesión de cobro a `issued` emitiendo el DTE del tipo indicado en `target_dte_type`. Solo disponible cuando la sesión está en estado `paid` (típicamente por haberla creado con `auto_issue=false`).

## ¿Para qué se usa?

Emite el DTE para una sesión de cobro ya pagada. Solo necesario cuando creaste la sesión con `auto_issue=false`.

## Qué hace

* Clona el documento interno de cobro al tipo de DTE indicado en `target_dte_type` (boleta o factura).
* Transiciona la sesión al estado `issued`.
* Retorna el payload completo de la sesión incluyendo `issued_document_id`.
* Dispara el webhook `payment_request.document_issued`.

## Body

Por ahora el único campo aceptado es `status` con valor `"issued"`. Cualquier otro valor o un body sin ese campo retorna `400 INVALID_STATUS`.

```json theme={null}
{ "status": "issued" }
```

## Ejemplos de uso

* **Validación previa a emisión**: tu sistema valida datos del cliente antes de emitir la factura.
* **Emisión diferida**: el cobro se confirma inmediatamente pero la factura se emite al final del día.

## Consideraciones importantes

### Requiere `auto_issue=false`

Este endpoint solo tiene sentido cuando creaste la sesión con `auto_issue=false`. Si usaste `auto_issue=true` (el default), el DTE ya fue emitido automáticamente y la sesión está en estado `issued`; recibirás `ALREADY_ISSUED`.

### Solo sobre cobros pagados

La sesión debe estar en estado `paid`. Si el usuario aún no pagó, recibirás `NOT_PAID`.

### Idempotencia

Si llamas este endpoint dos veces sobre la misma sesión, la segunda llamada retorna `ALREADY_ISSUED`. El DTE no se emite dos veces.


## OpenAPI

````yaml api-reference/openapi-payment-requests.json PATCH /payment-requests/{payment_request_id}/
openapi: 3.0.0
info:
  title: Tupana API - Recaudación
  description: >-
    API de Cobros — Crea sesiones de pago, procesa cobros y emite DTE
    automáticamente.
  version: 1.0.0
servers:
  - url: https://api.tupana.ai/v1
    description: Servidor de producción
security:
  - apiKeyAuth: []
paths:
  /payment-requests/{payment_request_id}/:
    patch:
      tags:
        - Cobros
      summary: Emitir DTE manualmente
      description: >-
        Transiciona la sesión de cobro a `issued` emitiendo el DTE del tipo
        indicado en `target_dte_type`. Solo disponible cuando la sesión está en
        estado `paid` (típicamente por haberla creado con `auto_issue=false`).
      operationId: updatePaymentRequest
      parameters:
        - name: payment_request_id
          in: path
          required: true
          description: ID numérico de la sesión de cobro.
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - status
              properties:
                status:
                  type: string
                  enum:
                    - issued
                  description: >-
                    Estado al que se quiere transicionar la sesión. Por ahora
                    solo se acepta `issued`.
            example:
              status: issued
      responses:
        '200':
          description: Sesión transicionada a `issued`
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentRequestResponse'
              example:
                payment_request_id: 1042
                status: issued
                payment_url: https://www.tupana.ai/pagos/tok_xyz
                expires_at: '2026-04-06T12:30:00Z'
                created_at: '2026-04-06T12:00:00Z'
                amount: 50000
                target_dte_type: '39'
                auto_issue: false
                external_id: booking_abc123
                metadata: {}
                issued_document_id: 9871
                document_ids: []
        '400':
          description: No se puede emitir el DTE
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalid_status:
                  value:
                    error_code: INVALID_STATUS
                    message: 'Only {"status": "issued"} is supported.'
                already_issued:
                  value:
                    error_code: ALREADY_ISSUED
                    message: Document has already been issued.
                not_paid:
                  value:
                    error_code: NOT_PAID
                    message: Payment request has not been paid yet.
                not_applicable:
                  value:
                    error_code: NOT_APPLICABLE
                    message: >-
                      Payment request charges existing documents and has nothing
                      to issue.
        '401':
          description: API key inválida o no proporcionada
        '404':
          description: Sesión no encontrada o no pertenece a tu API key
      security:
        - apiKeyAuth: []
components:
  schemas:
    PaymentRequestResponse:
      type: object
      properties:
        payment_request_id:
          type: integer
          description: ID único de la sesión de cobro.
          example: 1042
        status:
          type: string
          enum:
            - pending
            - paid
            - issued
            - failed
            - expired
            - refunded
          example: pending
        payment_url:
          type: string
          format: uri
          description: URL a la que debes redirigir al usuario para que complete el pago.
          example: https://www.tupana.ai/pagos/tok_xyz
        expires_at:
          type: string
          format: date-time
          description: Fecha y hora en que vence la sesión (UTC).
          example: '2026-04-06T12:30:00Z'
        created_at:
          type: string
          format: date-time
          description: Fecha y hora de creación de la sesión (UTC).
          example: '2026-04-06T12:00:00Z'
        amount:
          type: number
          description: Monto del cobro en CLP.
          example: 50000
        target_dte_type:
          type: string
          nullable: true
          description: >-
            Tipo de DTE que se emitirá al pagarse. `null` en modo cobro directo
            (no hay DTE a emitir).
          example: '39'
        auto_issue:
          type: boolean
          nullable: true
          description: >-
            Si el DTE se emite automáticamente al confirmarse el pago. `null` en
            modo cobro directo.
          example: true
        external_id:
          type: string
          nullable: true
          description: Tu ID propio para esta sesión.
          example: booking_abc123
        metadata:
          type: object
          additionalProperties: true
          description: Datos adicionales que enviaste al crear la sesión.
        issued_document_id:
          type: integer
          nullable: true
          description: >-
            ID del DTE emitido. `null` mientras la sesión no haya emitido el
            DTE. Siempre `null` en modo cobro directo.
          example: 9871
        document_ids:
          type: array
          items:
            type: integer
          description: >-
            IDs de los documentos que esta sesión cobra. Lista vacía en modo
            emisión (donde el DTE se emite al pagarse).
          example:
            - 9871
            - 9872
    ErrorResponse:
      type: object
      properties:
        error_code:
          type: string
          example: RECIPIENT_NOT_FOUND
        message:
          type: string
          example: Recipient with id 789 not found.
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: 'API Key para autenticación. Formato: `Api-Key YOUR-API-KEY`'

````