> ## Documentation Index
> Fetch the complete documentation index at: https://developers.uvvipay.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Criar assinatura

> Cria uma nova assinatura.

Cria uma nova assinatura. Sem trial (`PENDING`), a primeira cobrança roda **no mesmo request**. Paid → `201`. Decline de negócio → `422` (`UVV154147`) com `subscription_id` / `invoice_id`. Com trial (`TRIAL`), não há cobrança no create.

O endpoint é limitado a **20 requisições por minuto** por rastreador do throttler (credencial/IP). Em excesso, a API responde `429`.

`payment_methods` aceita `credit_card` (PAN) ou `pix`. Sem trial e com PIX, a resposta inclui `pix.qrcode` e a assinatura permanece `PENDING` até o pagamento.

A resposta HTTP do create usa **snake\_case** (`subscription_id`, `subscription_status`, …). `trial_unit` aceita apenas `DAY`.

`transaction_idempotency_id` deve ser único por organização.

## Resposta de sucesso (`201`)

Inclui status da assinatura/invoice/cobrança quando a cobrança sync é paga, quando é trial sem cobrança, ou quando é PIX aguardando pagamento.

Exemplo PIX (sem trial):

```json theme={null}
{
  "subscription_id": "550e8400-e29b-41d4-a716-446655440000",
  "customer_id": "660e8400-e29b-41d4-a716-446655440000",
  "invoice_id": "770e8400-e29b-41d4-a716-446655440000",
  "subscription_status": "PENDING",
  "invoice_status": "open",
  "charge_status": "pending",
  "transaction_id": "880e8400-e29b-41d4-a716-446655440000",
  "failure_code": null,
  "failure_message": null,
  "pix": {
    "qrcode": "00020126..."
  }
}
```

## Declínio na cobrança sync (`422` / `UVV154147`)

A assinatura **é criada** (`PAST_DUE`, invoice `OPEN`), mas a API **não** devolve `201` com falha embutida. Body:

```json theme={null}
{
  "code": "UVV154147",
  "message": "Nao foi possivel processar o pagamento. Verifique os dados e tente novamente.",
  "subscription_id": "...",
  "invoice_id": "...",
  "transaction_id": "...",
  "failure_code": "issuer_declined",
  "failure_message": "Recusa do banco emissor"
}
```

`transaction_id` é público e só entra no body quando a adquirente devolveu um id na tentativa recusada.

Recuperação: reenvie o **mesmo** `POST` com o **mesmo** `transaction_idempotency_id` e o mesmo payload de negócio. O backend cria o próximo charge attempt e cobra de novo (retries manuais via POST **não** aplicam o limite da fila automática). Não há retry automático na fila para a primeira cobrança (`auto_charge=false`).

## Erros de negócio e cobrança

Corpo padrão:

```json theme={null}
{
  "code": "UVV154293",
  "message": "Nao foi possivel processar pagamento. Verifique os dados e tente novamente."
}
```

| HTTP  | `code`                                                          | `message`                                                                                               |
| ----- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `404` | `UVV154817`, `UVV154293`                                        | Nao foi possivel processar pagamento. Verifique os dados e tente novamente.                             |
| `409` | `UVV154158`, `UVV154972`, `UVV154785`, `UVV154431`, `UVV154862` | Nao foi possivel processar pagamento. Verifique os dados e tente novamente.                             |
| `422` | `UVV154640`, `UVV154306`, `UVV154718`                           | Nao foi possivel processar pagamento. Verifique os dados e tente novamente.                             |
| `400` | `UVV154069`                                                     | Nao foi possivel validar os dados da cobranca. Verifique os dados e tente novamente. (+ ids)            |
| `429` | —                                                               | Rate limit do create (20 req / 60s)                                                                     |
| `500` | `UVV154524`                                                     | Nao foi possivel processar a cobranca. Tente novamente. (+ ids)                                         |
| `422` | `UVV154147`                                                     | Nao foi possivel processar o pagamento. Verifique os dados e tente novamente. (+ ids)                   |
| `422` | `UVV154591`                                                     | Limite de tentativas de cobranca atingido. Atualize o metodo de pagamento ou contate o suporte. (+ ids) |

