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

# POST Create Subscription

> Creates a new subscription for recurring card payments.

Create a new subscription for recurring payments with credit or debit card.

This endpoint allows you to associate a card with a subscription plan, defining the periodicity of recurring payments (monthly, yearly, or custom).

<RequestExample>
  ```bash theme={null}
  curl --request POST 'https://tumipay-card-payments.staging.topup.com.co/production/api/subscription/card' \
  --header 'Token-Top: your_auth_token' \
  --header 'Authorization: Basic your_auth_key' \
  --header 'X-Merchant-ID: your_merchant_id' \
  --header 'X-Request-ID: your-request-id' \
  --header 'Content-Type: application/json' \
  --data-raw '{
      "token": "card_token_abc123",
      "plan_name": "Plan Premium",
      "periodicity": "monthly",
      "customer_data": {
          "legal_doc": "1234567890",
          "legal_doc_type": "CC",
          "phone_code": "+57",
          "phone_number": "3121234567",
          "email": "customer@example.com",
          "full_name": "John Doe"
      },
      "start_date": "2026-01-01"
  }'
  ```
</RequestExample>

<ResponseExample>
  ```json Success - Subscription Created (200) theme={null}
  {
      "code": "CREATED",
      "status": true,
      "message": "Suscripción creada exitosamente",
      "data": {
          "subscription_id": "550e8400-e29b-41d4-a716-446655440000"
      }
  }
  ```

  ```json Validation Error (422) theme={null}
  {
      "code": "VALIDATION_ERROR",
      "status": false,
      "message": "Los datos proporcionados no son válidos."
  }
  ```

  ```json Missing Required Header - X-Merchant-ID (400) theme={null}
  {
      "message": "Missing required header: X-Merchant-ID"
  }
  ```

  ```json Missing Required Header - X-Request-ID (400) theme={null}
  {
      "message": "Missing required header: X-Request-ID"
  }
  ```

  ```json Internal Authentication Failed (401) theme={null}
  {
      "code": "UNAUTHORIZED",
      "status": false,
      "message": "Unauthorized."
  }
  ```

  ```json Merchant Not Found (404) theme={null}
  {
      "code": "NOT_FOUND",
      "status": false,
      "message": "Comerciante no encontrado con UUID: {merchant_uuid}"
  }
  ```

  ```json Merchant Inactive (403) theme={null}
  {
      "code": "ACCESS_DENIED",
      "status": false,
      "message": "El comerciante está inactivo"
  }
  ```

  ```json Subscription Creation Failed - Business Error (200) theme={null}
  {
      "code": "SUBSCRIPTION_CREATION_FAILED",
      "status": false,
      "message": "Mensaje de error de excepción de negocio"
  }
  ```

  ```json Service Error (500) theme={null}
  {
      "code": "SERVICE_ERROR",
      "status": false,
      "message": "Ocurrió un error inesperado"
  }
  ```
</ResponseExample>

## Required Headers

<ParamField header="Token-Top" type="string" required>
  Merchant authentication token
</ParamField>

<ParamField header="Authorization" type="string" required>
  Basic authentication (Basic Auth)
</ParamField>

<ParamField header="X-Merchant-ID" type="string" required>
  Unique identifier of the merchant invoking Card Payment services
</ParamField>

<ParamField header="X-Request-ID" type="string" required>
  Unique tracking identifier for the request
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Must be "application/json"
</ParamField>

## Request Body Parameters

<ParamField body="token" type="string" required>
  Token of the card associated with the subscription. This token is obtained through the TumiPay SDK.
</ParamField>

<ParamField body="plan_name" type="string" required>
  Identifier name of the subscription plan (e.g., "Premium Plan", "Basic Plan").
</ParamField>

<ParamField body="periodicity" type="string" required>
  Periodicity of recurring payments. Possible values:

  * `monthly`: Monthly payments
  * `yearly`: Yearly payments
  * `custom`: Custom periodicity according to plan configuration
</ParamField>

<ParamField body="customer_data" type="object" required>
  <Expandable title="Customer data">
    <ParamField body="legal_doc" type="string" required>
      Customer identity document number
    </ParamField>

    <ParamField body="legal_doc_type" type="string" required>
      Document type. Possible values: `CC`, `CE`, `PPN` (Colombia)
    </ParamField>

    <ParamField body="phone_code" type="string" required>
      Country phone code (e.g., "+57" for Colombia)
    </ParamField>

    <ParamField body="phone_number" type="string" required>
      Phone number without country code
    </ParamField>

    <ParamField body="email" type="string" required>
      Customer email address
    </ParamField>

    <ParamField body="full_name" type="string" required>
      Customer full name
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="start_date" type="string" format="date" required>
  Subscription start date in `YYYY-MM-DD` format (e.g., "2026-01-01").
</ParamField>

## Validation Rules

### Required Fields

