# Planes (Prices)
---
- [Planes (Prices)](#planes)
- [¿Qué es un plan?](#overview)
- [Checkout de suscripción alojado](#checkout)
- [Crear plan](#create)
- [Actualizar plan](#update)
- [Metadata](#metadata)
- [Listar planes](#get-active-plans)
- [Obtener un plan](#get)
- [Planes de un grupo](#get-by-group)
- [Activar / desactivar plan](#change-active)
- [Eliminar plan](#delete)
- [Alias `price`](#alias)
## ¿Qué es un plan? [#overview]
Un **plan** es la plantilla que usará cada suscripción para determinar **cuánto** y
**cada cuánto** se cobra: precio, moneda, frecuencia de la recurrencia (`invoice_period`
+ `invoice_interval`), días de prueba (`trial_*`) y período de gracia (`grace_*`). Un
plan puede pertenecer a un [grupo](/grupos).
:::note
**Nombre alternativo (estilo Stripe).** Cada ruta de esta página existe también
bajo `price`. Ojo con una diferencia: el filtro por grupo cambia de segmento.
| Nombre original | Alias |
| - | - |
| `GET /api/v1/subscriptions/plan` | `GET /api/v1/subscriptions/price` |
| `GET /api/v1/subscriptions/plan/{id}` | `GET /api/v1/subscriptions/price/{id}` |
| `GET /api/v1/subscriptions/plan/group/{group}/{all?}` | `GET /api/v1/subscriptions/price/product/{group}/{all?}` |
| `POST /api/v1/subscriptions/plan` | `POST /api/v1/subscriptions/price` |
| `PUT /api/v1/subscriptions/plan/{id}` | `PUT /api/v1/subscriptions/price/{id}` |
| `PUT /api/v1/subscriptions/plan/changeActive/{id}` | `PUT /api/v1/subscriptions/price/changeActive/{id}` |
| `DELETE /api/v1/subscriptions/plan/{id}` | `DELETE /api/v1/subscriptions/price/{id}` |
:::
:::note
**Descuentos:** para aplicar descuentos usa
[Cupones](/coupons) reutilizables. Los campos `discount_*` del
plan siguen disponibles por compatibilidad, pero los cupones son la forma recomendada.
:::
## Checkout de suscripción alojado [#checkout]
**No necesitas construir un formulario de suscripción.** Cada plan trae una página de
checkout alojada por Efipay, lista para usar. Al crear el plan la respuesta te devuelve:
| Campo | Qué es |
| - | - |
| checkoutUrl | La URL de la página donde tu cliente se suscribe: ingresa sus datos, su tarjeta y queda suscrito |
| qrCodeSvg | Esa misma URL como código QR, ya renderizado en SVG. Sirve para imprimirlo o mostrarlo en pantalla |
Es la ruta de integración más corta: creas el plan una vez, publicas el enlace y no
escribes una sola línea de código de cobro. Efipay se encarga del formulario, la
tokenización de la tarjeta y el cobro recurrente.
Desde ese mismo enlace tu suscriptor tiene un **portal de autogestión** donde puede
consultar sus cobros y facturas, actualizar la tarjeta con la que paga, renovar y
cancelar su suscripción. Se identifica con un código de verificación que le llega por
correo, así que no tienes que darle usuario ni contraseña.
:::note
Si prefieres controlar la experiencia, ignora `checkoutUrl` y crea las
suscripciones tú mismo con
[`POST /api/v1/subscriptions/subscription`](/subscription#create).
Ambos caminos producen la misma suscripción.
:::
:::caution
El `checkoutUrl` de un plan de prueba solo funciona con datos de prueba. No
lo publiques a clientes reales hasta que crees el plan con un token de producción.
:::
## Crear plan [#create]
**Descripción:** Crea un plan que servirá como guía para las suscripciones recurrentes
(precio, moneda, frecuencia, prueba y gracia).
`POST /api/v1/subscriptions/plan`
| Nombre del campo | Descripción | Reglas |
| - | - | - |
| name | Nombre del plan. Lo ve el suscriptor | `['required', 'string', 'max:150']` |
| description | Qué incluye el plan | `['required', 'string', 'max:500']` |
| price | Valor que se cobra en cada renovación. El máximo depende de la moneda: `999999999999` en COP y `200000000` en USD/EUR | `['required', 'numeric', 'min:1', 'max:999999999999']` |
| currency_type | Moneda del cobro. Ver [enumeraciones](/resources) | `['required', 'in:COP,USD,EUR']` |
| tax | Valor del IVA a aplicar. Debe ser uno de tus impuestos **activos**; consúltalos en `GET /api/v1/resources/get-taxes` | `['nullable', 'exists:taxes,value']` |
| invoice_period | Cada cuántos `invoice_interval` se cobra. Junto con el intervalo define la frecuencia | `['required', 'integer', 'min:1', 'max:30']` |
| invoice_interval | Unidad de la frecuencia de cobro | `['required', 'in:day,week,month,year']` |
| trial_period | Períodos de prueba antes del primer cobro. `0` = sin prueba | `['sometimes', 'integer', 'min:0', 'max:30']` |
| trial_interval | Unidad del período de prueba | `['sometimes', 'in:day,week,month,year']` |
| grace_period | Tiempo tras el vencimiento en el que se sigue reintentando el cobro antes de dar la suscripción por inactiva | `['sometimes', 'integer', 'min:0', 'max:7']` |
| grace_interval | Unidad del período de gracia | `['sometimes', 'in:day,week,month,year']` |
| max_recurrences | Número máximo de cobros aprobados. Al alcanzarlo la suscripción se cancela sola | `['nullable', 'integer', 'min:1', 'max:100']` |
| deadline | Fecha tope de la suscripción. Al pasarla se cancela sola | `['nullable', 'date', 'date_format:Y-m-d H:i:s']` |
| active_subscribers_limit | Máximo de suscriptores activos que admite el plan | `['nullable', 'integer', 'max:100000']` |
| allow_multiple_subscriptions | Permite que un mismo suscriptor tenga más de una suscripción a este plan | `['sometimes', 'boolean']` |
| sort_order | Orden en que se listan los planes | `['nullable', 'integer', 'max:100000']` |
| subscription_group_id | [Grupo](/grupos) al que pertenece el plan | `['nullable', 'exists:subscription_groups,id']` |
| office | Sucursal a la que pertenece el plan. Debe ser una de [tus sucursales](/commercio) | `['required', 'exists:offices,id']` |
| advanced_options | Opciones avanzadas del cobro | `['nullable', 'array']` |
| advanced_options.result_urls | URLs de retorno y webhook para los cobros del plan | `['nullable', 'array']` |
| metadata | Tus pares clave-valor. Ver [Metadata](#metadata) | `['sometimes', 'nullable', 'metadata']` |
:::caution
`subscription_group_id` se valida contra los grupos creados por **el usuario
del token**, no por el comercio. Si otro usuario de tu comercio creó el grupo, la API lo
rechazará como inválido. Crea los grupos con el mismo usuario con el que creas los
planes.
:::
**Descuento del plan** — se mantiene por compatibilidad. Para descuentos nuevos usa
[Cupones](/coupons), que son reutilizables entre planes.
| Nombre del campo | Descripción | Reglas |
| - | - | - |
| discount_type_amount | Tipo de descuento. Ver [enumeraciones](/resources) | `['sometimes', 'nullable', 'in:value,percentage']` |
| discount_amount | Valor del descuento, según el tipo | `['sometimes', 'nullable', 'numeric']` |
| discount_period | Duración del descuento, en `discount_interval` | `['sometimes', 'integer', 'min:0', 'max:30']` |
| discount_interval | Unidad de la duración del descuento | `['sometimes', 'in:day,week,month,year']` |
| discount_subscribers_limit | Cuántos suscriptores alcanzan el descuento | `['sometimes', 'nullable', 'integer', 'min:1', 'max:100000']` |
`POST /api/v1/subscriptions/plan`
Cuerpo de ejemplo:
```json
{
"name": "Newsletter mensual",
"description": "Suscripción general a newsletters, 15 envíos por mes",
"price": 15000,
"currency_type": "COP",
"tax": 19,
"trial_period": 0,
"trial_interval": "day",
"invoice_period": 1,
"invoice_interval": "month",
"grace_period": 3,
"grace_interval": "day",
"max_recurrences": 12,
"sort_order": 0,
"active_subscribers_limit": 1000,
"allow_multiple_subscriptions": false,
"subscription_group_id": "9ae9a2e0-bf16-43c7-a052-f448c447c33e",
"office": 1
}
```
```bash
curl -X POST \
'/api/v1/subscriptions/plan' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-type: application/json' \
-H 'Idempotency-Key: 9b1f0e34-6b2a-4a7e-9d0a-000000000002' \
-d '{
"name": "Newsletter mensual",
"description": "Suscripción general a newsletters, 15 envíos por mes",
"price": 15000,
"currency_type": "COP",
"tax": 19,
"invoice_period": 1,
"invoice_interval": "month",
"grace_period": 3,
"grace_interval": "day",
"office": 1
}'
```
:::tip
Respuesta satisfactoria
:::
Código de respuesta: 200
```json
{
"saved": true,
"plan": {
"id": "9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f",
"name": "Newsletter mensual",
"description": "Suscripción general a newsletters, 15 envíos por mes",
"price": 15000,
"currencyType": "COP",
"production": false,
"trialInterval": "day",
"trialPeriod": 0,
"invoiceInterval": "month",
"invoicePeriod": 1,
"graceInterval": "day",
"gracePeriod": 3,
"discountInterval": "day",
"discountPeriod": 0,
"discountTypeAmount": null,
"discountSubscribersLimit": null,
"activeSubscribersLimit": null,
"allowMultipleSubscriptions": false,
"subscriptionGroupId": null,
"groupName": null,
"maxRecurrences": null,
"deadline": null,
"resultUrls": null,
"createdAt": "2026-07-31 10:15:00",
"active": true,
"checkoutUrl": "https://sag.efipay.co/checkout/subscription-gateway/9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f",
"qrCodeSvg": ""
}
}
```
:::danger
Un impuesto que no existe o no está activo, o una sucursal que no es tuya
:::
Código de respuesta: 422
```json
{
"message": "El tax seleccionado no es válido.",
"errors": {
"tax": ["El tax seleccionado no es válido."],
"office": ["El office seleccionado no es válido."]
}
}
```
:::danger
Tu comercio no tiene habilitada la funcionalidad de suscripciones
:::
Código de respuesta: 403
## Actualizar plan [#update]
**Descripción:** Actualiza los campos de un plan existente. Envía solo lo que quieras
cambiar.
`PUT /api/v1/subscriptions/plan/{plan-id}`
:::caution
**Las reglas no son idénticas a las de crear.** `office` no se puede cambiar,
`price` pierde el máximo por moneda, `deadline` deja de validarse como fecha real y los
límites de descuento cambian. Esta es la lista exacta:
:::
| Nombre del campo | Descripción | Reglas |
| - | - | - |
| name | Nuevo nombre | `['sometimes', 'required', 'string', 'max:150']` |
| description | Nueva descripción | `['sometimes', 'required', 'string', 'max:500']` |
| price | Nuevo precio | `['sometimes', 'numeric', 'min:1']` |
| currency_type | Nueva moneda | `['sometimes', 'in:COP,USD,EUR']` |
| tax | Nuevo IVA, entre tus impuestos activos | `['sometimes', 'nullable', 'exists:taxes,value']` |
| invoice_period | Cada cuántos `invoice_interval` se cobra | `['sometimes', 'integer', 'min:1', 'max:30']` |
| invoice_interval | Unidad de la frecuencia de cobro | `['sometimes', 'in:day,week,month,year']` |
| trial_period | Períodos de prueba | `['sometimes', 'integer', 'min:0', 'max:30']` |
| trial_interval | Unidad del período de prueba | `['sometimes', 'in:day,week,month,year']` |
| grace_period | Períodos de gracia | `['sometimes', 'integer', 'min:0', 'max:7']` |
| grace_interval | Unidad del período de gracia | `['sometimes', 'in:day,week,month,year']` |
| discount_type_amount | Tipo de descuento | `['sometimes', 'nullable', 'in:value,percentage']` |
| discount_amount | Valor del descuento | `['sometimes', 'nullable', 'numeric']` |
| discount_period | Duración del descuento. **Aquí el máximo es 100000**, no 30 | `['sometimes', 'integer', 'min:0', 'max:100000']` |
| discount_interval | Unidad de la duración del descuento | `['sometimes', 'in:day,week,month,year']` |
| discount_subscribers_limit | Cuántos suscriptores alcanzan el descuento. **Aquí no hay `min:1`** | `['sometimes', 'nullable', 'integer', 'max:100000']` |
| sort_order | Orden en que se listan los planes | `['sometimes', 'nullable', 'integer', 'max:100000']` |
| active_subscribers_limit | Máximo de suscriptores activos | `['sometimes', 'nullable', 'integer', 'max:100000']` |
| max_recurrences | Máximo de cobros aprobados | `['sometimes', 'nullable', 'integer', 'min:1', 'max:100']` |
| deadline | Fecha tope de la suscripción | `['sometimes', 'nullable', 'date_format:Y-m-d H:i:s']` |
| allow_multiple_subscriptions | Permitir varias suscripciones del mismo suscriptor | `['sometimes', 'boolean']` |
| subscription_group_id | Grupo al que pertenece el plan | `['sometimes', 'nullable', 'exists:subscription_groups,id']` |
| advanced_options | Opciones avanzadas. Envía `null` para borrarlas | `['nullable', 'array']` |
| advanced_options.result_urls | URLs de retorno y webhook | `['nullable', 'array']` |
| metadata | Se **combina** con la existente. Una clave con `""` o `null` se borra; `metadata: null` borra todo. Ver [Metadata](#metadata) | `['sometimes', 'nullable', 'metadata']` |
:::danger
Cambiar el precio de un plan afecta a **todas** las suscripciones activas en su
próxima renovación. Si quieres subir el precio solo a los nuevos, crea un plan nuevo y
deja el anterior activo.
:::
`PUT /api/v1/subscriptions/plan/your-plan-id`
Cuerpo de ejemplo:
```json
{
"name": "Newsletter mensual",
"description": "Suscripción básica a newsletter, 40 envíos por mes",
"price": 30000
}
```
```bash
curl -X PUT \
'/api/v1/subscriptions/plan/9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-type: application/json' \
-d '{
"price": 30000,
"description": "Suscripción básica a newsletter, 40 envíos por mes"
}'
```
:::tip
Respuesta satisfactoria
:::
Código de respuesta: 200
```json
{
"saved": true,
"plan": {
"id": "9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f",
"name": "Newsletter mensual",
"description": "Suscripción básica a newsletter, 40 envíos por mes",
"price": 30000,
"currencyType": "COP",
"production": false,
"trialInterval": "day",
"trialPeriod": 0,
"invoiceInterval": "month",
"invoicePeriod": 1,
"graceInterval": "day",
"gracePeriod": 3,
"discountInterval": "day",
"discountPeriod": 0,
"discountTypeAmount": null,
"discountSubscribersLimit": null,
"activeSubscribersLimit": null,
"allowMultipleSubscriptions": false,
"subscriptionGroupId": null,
"groupName": null,
"maxRecurrences": null,
"deadline": null,
"resultUrls": null,
"createdAt": "2026-07-31 10:15:00",
"active": true,
"checkoutUrl": "https://sag.efipay.co/checkout/subscription-gateway/9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f",
"qrCodeSvg": ""
}
}
```
## Metadata [#metadata]
`metadata` guarda tus propias referencias del plan (SKU, nivel, id en tu catálogo…), al
estilo de Stripe. Mismas reglas que en [suscripciones](/subscription#metadata):
| Límite | Valor |
| - | - |
| Claves | Hasta 50, de 1 a 40 caracteres `[A-Za-z0-9_-]` |
| Valor | Texto o número, hasta 500 caracteres. Se guarda como texto |
| Al actualizar | Las claves se combinan; `""` o `null` borra una clave; `metadata: null` borra todo |
Llega en los `GET` y listados y en los
[webhooks de suscripción](/subscription-webhook), dentro de
`subscription.plan.metadata`. Filtra los listados con `filter[metadata][clave]=valor`.
Un valor inválido responde `422` con `error.code: "validation_failed"` y
`error.param: "metadata"`.
## Listar planes [#get-active-plans]
**Descripción:** Devuelve tus planes, paginados.
`GET /api/v1/subscriptions/plan`
Estos parámetros de consulta **no se validan en el servidor**: un valor inesperado no
produce un `422`, simplemente no filtra.
| Nombre del campo | Descripción |
| - | - |
| active | Envía exactamente la cadena `true` para traer solo los planes activos. Cualquier otro valor no filtra |
| fields | Columnas a devolver, separadas por coma. Útil para respuestas ligeras |
| per_page | Planes por página. **Por defecto 2**, así que casi siempre querrás enviarlo |
| filter[metadata][clave] | Coincidencia exacta con un par de tu [metadata](#metadata), por ejemplo `filter[metadata][tier]=gold` |
:::danger
`per_page` viene en **2** por defecto. Si no lo envías parecerá que tu comercio
solo tiene dos planes. Es el error más común al integrar esta página.
:::
:::caution
Este listado filtra por el ambiente configurado en **tu comercio**, no por el
del token, y solo devuelve planes de las sucursales de tu usuario. Si un plan que
acabas de crear no aparece aquí, búscalo con
[Obtener un plan](#get) por su `id`.
:::
La respuesta son los **modelos crudos en `snake_case`** dentro del sobre de paginación de
Laravel, no el objeto camelCase que devuelven crear y actualizar.
`GET /api/v1/subscriptions/plan`
```bash
curl -X GET \
'/api/v1/subscriptions/plan?active=true&per_page=50' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Accept: application/json'
```
:::tip
Respuesta satisfactoria
:::
Código de respuesta: 200
```json
{
"current_page": 1,
"data": [
{
"id": "9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f",
"name": "Newsletter mensual",
"description": "Suscripción general a newsletters, 15 envíos por mes",
"price": 15000,
"currency_type": "COP",
"advanced_option_id": null,
"tax": 19,
"trial_period": 0,
"trial_interval": "day",
"invoice_period": 1,
"invoice_interval": "month",
"grace_period": 3,
"grace_interval": "day",
"discount_period": 0,
"discount_interval": "day",
"discount_subscribers_limit": null,
"discount_type_amount": null,
"discount_amount": null,
"sort_order": 0,
"active_subscribers_limit": null,
"max_recurrences": null,
"deadline": null,
"production": false,
"active": true,
"subscription_group_id": null,
"user_id": 42,
"office_id": 1,
"commerce_id": 315,
"allow_multiple_subscriptions": false,
"metadata": { "tier": "gold" },
"created_at": "2026-07-31 10:15:00",
"checkout_url": "https://sag.efipay.co/checkout/subscription-gateway/9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f",
"checkout_url_commerce_assign": "https://sag.efipay.co/checkout/subscription-gateway/9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f?commerce_assign=true"
}
],
"first_page_url": "https://sag.efipay.co/api/v1/subscriptions/plan?page=1",
"from": 1,
"last_page": 1,
"last_page_url": "https://sag.efipay.co/api/v1/subscriptions/plan?page=1",
"next_page_url": null,
"path": "https://sag.efipay.co/api/v1/subscriptions/plan",
"per_page": 50,
"prev_page_url": null,
"to": 1,
"total": 1
}
```
## Obtener un plan [#get]
**Descripción:** Devuelve un plan por su `id`, como modelo crudo en `snake_case`.
`GET /api/v1/subscriptions/plan/{plan-id}`
`GET /api/v1/subscriptions/plan/your-plan-id`
```bash
curl -X GET \
'/api/v1/subscriptions/plan/9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Accept: application/json'
```
:::tip
Respuesta satisfactoria
:::
Código de respuesta: 200
```json
{
"id": "9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f",
"name": "Newsletter mensual",
"description": "Suscripción general a newsletters, 15 envíos por mes",
"price": 15000,
"currency_type": "COP",
"tax": 19,
"trial_period": 0,
"trial_interval": "day",
"invoice_period": 1,
"invoice_interval": "month",
"grace_period": 3,
"grace_interval": "day",
"production": false,
"active": true,
"subscription_group_id": null,
"office_id": 1,
"commerce_id": 315,
"allow_multiple_subscriptions": false,
"created_at": "2026-07-31 10:15:00",
"checkout_url": "https://sag.efipay.co/checkout/subscription-gateway/9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f",
"checkout_url_commerce_assign": "https://sag.efipay.co/checkout/subscription-gateway/9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f?commerce_assign=true"
}
```
:::danger
El plan no existe o no es de tu comercio
:::
Código de respuesta: 404
## Planes de un grupo [#get-by-group]
**Descripción:** A partir del ID de un [grupo](/grupos), devuelve
los planes de ese grupo.
`GET /api/v1/subscriptions/plan/group/{group}/{all?}`
Los dos segmentos son opcionales y cambian el resultado:
| Ruta | Devuelve |
| - | - |
| `/plan/group/{group}` | Solo los planes **activos** del grupo |
| `/plan/group/{group}/all` | **Todos** los planes del grupo, activos e inactivos |
| `/plan/group` | Los planes activos del comercio, sin filtrar por grupo |
Acepta también `filter[metadata][clave]=valor` para quedarte con los planes cuya
[metadata](#metadata) coincide exactamente.
:::caution
Este endpoint **no está paginado**, **no viene envuelto en `data`** y **no
filtra por ambiente**: devuelve el arreglo de modelos crudos, mezclando planes de prueba
y de producción. Filtra por el campo `production` de tu lado.
:::
`GET /api/v1/subscriptions/plan/group/{your-group-id}/all`
```bash
curl -X GET \
'/api/v1/subscriptions/plan/group/9ae9a2e0-bf16-43c7-a052-f448c447c33e/all' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Accept: application/json'
```
:::tip
Respuesta satisfactoria
:::
Código de respuesta: 200
```json
[
{
"id": "9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f",
"name": "Newsletter mensual",
"price": 15000,
"currency_type": "COP",
"invoice_period": 1,
"invoice_interval": "month",
"production": false,
"active": true,
"subscription_group_id": "9ae9a2e0-bf16-43c7-a052-f448c447c33e",
"created_at": "2026-07-31 10:15:00"
}
]
```
## Activar / desactivar plan [#change-active]
**Descripción:** Activa o desactiva un plan. Un plan inactivo no puede usarse para crear
nuevas suscripciones, pero **las suscripciones existentes siguen cobrándose**.
`PUT /api/v1/subscriptions/plan/changeActive/{plan-id}`
| Nombre del campo | Descripción | Reglas |
| - | - | - |
| active | Nuevo estado del plan | `['required', 'boolean']` |
`PUT /api/v1/subscriptions/plan/changeActive/your-plan-id`
Cuerpo de ejemplo:
```json
{
"active": false
}
```
```bash
curl -X PUT \
'/api/v1/subscriptions/plan/changeActive/9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-type: application/json' \
-d '{ "active": false }'
```
:::tip
Respuesta satisfactoria
:::
Código de respuesta: 200
```json
{
"active": false,
"plan": {
"id": "9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f",
"name": "Newsletter mensual",
"price": 15000,
"currencyType": "COP",
"active": false,
"createdAt": "2026-07-31 10:15:00",
"checkoutUrl": "https://sag.efipay.co/checkout/subscription-gateway/9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f",
"qrCodeSvg": ""
}
}
```
## Eliminar plan [#delete]
**Descripción:** Elimina un plan por su `id`.
`DELETE /api/v1/subscriptions/plan/{plan-id}`
:::caution
No podrás eliminar un plan que tenga suscripciones activas. Cancélalas
primero, o simplemente [desactiva el plan](#change-active) para que no acepte nuevas
suscripciones.
:::
`DELETE /api/v1/subscriptions/plan/your-plan-id`
```bash
curl -X DELETE \
'/api/v1/subscriptions/plan/9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Accept: application/json'
```
:::tip
Respuesta satisfactoria
:::
Código de respuesta: 200
```json
{
"deleted": true
}
```
:::danger
El plan tiene suscripciones activas
:::
Código de respuesta: 400
```json
{
"message": "El plan tiene suscripciones activas y no puede eliminarse."
}
```
## Alias `price` [#alias]
Las mismas operaciones, con el nombre de Stripe. Comportamiento, parámetros y respuestas
son idénticos a los de arriba. Fíjate en que el filtro por grupo usa `product` en lugar
de `group`.
**Listar** — `GET /api/v1/subscriptions/price` (recuerda `per_page`, que por defecto es 2)
`GET /api/v1/subscriptions/price`
**Obtener uno** — `GET /api/v1/subscriptions/price/{price-id}`
`GET /api/v1/subscriptions/price/your-plan-id`
**Por grupo** — `GET /api/v1/subscriptions/price/product/{product-id}/{all?}`
`GET /api/v1/subscriptions/price/product/{your-group-id}/all`
**Crear** — `POST /api/v1/subscriptions/price`
`POST /api/v1/subscriptions/price`
Cuerpo de ejemplo:
```json
{
"name": "Newsletter mensual",
"description": "Suscripción general a newsletters, 15 envíos por mes",
"price": 15000,
"currency_type": "COP",
"invoice_period": 1,
"invoice_interval": "month",
"office": 1
}
```
**Actualizar** — `PUT /api/v1/subscriptions/price/{price-id}`
`PUT /api/v1/subscriptions/price/your-plan-id`
Cuerpo de ejemplo:
```json
{
"price": 30000
}
```
**Activar / desactivar** — `PUT /api/v1/subscriptions/price/changeActive/{price-id}`
`PUT /api/v1/subscriptions/price/changeActive/your-plan-id`
Cuerpo de ejemplo:
```json
{
"active": false
}
```
**Eliminar** — `DELETE /api/v1/subscriptions/price/{price-id}`
`DELETE /api/v1/subscriptions/price/your-plan-id`