Os `code`s são opacos no formato `UVV154` + 3 dígitos. Use-os para branching programático.

## Customer

`external_customer_id` e documento (número + tipo) são únicos por organização.

No create de assinatura:

* mesmo `external_customer_id` com nome/email/telefone/documento divergente → `422` / `UVV154640` (`CUSTOMER_DATA_MISMATCH`);
* mesmo documento (número + tipo) com `external_customer_id` diferente → `422` / `UVV154718` (`EXTERNAL_CUSTOMER_ID_MISMATCH`).


## OpenAPI

````yaml POST /v1/recurrency/subscription
openapi: 3.0.0
info:
  title: UvviPay Public API
  description: >-
    Endpoints públicos da plataforma UvviPay para integração de subcontas
    (submerchants).
  version: 1.0.0
  contact: {}
servers:
  - url: https://api.uvvipay.com.br
    description: Produção
  - url: https://api-staging.uvvipay.com.br
    description: Staging
security:
  - client-id: []
    client-secret: []
tags: []
paths:
  /v1/recurrency/subscription:
    post:
      tags:
        - Assinaturas
      summary: Criar assinatura
      description: Cria uma nova assinatura.
      operationId: createSubscription
      parameters:
        - name: client-id
          in: header
          description: ID público da credencial do merchant
          required: true
          schema:
            type: string
        - name: client-secret
          in: header
          description: Secret da credencial do merchant
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSubscriptionDto'
      responses:
        '201':
          description: >-
            Assinatura criada. Sem trial, a primeira cobranca e sincrona: cartao
            pago → ACTIVE; PIX aguardando pagamento → PENDING com pix.qrcode;
            trial → TRIAL sem cobranca. Decline de negocio na cobranca sync
            responde 422 (UVV154147), nao 201.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateSubscriptionResponseDto'
        '400':
          description: Requisição inválida (`UVV154069`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateSubscriptionErrorDto'
              example:
                code: UVV154069
                message: >-
                  Nao foi possivel validar os dados da cobranca. Verifique os
                  dados e tente novamente.
        '401':
          description: Credenciais inválidas ou ausentes
        '403':
          description: Produto `recurrency` não habilitado para o merchant
        '404':
          description: Não encontrado (`UVV154817`, `UVV154293`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateSubscriptionErrorDto'
              example:
                code: UVV154293
                message: >-
                  Nao foi possivel processar pagamento. Verifique os dados e
                  tente novamente.
        '409':
          description: >-
            Conflito (`UVV154158`, `UVV154972`, `UVV154785`, `UVV154431`,
            `UVV154862`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateSubscriptionErrorDto'
              example:
                code: UVV154158
                message: >-
                  Nao foi possivel processar pagamento. Verifique os dados e
                  tente novamente.
        '422':
          description: >-
            Não processável (`UVV154640`, `UVV154306`, `UVV154718`, `UVV154147`,
            `UVV154591`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateSubscriptionErrorDto'
              example:
                code: UVV154640
                message: >-
                  Nao foi possivel processar pagamento. Verifique os dados e
                  tente novamente.
        '429':
          description: Limite de requisições excedido (20 requests per 60 seconds)
        '500':
          description: Erro interno (`UVV154524`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateSubscriptionErrorDto'
              example:
                code: UVV154524
                message: Nao foi possivel processar a cobranca. Tente novamente.
components:
  schemas:
    CreateSubscriptionDto:
      type: object
      required:
        - subscription_plan_id
        - grace_period_days
        - customer
        - payment_methods
        - transaction_idempotency_id
      properties:
        subscription_plan_id:
          type: string
          format: uuid
          description: >-
            UUID de um plano ACTIVE criado antes via POST /v1/recurrency/plan.
            Define valor, moeda e cadência da assinatura.
        grace_period_days:
          type: integer
          minimum: 0
          example: 3
          description: >-
            Dias de tolerância após falha de cobrança antes do cancelamento
            terminal.
        trial_duration:
          type: integer
          minimum: 0
          nullable: true
          description: >-
            Duração do trial desta assinatura. Sobrescreve o trial padrão do
            plano quando informado.
        trial_unit:
          type: string
          enum:
            - DAY
          nullable: true
          description: Unidade do trial desta assinatura. Apenas DAY é aceito.
        customer:
          allOf:
            - $ref: '#/components/schemas/RecurrencyCustomerDto'
          description: >-
            Dados do cliente. Reaproveitado por external_customer_id quando já
            existir.
        payment_methods:
          allOf:
            - $ref: '#/components/schemas/RecurrencyPaymentMethodDto'
          description: Método de pagamento (credit_card com PAN ou pix).
        transaction_idempotency_id:
          type: string
          description: Chave de idempotência da criação (scope subscription_create)
          example: sub-create-0001
    CreateSubscriptionResponseDto:
      type: object
      properties:
        subscription_id:
          type: string
          format: uuid
          description: Identificador da assinatura criada.
        customer_id:
          type: string
          format: uuid
          description: Identificador do cliente vinculado.
        invoice_id:
          type: string
          format: uuid
          description: Identificador da primeira invoice.
        subscription_status:
          type: string
          enum:
            - ACTIVE
            - PENDING
            - TRIAL
            - PAST_DUE
            - CANCELLED
          example: ACTIVE
          description: >-
            Status da assinatura após o create (ACTIVE se paid; PENDING se PIX
            waiting_payment; PAST_DUE se decline; TRIAL se trial).
        invoice_status:
          type: string
          nullable: true
          description: >-
            Status da invoice após a cobrança sync (ou open no trial/PIX
            pendente).
        charge_status:
          type: string
          nullable: true
          enum:
            - pending
            - succeeded
            - failed
          description: >-
            Status da tentativa de cobrança. Null no trial (sem cobrança no
            create). pending para PIX aguardando pagamento.
        transaction_id:
          type: string
          format: uuid
          nullable: true
          description: ID da transação quando a cobrança gerou pagamento.
        failure_code:
          type: string
          nullable: true
          description: >-
            Categoria pública de recusa em decline (ex.: issuer_declined). Null
            quando paid/trial/PIX pendente.
        failure_message:
          type: string
          nullable: true
          description: Rótulo público da recusa. Null quando paid/trial/PIX pendente.
        pix:
          type: object
          nullable: true
          description: >-
            Presente quando a primeira cobrança PIX foi gerada e aguarda
            pagamento.
          properties:
            qrcode:
              type: string
              description: Payload/QR code PIX para pagamento.
          required:
            - qrcode
    CreateSubscriptionErrorDto:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          enum:
            - UVV154817
            - UVV154293
            - UVV154640
            - UVV154158
            - UVV154972
            - UVV154431
            - UVV154785
            - UVV154069
            - UVV154524
            - UVV154306
            - UVV154718
            - UVV154862
            - UVV154147
            - UVV154591
          description: >-
            Código opaco estável no formato UVV154 + 3 dígitos para tratamento
            programático.
        message:
          type: string
          description: Mensagem de erro
        subscription_id:
          type: string
          description: >-
            Identificador da assinatura quando a falha ocorre apos a
            persistencia (ex.: cobranca sync).
        invoice_id:
          type: string
          description: >-
            Identificador da invoice quando a falha ocorre apos a persistencia
            (ex.: cobranca sync).
        transaction_id:
          type: string
          nullable: true
          description: >-
            Identificador publico da transacao na adquirente, quando disponivel
            na tentativa recusada.
        failure_code:
          type: string
          nullable: true
          description: 'Categoria publica da falha de cobranca (ex.: issuer_declined).'
        failure_message:
          type: string
          nullable: true
          description: Mensagem publica associada a falha de cobranca.
    RecurrencyCustomerDto:
      type: object
      required:
        - external_customer_id
        - name
        - email
        - phone
        - address
        - document
      properties:
        external_customer_id:
          type: string
          example: customer-ext-0001
          description: >-
            Identificador do cliente no seu sistema. Usado para deduplicar o
            customer.
        name:
          type: string
          description: Nome completo do cliente.
        email:
          type: string
          format: email
          description: E-mail do cliente.
        phone:
          type: string
          example: '11987654321'
          description: Telefone do cliente (somente dígitos, com DDD).
        address:
          allOf:
            - $ref: '#/components/schemas/RecurrencyCustomerAddressDto'
          description: Endereço do cliente.
        document:
          allOf:
            - $ref: '#/components/schemas/RecurrencyCustomerDocumentDto'
          description: Documento fiscal do cliente.
    RecurrencyPaymentMethodDto:
      oneOf:
        - $ref: '#/components/schemas/RecurrencyCardPaymentMethodDto'
        - $ref: '#/components/schemas/RecurrencyPixPaymentMethodDto'
      discriminator:
        propertyName: type
        mapping:
          credit_card:
            $ref: '#/components/schemas/RecurrencyCardPaymentMethodDto'
          pix:
            $ref: '#/components/schemas/RecurrencyPixPaymentMethodDto'
    RecurrencyCustomerAddressDto:
      type: object
      required:
        - street
        - street_number
        - zip_code
        - city
        - state
        - country
        - neighborhood
      properties:
        street:
          type: string
          description: Logradouro do endereço do cliente.
        street_number:
          type: string
          description: Número do endereço.
        zip_code:
          type: string
          description: CEP (somente dígitos).
        city:
          type: string
          description: Cidade.
        state:
          type: string
          description: UF (sigla de 2 letras).
        country:
          type: string
          example: BR
          description: 'País ISO 3166-1 alpha-2 (ex.: BR).'
        neighborhood:
          type: string
          description: Bairro.
    RecurrencyCustomerDocumentDto:
      type: object
      required:
        - number
        - type
      properties:
        number:
          type: string
          example: '12345678901'
          description: Número do documento (somente dígitos).
        type:
          type: string
          enum:
            - cpf
            - cnpj
          description: 'Tipo do documento: cpf ou cnpj.'
    RecurrencyCardPaymentMethodDto:
      type: object
      required:
        - number
        - holder_name
        - security_code
        - expiration_month
        - expiration_year
        - type
      properties:
        number:
          type: string
          description: PAN do cartão (somente backend/PCI)
          example: '4111111111111111'
        holder_name:
          type: string
          example: JOAO DA SILVA
          description: Nome do portador impresso no cartão.
        security_code:
          type: string
          example: '123'
          description: Código de segurança (CVV). Enviado apenas do backend (PCI).
        expiration_month:
          type: integer
          minimum: 1
          maximum: 12
          example: 12
          description: Mês de expiração do cartão (1-12).
        expiration_year:
          type: integer
          example: 2030
          description: Ano de expiração do cartão (4 dígitos).
        main_payment_method:
          type: boolean
          example: true
          description: Define este cartão como método de pagamento padrão da assinatura.
        type:
          type: string
          enum:
            - credit_card
          description: Tipo do método de pagamento credit_card.
    RecurrencyPixPaymentMethodDto:
      type: object
      required:
        - type
      properties:
        type:
          type: string
          enum:
            - pix
          description: Tipo do método de pagamento pix.
        main_payment_method:
          type: boolean
          example: true
          description: Define este PIX como método de pagamento padrão da assinatura.
  securitySchemes:
    client-id:
      type: apiKey
      in: header
      name: client-id
    client-secret:
      type: apiKey
      in: header
      name: client-secret

````