| Field                          | Type   | Rules                        | Description                                  |
| ------------------------------ | ------ | ---------------------------- | -------------------------------------------- |
| `token`                        | string | required, max:60             | Card subscription token                      |
| `plan_name`                    | string | required, max:20             | Subscription plan name                       |
| `periodicity`                  | string | required                     | Subscription periodicity                     |
| `customer_data`                | object | required                     | Customer data                                |
| `customer_data.legal_doc`      | string | required, max:15             | Customer legal document number               |
| `customer_data.legal_doc_type` | string | required                     | Legal document type                          |
| `customer_data.phone_code`     | string | required, max:4              | Country phone code                           |
| `customer_data.phone_number`   | string | required, max:20             | Customer phone number                        |
| `customer_data.email`          | string | required, email, max:255     | Customer email address                       |
| `customer_data.full_name`      | string | required, max:50             | Customer full name                           |
| `start_date`                   | string | required, date\_format:Y-m-d | Subscription start date (format: YYYY-MM-DD) |

### Allowed Values

#### periodicity

* `daily`
* `weekly`
* `biweekly`
* `monthly`
* `threefortnights`
* `bimonthly`
* `quarterly`
* `fourmonths`
* `halfyearly`
* `yearly`
* `custom`

#### customer\_data.legal\_doc\_type

* `CC` - Cédula de Ciudadanía
* `CE` - Cédula de Extranjería
* `NIT` - Número de Identificación Tributaria
* `TI` - Tarjeta de Identidad
* `PAS` - Pasaporte

#### customer\_data.phone\_code

* `+57` - Colombia

### Common Validation Error Messages

The following are common validation error messages returned by the API (in Spanish):

* `:attribute es obligatorio.` - Required field missing
* `:attribute debe ser una cadena de texto.` - Invalid data type (expected string)
* `:attribute debe ser un número.` - Invalid data type (expected numeric)
* `:attribute debe ser un arreglo.` - Invalid data type (expected array)
* `:attribute debe ser una dirección de correo electrónico válida.` - Invalid email format
* `:attribute no puede tener más de :max caracteres.` - Maximum length exceeded
* `:attribute debe ser mayor o igual a :min.` - Minimum value not met
* `:attribute debe tener el formato YYYY-MM-DD.` - Invalid date format
* `:attribute no es válido.` - Invalid value

## Response Fields

### Success Response (200 OK)

<ResponseField name="code" type="string" required>
  Response code. Value: `"CREATED"` when the subscription is created successfully
</ResponseField>

<ResponseField name="status" type="boolean" required>
  Operation status. `true` when successful, `false` when there is an error
</ResponseField>

<ResponseField name="message" type="string" required>
  Descriptive message about the operation result
</ResponseField>

<ResponseField name="data" type="object" required>
  <Expandable title="Subscription data">
    <ResponseField name="subscription_id" type="string" format="uuid" required>
      Unique identifier of the created subscription. This ID will be used for subsequent operations (preauthorization, cancellation, etc.)
    </ResponseField>
  </Expandable>
</ResponseField>

## HTTP Status Codes

| Status Code                 | Description                                                    | Response Body                                                  |
| --------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------- |
| `200 OK`                    | Successful operation or business error                         | `status: true` for success, `status: false` for business error |
| `400 Bad Request`           | Missing required header (`X-Merchant-ID` or `X-Request-ID`)    | Simple error message                                           |
| `401 Unauthorized`          | Authentication failed (invalid `Token-Top` or `Authorization`) | `code: "UNAUTHORIZED"`                                         |
| `403 Forbidden`             | Inactive merchant                                              | `code: "ACCESS_DENIED"`                                        |
| `404 Not Found`             | Merchant not found                                             | `code: "NOT_FOUND"`                                            |
| `422 Unprocessable Entity`  | Validation error in request data                               | `code: "VALIDATION_ERROR"`                                     |
| `500 Internal Server Error` | Internal server error                                          | `code: "SERVICE_ERROR"`                                        |

## Response Codes

| Code                           | Description                                                               |
| ------------------------------ | ------------------------------------------------------------------------- |
| `CREATED`                      | Subscription created successfully                                         |
| `VALIDATION_ERROR`             | Validation error in sent data                                             |
| `UNAUTHORIZED`                 | Authentication error                                                      |
| `NOT_FOUND`                    | Merchant not found                                                        |
| `ACCESS_DENIED`                | Inactive merchant                                                         |
| `SUBSCRIPTION_CREATION_FAILED` | Business error when creating subscription (provider, invalid token, etc.) |
| `SERVICE_ERROR`                | Internal server error                                                     |


## OpenAPI

````yaml post /api/subscription/card
openapi: 3.0.0
info:
  title: Payment Platform - Card Payment API
  version: 1.0.0
  description: API for managing subscriptions with credit and debit cards.
  contact:
    url: https://docs.tumipay.co
    name: Payment Platform Card Payment
    email: it@tumipay.co
  license:
    name: Proprietary License
    url: https://tumipay.com/license
servers:
  - url: https://tumipay-card-payments.staging.topup.com.co/production
    description: Staging server
