---
agentTools:
  projectIndex: https://docs.ninepay.com.br/llms.txt
  projectSearch: https://docs.ninepay.com.br/agentSearch?query=term1%20term2
---

# Criar nova assinatura

Cria uma nova assinatura, que representa uma cobrança recorrente, vinculando um cliente a um plano específico.
**Cartão de crédito:** se a assinatura for cobrada no cartão, o cadastro do cliente precisa ter CPF ou CNPJ, telefone, CEP e número do endereço. Esses dados são enviados à adquirente como dados do titular, e a cobrança é recusada se algum deles estiver faltando. Recomendamos cadastrar o cliente com o máximo de informações possível, mesmo que hoje você só cobre por boleto ou Pix.


# OpenAPI definition

```json
{
  "openapi": "3.0.3",
  "info": {
    "title": "NinePay API",
    "version": "1.0",
    "x-logo": {
      "url": ""
    },
    "termsOfService": "https://bit.ly/cefispay-contrato",
    "contact": {
      "name": "NinePay Engineering Team",
      "email": "ti@ninepay.com.br"
    },
    "description": "# Introdução\nBem vindo a referência da **API NinePay**.\nÉ através desta API que você integra o seu sistema ao nosso.\nNossa API é <a target=\"_blank\" href=\"https://en.wikipedia.org/wiki/Representational_state_transfer\">RESTful</a>, e todas suas respostas são em <a target=\"_blank\" href=\"https://www.json.org/\">JSON</a>, no endpoint base:\n```\nhttps://payments.cefis.com.br/api/v1/\n```\n\n## Ambientes\nAlém do ambiente de **produção** temos disponível o ambiente **sandbox**\npara a realização de testes de integração. Toda a comunicação com o ambiente sandbox deve ser feita através da url:\n\n```\nhttps://api.sandbox.cefispay.com.br/api/v1/\n```\n\n## Autenticação\nTodas as requisições que requerem autenticação, deverão informar no header `Authorization` o token de api enviado pela nossa equipe, observando sempre o ambiente desejado e no seguinte formato:\n```\nAuthorization: Bearer <token>\n```\n\n## Headers\nRecomendamos que os cabeçalhos da requisições sejam corretamente adicionados para trabalhar com os tipos de dados enviados e recebidos da API:\n  - Todas as requisições devem contem o header `Content-Type: application/json`, a menos que o endpoint específico defina diferente\n  - Todas as requisições devem contem o header `Accept: application/json`, a menos que o endpoint específico defina diferente\n\n## Respostas\n- Os recursos vêm dentro de `data`: `GET /customers/{id}` responde `{ \"data\": { ... } }`.\n- As criações respondem **201**. `POST /payments` responde `{ \"customer\", \"payment\", \"invoice_url\" }` (o `invoice_url` só no boleto) e `POST /subscriptions` responde `{ \"customer\", \"subscription\" }`.\n- Valores sempre em centavos (inteiro): R$ 50,00 é `5000`.\n\n## Erros\nTodo erro tem o mesmo formato:\n```json\n{\n  \"code\": \"VALIDATION_ERROR\",\n  \"message\": \"Os dados informados são inválidos.\",\n  \"errors\": { \"email\": [\"O campo email é obrigatório.\"] },\n  \"timestamp\": \"2026-10-22T12:03:54+00:00\",\n  \"request_id\": \"64d62d36-e797-45ed-a9d5-c203bde81032\",\n  \"documentation_url\": \"https://docs.ninepay.com.br\",\n  \"suggestion\": \"Corrija os campos e tente novamente.\"\n}\n```\n`errors` só vem na validação, com uma **lista** de mensagens por campo. `suggestion` vem quando há uma. Guarde o `request_id` para falar com o suporte.\n\n| `code` | HTTP | Quando |\n| --- | --- | --- |\n| `AUTHENTICATION_ERROR` | 401 | Token ausente ou inválido |\n| `FORBIDDEN_ERROR` | 403 | O recurso não é da sua empresa. Em várias rotas, um id que não existe também responde 403, para não revelar quais ids existem |\n| `COMPANYBLOCKED_ERROR` | 403 | A conta está suspensa |\n| `RESOURCE_NOT_FOUND_ERROR` | 404 | O recurso não existe |\n| `ROUTE_NOT_FOUND_ERROR` | 404 | A rota não existe |\n| `METHOD_NOT_ALLOWED_ERROR` | 405 | O método não vale para a rota (ex.: `PUT /customers` sem o id) |\n| `INVALID_STATE_ERROR` | 400 | O recurso não está num estado que permita a ação (ex.: cancelar um pagamento já pago) |\n| `VALIDATION_ERROR` | 422 | Dados inválidos; veja `errors` |\n| `REFUND_NOT_ALLOWED` | 422 | O pagamento não pode ser reembolsado |\n| `TOO_MANY_ATTEMPTS` | 429 | Muitas requisições; respeite o cabeçalho `Retry-After` |\n| `UNEXPECTED_ERROR` | 500 | Erro nosso; se repetir, fale com o suporte com o `request_id` |\n\n## Paginação\nAs listagens recebem `page` (a partir de 1) e `limit` (itens por página: **10** por padrão, de 1 a **100**). A resposta traz `data` (os itens), `links` e `meta` (`current_page`, `last_page`, `per_page`, `total`).\n\n## Datas\n- Datas de calendário (`due_date`, `next_payment`) vão como `AAAA-MM-DD` na requisição.\n- Nas respostas, os campos de data e hora aparecem em dois formatos: ISO 8601 em UTC (`2026-10-27T03:00:00.000000Z`, em `due_date` e `ref_date` do pagamento) e `AAAA-MM-DD HH:MM:SS` no horário de Brasília (`created_at` e `updated_at`). Leia o campo pelo formato dele.\n\n## Identificadores\nCada recurso tem um `id` numérico e um `uuid`. Use o `id` nas rotas autenticadas e o **`uuid`** em tudo que é público (o link de pagamento, o checkout e o PDF do boleto).\n\n# Hash de cartões\nO hash de um cartão é uma versão criptografada de todos os dados do cartão do cliente, essa é a maneira mais segura de enviar os dados do cartão\ndo seu cliente diretamente para a gente. Abaixo vamos detalhar como ele funciona e como obter um hash a partir dos dados inseridos pelo cliente.\nÉ importante ressaltar que esse fluxo deve ser executado no front-end, seja ele web ou mobile, e que os dados do cartão do cliente nunca devem\nser enviados para o backend, já o hash do cartão pode ser enviado para o backend sem problemas.\n\n## Gerando uma encryption key\nA encryption key consiste basicamente em uma chave pública RSA usada para encriptar os dados do cartão, essa chave só pode ser usada uma vez, então\nsempre que precisar encriptar um novo cartão você precisa gerar uma nova encryption key.\n\nPara gerar uma encryption key é necessário fazer uma requisição ``POST`` para a rota ``/encryption_keys`` da API enviando como parâmetro seu\n``merchant_id``. Ela não usa o token da API (nunca o coloque no front-end): o ``merchant_id`` identifica a sua conta, e um\n``merchant_id`` que não existe responde 401.\n\nA requisição deverá ter esse formato:\n```\ncurl -X POST https://payments.cefis.com.br/api/v1/encryption_keys -H 'Content-Type: application/json' -d '{\"merchant_id\":\"SEU_MERCHANT_ID\"}'\n```\n\nComo resposta você receberá um objeto JSON no seguinte formato:\n```\n{\n  \"id\": 1111,\n  \"public_key\": \"-----BEGIN PUBLIC KEY-----\\n ... \\n-----END PUBLIC KEY-----\\n\",\n  \"ip_address\": \"000.000.000.000\",\n  \"created_at\": \"2017-07-03\",\n}\n```\n\n## Encriptando os dados do cartão\nPara encriptar os dados do cartão primeiro você precisa formatá-los de forma correta, para isso crie uma string JSON\ncontendo todos os dados do cartão no seguinte formato:\n\n```\n{\"card_number\":\"1111111111111111\",\"card_holder_name\":\"Jose Silva\",\"card_expiration_date\":\"11/2021\",\"card_cvv\":\"111\"}\n```\n\nEm seguida faça a criptografia RSA dessa string utilizando a chave pública (public_key) gerada no passo anterior, com\npadding do tipo PKCS1.\n\nApós criptografar os dados converta a string resultante para base64 e você terá um resultado parecido com esse:\n\n```\nGprWNDlg+MKGgtr6y9wJgz7oOUxGuhhdX3EwydmoOvb+yNDWrjDKktDtWicReOrvSo0u5rsNvCqBFjyoMfaRXn4Qq3KdV8vuuFXubb4FT3OcSSVpu6ddaOjm2tf82+GKjdCy54Lgw4T0m9mWdLPveh/zkYP0+4lhHCFhBKX5EqBdR4918wP5oUV1KpzV4V94ldSA+Cy2n1NUxyUiSnv87H2m+HkdqKDIcX9X8KEtUmorC/EjTPzoeEdpRdj8t3ThcL73mirJvDcYthSdT/ADyaFQ2hMRMkKEVOQjUYMn76vzWyQkqsZ+HVQlxQMOBVHPh5yfrmi1HAVd1jLQuOK8wQ==\n```\n\nO último passo é concatenar o id da sua encryption key (recebido como resposta da requisição anterior) com a string\nem base64 que representa os dados do cartão, da seguinte forma:\n\n``encryption_key_id + \"_\" + base64_encrypted_card``\n\nO resultado será o seu card hash:\n\n```\n1111_GprWNDlg+MKGgtr6y9wJgz7oOUxGuhhdX3EwydmoOvb+yNDWrjDKktDtWicReOrvSo0u5rsNvCqBFjyoMfaRXn4Qq3KdV8vuuFXubb4FT3OcSSVpu6ddaOjm2tf82+GKjdCy54Lgw4T0m9mWdLPveh/zkYP0+4lhHCFhBKX5EqBdR4918wP5oUV1KpzV4V94ldSA+Cy2n1NUxyUiSnv87H2m+HkdqKDIcX9X8KEtUmorC/EjTPzoeEdpRdj8t3ThcL73mirJvDcYthSdT/ADyaFQ2hMRMkKEVOQjUYMn76vzWyQkqsZ+HVQlxQMOBVHPh5yfrmi1HAVd1jLQuOK8wQ==\n```\n\nPronto, agora os dados do cartão do cliente já estão em um formato seguro para serem transportados pela rede, podendo\nagora ser enviados para o seu back-end dar sequência ao fluxo. Vale lembrar que cada card hash pode ser usado apenas\numa vez e além disso tem uma validade máxima de 30 minutos após a geração da encryption key. Caso seja necessário utilizar\no cartão mais de uma vez faça uma requisição para a rota de cartões e salve esse cartão vinculado ao usuário que o detém,\nassim você receberá um ID único que poderá ser usado para realizar mais transações com o mesmo cartão.\n"
  },
  "paths": {
    "/subscriptions": {
      "post": {
        "summary": "Criar nova assinatura",
        "tags": [
          "Assinaturas"
        ],
        "description": "Cria uma nova assinatura, que representa uma cobrança recorrente, vinculando um cliente a um plano específico.\n**Cartão de crédito:** se a assinatura for cobrada no cartão, o cadastro do cliente precisa ter CPF ou CNPJ, telefone, CEP e número do endereço. Esses dados são enviados à adquirente como dados do titular, e a cobrança é recusada se algum deles estiver faltando. Recomendamos cadastrar o cliente com o máximo de informações possível, mesmo que hoje você só cobre por boleto ou Pix.\n",
        "requestBody": {
          "$ref": "#/components/requestBodies/SubscriptionStoreBody"
        },
        "responses": {
          "200": {
            "description": "Assinatura criada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionStoreResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "422": {
            "$ref": "#/components/responses/422"
          },
          "500": {
            "$ref": "#/components/responses/500"
          }
        },
        "operationId": "createSubscription"
      }
    }
  },
  "components": {
    "securitySchemes": {
      "Bearer": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "Todas as requisições que requerem autenticação devem incluir no cabeçalho `Authorization` o token de API enviado pela nossa equipe. O token deve ser fornecido no seguinte formato:\n```\nAuthorization: Bearer <token>\n```"
      }
    },
    "responses": {
      "401": {
        "description": "Não autenticado",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            },
            "example": {
              "code": "AUTHENTICATION_ERROR",
              "message": "Não autenticado.",
              "timestamp": "2026-10-22T12:03:44+00:00",
              "request_id": "f2a7e962-6083-4525-816e-f14d4a602e0a",
              "documentation_url": "https://docs.ninepay.com.br"
            }
          }
        }
      },
      "422": {
        "description": "Erro na validação dos dados",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            },
            "example": {
              "code": "VALIDATION_ERROR",
              "message": "Os dados informados são inválidos.",
              "errors": {
                "email": [
                  "O campo email é obrigatório."
                ]
              },
              "timestamp": "2026-10-22T12:03:54+00:00",
              "request_id": "64d62d36-e797-45ed-a9d5-c203bde81032",
              "documentation_url": "https://docs.ninepay.com.br",
              "suggestion": "Corrija os campos e tente novamente."
            }
          }
        }
      },
      "500": {
        "description": "Erro inesperado",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            },
            "example": {
              "code": "UNEXPECTED_ERROR",
              "message": "Houve um erro inesperado.",
              "timestamp": "2026-10-22T12:04:46+00:00",
              "request_id": "868443d3-38fd-4c92-8ea8-7cccbbce4308",
              "documentation_url": "https://docs.ninepay.com.br",
              "suggestion": "Verifique todos os parâmetros da requisição. Se o erro persistir, entre em contato com nossa equipe em ti@ninepay.com.br."
            }
          }
        }
      }
    },
    "schemas": {
      "ApiError": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "O código do erro. Ex.: `VALIDATION_ERROR`, `FORBIDDEN_ERROR`, `UNEXPECTED_ERROR`."
          },
          "message": {
            "type": "string",
            "description": "A mensagem do erro."
          },
          "errors": {
            "type": "object",
            "description": "Os erros de cada campo, quando o `code` é `VALIDATION_ERROR`.",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "A data e hora do erro, em UTC."
          },
          "request_id": {
            "type": "string",
            "description": "Um identificador único gerado para esta resposta de erro."
          },
          "documentation_url": {
            "type": "string",
            "description": "O endereço desta documentação."
          },
          "suggestion": {
            "type": "string",
            "description": "Uma sugestão de como resolver o erro."
          }
        }
      },
      "SubscriptionStoreResponse": {
        "type": "object",
        "properties": {
          "subscription": {
            "$ref": "#/components/schemas/Subscription"
          },
          "customer": {
            "$ref": "#/components/schemas/Customer"
          }
        }
      },
      "Customer": {
        "type": "object",
        "required": [
          "id",
          "name",
          "email",
          "cpf",
          "cnpj"
        ],
        "properties": {
          "id": {
            "description": "O id do cliente na NinePay. Obrigatório se os demais dados do usuário não forem informados",
            "type": "integer",
            "example": 42,
            "readOnly": true
          },
          "name": {
            "description": "O nome do cliente. Obrigatório se o `id` não for informado",
            "type": "string",
            "example": "Jhon Doe"
          },
          "email": {
            "description": "O email do cliente. Obrigatório se o `id` não for informado",
            "type": "string",
            "example": "jhon@doe.com"
          },
          "cpf": {
            "description": "O cpf do cliente. Obrigatório se o `id` ou o `cnpj` não forem informados",
            "type": "string",
            "example": "833.828.600-15"
          },
          "cnpj": {
            "description": "O cnpj do cliente. Obrigatório se o `id` ou o `cpf` não forem informados",
            "type": "string",
            "example": "95.135.209/0001-79"
          },
          "phone": {
            "description": "O telefone celular do cliente, com DDD. Obrigatório para cobranças no cartão de crédito.",
            "type": "string",
            "example": "(11) 11111-1111"
          },
          "cep": {
            "description": "O CEP do cliente. Obrigatório para cobranças no cartão de crédito.",
            "type": "string",
            "example": "01423-910"
          },
          "address": {
            "description": "O endereço do cliente",
            "type": "string",
            "example": "Rua José Maria Lisboa"
          },
          "number": {
            "description": "O número do endereço do cliente. Obrigatório para cobranças no cartão de crédito.",
            "type": "string",
            "example": 42
          },
          "district": {
            "description": "O bairro do cliente",
            "type": "string",
            "example": "Jardim Paulista"
          },
          "city": {
            "description": "A cidade do cliente",
            "type": "string",
            "example": "São Paulo"
          },
          "state": {
            "description": "O estado do cliente",
            "type": "string",
            "example": "SP"
          },
          "country": {
            "description": "O código do país do cliente, no formato Alpha 2 de acordo com a [ISO 3166](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes).",
            "type": "string",
            "example": "BR"
          }
        }
      },
      "Subscription": {
        "type": "object",
        "properties": {
          "id": {
            "description": "O id da assinatura.",
            "type": "integer",
            "example": 42,
            "readOnly": true
          },
          "uuid": {
            "description": "O id publico da assinatura. Esse id pode ser usado para levar o cliente a página de checkout para pagamento.",
            "type": "string",
            "format": "uuid",
            "example": "8b2cad02-06f0-42be-84ac-101b23a1bb0d"
          },
          "amount": {
            "description": "O valor da assinatura em centavos.",
            "type": "number",
            "example": 2500
          },
          "plan_id": {
            "description": "O id do plano.",
            "type": "number",
            "example": 2500
          },
          "status": {
            "description": "O status da assinatura.",
            "$ref": "#/components/schemas/SubscriptionStatus",
            "example": "credit"
          },
          "created_at": {
            "description": "Data de criação.",
            "type": "string",
            "format": "date-time",
            "example": "2017-07-21 05:20:00"
          }
        }
      },
      "SubscriptionStatus": {
        "type": "string",
        "enum": [
          "new",
          "trial",
          "active",
          "overdue",
          "canceled",
          "expired",
          "paused"
        ]
      },
      "SubscriptionStoreBody": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SubscriptionBody"
          },
          {
            "type": "object",
            "properties": {
              "products": {
                "type": "array",
                "description": "Opcional. Os produtos da assinatura, cobrados junto do plano. Enviados aqui, eles entram já na primeira cobrança, e não apenas nas seguintes. Quando o plano tem trial, a primeira cobrança continua sendo R$ 0,00 e os produtos entram na cobrança seguinte ao trial. Os produtos também podem ser anexados depois da criação, pelo endpoint de produtos da assinatura.\n",
                "items": {
                  "type": "object",
                  "required": [
                    "identifier",
                    "value"
                  ],
                  "properties": {
                    "identifier": {
                      "type": "string",
                      "maxLength": 50,
                      "description": "O nome do produto, como aparece na cobrança.",
                      "example": "Membro adicional"
                    },
                    "value": {
                      "type": "integer",
                      "description": "O valor do produto, em centavos.",
                      "example": 1290
                    },
                    "name": {
                      "type": "string",
                      "maxLength": 191,
                      "description": "Opcional. O que o cliente lê na cobrança. O `identifier` é a chave pela qual o produto é removido, então costuma ser um valor técnico; o `name` é o rótulo apresentável. Sem `name`, o `identifier` continua sendo exibido.\n",
                      "example": "Membro adicional"
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "SubscriptionBody": {
        "type": "object",
        "required": [
          "customer",
          "plan"
        ],
        "properties": {
          "customer": {
            "type": "object",
            "required": [
              "id"
            ],
            "properties": {
              "id": {
                "type": "number",
                "description": "O ID do cliente na NinePay. Se você ainda não tem o ID do cliente, utilize o endpoint de criação de Cliente para fazer o cadastro e receber o ID."
              }
            }
          },
          "plan": {
            "type": "object",
            "required": [
              "id"
            ],
            "properties": {
              "id": {
                "type": "number",
                "description": "O ID do plano a que a nova assinatura será vinculada."
              }
            }
          },
          "coupon_codes": {
            "type": "array",
            "items": {
              "type": "string",
              "example": [
                "ABC123",
                "DEF456"
              ]
            }
          }
        }
      }
    },
    "requestBodies": {
      "SubscriptionStoreBody": {
        "required": true,
        "description": "Descreve os dados a serem incluídos no corpo da requisição.\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SubscriptionStoreBody"
            }
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Assinaturas",
      "description": "Assinaturas"
    }
  ],
  "x-tagGroups": [
    {
      "name": "API Calls",
      "tags": [
        "Pagamentos",
        "Clientes",
        "Planos",
        "Assinaturas",
        "Consultas"
      ]
    }
  ],
  "servers": [
    {
      "url": "https://api.sandbox.cefispay.com.br/api/v1",
      "description": "Servidor de Testes (sandbox)"
    }
  ],
  "security": [
    {
      "Bearer": []
    }
  ]
}
```
