Skip to main content

Endpoint

POST /api/subscription/create
Creates a new subscription for the authenticated user after a successful payment. This endpoint is typically called from the payment success webhook or redirect page.

Authentication

Requires a valid Supabase authentication token in the request headers.
Authorization: Bearer <supabase_access_token>

Request Body

planType
string
required
The subscription plan type. Must be one of:
  • PLAN_BASICO - Basic plan (1 month duration)
  • PLAN_PRO - Pro plan (1 month duration)
  • PLAN_PREMIUM - Premium plan (1 month duration)
paymentProvider
string
required
The payment provider used for the transaction. Must be one of:
  • mercadopago - MercadoPago payment
  • wompi - Wompi payment
paymentReference
string
required
The payment reference ID from the payment provider (e.g., MercadoPago payment ID)
amountPaid
number
required
The amount paid in Colombian pesos (COP). Must match the plan price:
  • PLAN_BASICO: 49900
  • PLAN_PRO: 89900
  • PLAN_PREMIUM: 149900

Response

subscription
object
required
The created subscription object
id
string
required
Unique subscription identifier (UUID)
userId
string
required
User ID associated with the subscription
planType
string
required
The subscription plan type (PLAN_BASICO, PLAN_PRO, or PLAN_PREMIUM)
status
string
required
Always active for newly created subscriptions
startDate
string
required
ISO 8601 timestamp when the subscription starts (current date/time)
endDate
string
required
ISO 8601 timestamp when the subscription expires (start date + 1 month)
paymentProvider
string
required
Payment provider used (mercadopago or wompi)
paymentReference
string
required
Payment reference from the provider
amountPaid
number
required
Amount paid in COP
createdAt
string
required
ISO 8601 timestamp when the subscription was created
updatedAt
string
required
ISO 8601 timestamp when the subscription was last updated
profile
object
required
Updated user profile information
hasActiveSubscription
boolean
required
Always true after subscription creation
currentPlan
string
required
The current active plan type
subscriptionEndDate
string
required
ISO 8601 timestamp when the subscription expires

Example Request

const response = await fetch('/api/subscription/create', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    planType: 'PLAN_PRO',
    paymentProvider: 'mercadopago',
    paymentReference: '1234567890',
    amountPaid: 89900
  })
});

const data = await response.json();

Example Response

{
  "subscription": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "userId": "123e4567-e89b-12d3-a456-426614174000",
    "planType": "PLAN_PRO",
    "status": "active",
    "startDate": "2026-03-01T12:00:00.000Z",
    "endDate": "2026-04-01T12:00:00.000Z",
    "paymentProvider": "mercadopago",
    "paymentReference": "1234567890",
    "amountPaid": 89900,
    "createdAt": "2026-03-01T12:00:00.000Z",
    "updatedAt": "2026-03-01T12:00:00.000Z"
  },
  "profile": {
    "hasActiveSubscription": true,
    "currentPlan": "PLAN_PRO",
    "subscriptionEndDate": "2026-04-01T12:00:00.000Z"
  }
}

Error Responses

400 Bad Request

Returned when required fields are missing or invalid.
{
  "error": "Bad Request",
  "message": "Invalid plan type. Must be PLAN_BASICO, PLAN_PRO, or PLAN_PREMIUM"
}
{
  "error": "Bad Request",
  "message": "Missing required field: paymentReference"
}

401 Unauthorized

Returned when the user is not authenticated.
{
  "error": "Unauthorized",
  "message": "Authentication required"
}

409 Conflict

Returned when the user already has an active subscription.
{
  "error": "Conflict",
  "message": "User already has an active subscription"
}

500 Internal Server Error

Returned when there’s a server error creating the subscription.
{
  "error": "Internal Server Error",
  "message": "Failed to create subscription"
}

Subscription Duration Logic

All subscription plans currently have a duration of 1 month. The endDate is calculated as:
const startDate = new Date();
const endDate = new Date();
endDate.setMonth(endDate.getMonth() + 1); // Add 1 month

Database Updates

Creating a subscription performs the following database operations:
  1. Insert into subscriptions table:
    • Creates new subscription record with status active
    • Records payment information
    • Sets start and end dates
  2. Update profiles table:
    • Sets has_active_subscription = true
    • Sets current_plan to the selected plan type
    • Sets subscription_end_date to the expiration date

Row Level Security (RLS)

The subscription is created with proper RLS policies:
  • Users can only create subscriptions for themselves (verified via auth.uid())
  • Users can only view their own subscriptions
  • Subscription data is protected and isolated per user

Usage in Payment Flow

This endpoint is typically called after payment confirmation:
// 1. User completes payment via MercadoPago
// 2. Payment webhook or success page calls this endpoint

async function handlePaymentSuccess(paymentId: string, planType: string) {
  const { data: { session } } = await supabase.auth.getSession();
  
  const response = await fetch('/api/subscription/create', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${session?.access_token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      planType: planType,
      paymentProvider: 'mercadopago',
      paymentReference: paymentId,
      amountPaid: getPlanPrice(planType)
    })
  });
  
  if (response.ok) {
    const { subscription } = await response.json();
    // Redirect to dashboard
    window.location.href = '/dashboard';
  }
}

Subscription Plans Reference

Plan TypeDurationPrice (COP)Features
PLAN_BASICO1 month49,9007-day meal plan, home workout routine, app access, email support
PLAN_PRO1 month89,900Personalized meal plan, gym + home routines, exercise videos, priority support, weekly tracking
PLAN_PREMIUM1 month149,900All Pro features + 1-on-1 coaching, monthly adjustments, VIP community access, results guarantee

Build docs developers (and LLMs) love