security: []
tags:
  - name: CardPayment
    description: Operations related to subscription creation, authorization, and capture.
paths:
  /api/subscription/card:
    post:
      tags:
        - CardPayment
      summary: Create subscription
      description: Creates a new subscription for recurring card payments.
      operationId: createCardPayment
      parameters:
        - $ref: '#/components/parameters/MerchantId'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/TokenTop'
        - $ref: '#/components/parameters/BasicAuth'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - token
                - plan_name
                - periodicity
                - customer_data
                - start_date
              properties:
                token:
                  type: string
                  example: card_token_abc123
                plan_name:
                  type: string
                  example: Plan Premium
                periodicity:
                  type: string
                  enum:
                    - daily
                    - weekly
                    - biweekly
                    - monthly
                    - threefortnights
                    - bimonthly
                    - quarterly
                    - fourmonths
                    - halfyearly
                    - yearly
                    - custom
                  example: monthly
                customer_data:
                  type: object
                  required:
                    - legal_doc
                    - legal_doc_type
                    - phone_code
                    - phone_number
                    - email
                    - full_name
                  properties:
                    legal_doc:
                      type: string
                      example: '1234567890'
                    legal_doc_type:
                      type: string
                      enum:
                        - CC
                        - CE
                        - NIT
                        - TI
                        - PAS
                      description: >-
                        Legal document type. Accepted: CC (Cédula Ciudadanía),
                        CE (Cédula Extranjería), NIT, TI (Tarjeta Identidad),
                        PAS (Pasaporte).
                      example: CC
                    phone_code:
                      type: string
                      description: >-
                        Country phone code with + prefix (e.g. +57 for
                        Colombia).
                      example: '+57'
                    phone_number:
                      type: string
                      example: '3121234567'
                    email:
                      type: string
                      example: customer@example.com
                    full_name:
                      type: string
                      example: John Doe
                start_date:
                  type: string
                  format: date
                  example: '2026-01-01'
      responses:
        '200':
          description: >-
            Subscription created successfully or business error. Check 'status'
            field in the body.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionResponse'
              examples:
                success:
                  summary: Subscription created successfully
                  value:
                    code: CREATED
                    status: true
                    message: Suscripción creada exitosamente
                    data:
                      subscription_id: 550e8400-e29b-41d4-a716-446655440000
                business_error:
                  summary: Business error (invalid token, etc.)
                  value:
                    code: SUBSCRIPTION_CREATION_FAILED
                    status: false
                    message: Token de tarjeta inválido
        '400':
          description: Missing required header (X-Merchant-ID or X-Request-ID).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication failed (invalid Token-Top or Authorization).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Inactive merchant.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Merchant not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error in request data.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  parameters:
    MerchantId:
      name: X-Merchant-ID
      in: header
      required: true
      description: >-
        Unique identifier of the Merchant invoking Card Payment services. Should
        not be used to authenticate end users.
      schema:
        type: string
    RequestId:
      name: X-Request-ID
      in: header
      required: true
      description: >-
        Tracking identifier associated with the request, used to establish a
        correlation_id between ecosystem components.
      schema:
        type: string
    TokenTop:
      name: Token-Top
      in: header
      required: true
      description: Token for authentication.
      schema:
        type: string
    BasicAuth:
      name: Authorization
      in: header
      required: true
      description: Basic authentication.
      schema:
        type: string
  schemas:
    SubscriptionResponse:
      type: object
      description: >-
        Response when creating a subscription. The 'status' field can be true
        (success) or false (business error) even with HTTP 200.
      properties:
        code:
          type: string
          description: >-
            Response code. Values: 'CREATED' (success),
            'SUBSCRIPTION_CREATION_FAILED' (business error)
          example: CREATED
        status:
          type: boolean
          description: Operation status. true for success, false for error
          example: true
        message:
          type: string
          description: Descriptive message about the result
          example: Suscripción creada exitosamente
        data:
          type: object
          properties:
            subscription_id:
              type: string
              format: uuid
              description: Unique identifier of the created subscription
              example: 550e8400-e29b-41d4-a716-446655440000
      required:
        - code
        - status
        - message
    ErrorResponse:
      type: object
      description: >-
        Standard structure for error responses. For 400 errors (missing
        headers), it only contains 'message'.
      oneOf:
        - type: object
          properties:
            code:
              type: string
              description: >-
                Error code. Possible values: 'VALIDATION_ERROR', 'UNAUTHORIZED',
                'NOT_FOUND', 'ACCESS_DENIED', 'SUBSCRIPTION_CREATION_FAILED',
                'SERVICE_ERROR'
              example: VALIDATION_ERROR
            status:
              type: boolean
              description: Always false for error responses
              example: false
            message:
              type: string
              description: Descriptive error message
              example: The given data was invalid.
            details:
              type: object
              additionalProperties: true
              description: Additional error details (optional)
        - type: object
          properties:
            message:
              type: string
              description: Error message for missing headers
              example: 'Missing required header: X-Merchant-ID'
          required:
            - message

````