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

# External Discount Codes

> Learn how to create discounts programmatically via API using external discount codes

# External Discount Codes

## Overview

**External Discount Codes** allow you to create discounts dynamically through APIs without pre-configuring discount codes in the admin portal. This feature is perfect for programmatic discount management, API integrations, and dynamic pricing strategies.

### Key Features

* ✅ **Dynamic Creation**: No need to pre-create discount codes in the admin portal
* ✅ **API-Based**: Create discounts programmatically via Merchant API or User API
* ✅ **Flexible Types**: Support both fixed amount and percentage discounts
* ✅ **One-time or Recurring**: Choose between single-use or recurring discounts
* ✅ **Automatic Code Generation**: System automatically generates unique discount codes
* ✅ **Metadata Support**: Attach custom metadata for tracking and analysis

### When to Use External Discount Codes

**Perfect for:**

* **API Integrations**: Third-party systems that need to apply discounts automatically
* **Dynamic Pricing**: Real-time price adjustments based on user attributes or market conditions
* **Personalized Offers**: Custom discounts for specific users without creating codes in advance
* **A/B Testing**: Test different discount strategies programmatically
* **Promotion Automation**: Automated discount creation based on business rules

**Not suitable for:**

* **Public Marketing Campaigns**: Use Standard or Batch discount codes instead
* **Checkout Page**: Checkout API doesn't support external discounts (use pre-created codes)
* **Bulk Tracking**: When you need to track usage across many customers

***

## External vs Internal Discount Codes

### Quick Comparison

| Feature               | Internal Discount Codes | External Discount Codes     |
| --------------------- | ----------------------- | --------------------------- |
| **Creation Method**   | Admin portal            | API only                    |
| **Pre-configuration** | Required                | Not needed                  |
| **Code Format**       | Custom name             | Auto-generated (`excode_*`) |
| **Reusability**       | Can be reused           | Single-use (per user)       |
| **Usage Limits**      | Supported               | Not supported               |
| **API Support**       | All APIs                | Merchant & User API only    |

### When to Choose Which

**Use Internal Discount Codes when:**

* Creating public marketing campaigns
* Need usage limits and restrictions
* Want customers to enter codes manually
* Need to track bulk usage

**Use External Discount Codes when:**

* Integrating with third-party systems
* Need programmatic discount creation
* Providing personalized offers
* Dynamic pricing requirements

***

## API Support

### Supported APIs

| API              | External Discount Support | Notes                                             |
| ---------------- | ------------------------- | ------------------------------------------------- |
| **Merchant API** | ✅ Full support            | Complete external discount functionality          |
| **User API**     | ✅ Full support            | Complete external discount functionality          |
| **Checkout API** | ❌ Not supported           | Only supports pre-created internal discount codes |

> ⚠️ **Important**: Checkout API doesn't support external discounts. If you need discounts on checkout pages, pre-create discount codes in the admin portal and use the `discountCode` parameter.

***

## How External Discounts Work

### Automatic Code Generation

When you create an external discount via API, the system automatically:

1. Generates a unique discount code (format: `excode_{merchantId}_{userId}_{source}_{timestamp}{random}`)
2. Creates the discount with your specified rules
3. Activates the discount immediately
4. Applies it to the subscription or purchase

**Example Generated Code**:

```
excode_123_456_789_1704355200000Xy7k9mN3
```

### Discount Parameters

When creating an external discount, you specify:

| Parameter              | Type    | Description                                      | Example                       |
| ---------------------- | ------- | ------------------------------------------------ | ----------------------------- |
| **recurring**          | boolean | One-time or recurring discount                   | `false` = one-time            |
| **discountAmount**     | integer | Fixed discount amount (in cents)                 | `1000` = \$10.00              |
| **discountPercentage** | integer | Percentage discount (100 = 1%)                   | `2000` = 20%                  |
| **cycleLimit**         | integer | Number of billing cycles (recurring only)        | `3` = 3 months                |
| **endTime**            | integer | Expiration time (Unix timestamp, recurring only) | `1767225599`                  |
| **metadata**           | object  | Custom metadata for tracking                     | `{"campaign": "summer_sale"}` |

***

## Usage Scenarios

### Scenario 1: First Order Discount (One-time)

Give new customers a 20% discount on their first purchase.

**Example**:

```json theme={null}
{
  "planId": 123,
  "userId": 456,
  "discount": {
    "recurring": false,
    "discountPercentage": 2000,
    "metadata": {
      "campaign": "first_order_20_off"
    }
  }
}
```

**Result**: Customer gets 20% off first payment only.

***

### Scenario 2: Recurring Discount (First 3 Months)

Offer 15% off for the first 3 billing cycles.

**Example**:

```json theme={null}
{
  "planId": 123,
  "userId": 456,
  "discount": {
    "recurring": true,
    "discountPercentage": 1500,
    "cycleLimit": 3,
    "metadata": {
      "campaign": "first_quarter_promotion"
    }
  }
}
```

**Result**: Customer gets 15% off for months 1-3, then pays full price.

***

### Scenario 3: VIP Lifetime Discount

Provide permanent 10% discount for VIP customers.

**Example**:

```json theme={null}
{
  "planId": 123,
  "userId": 456,
  "discount": {
    "recurring": true,
    "discountPercentage": 1000,
    "cycleLimit": 0,
    "metadata": {
      "user_type": "vip",
      "reason": "lifetime_discount"
    }
  }
}
```

**Result**: Customer gets 10% off every billing cycle indefinitely.

***

### Scenario 4: Time-Limited Campaign

Offer 25% discount until end of year.

**Example**:

```javascript theme={null}
// Calculate end time (Dec 31, 2025 23:59:59 UTC)
const endTime = new Date('2025-12-31T23:59:59Z').getTime() / 1000;

{
  "planId": 123,
  "userId": 456,
  "discount": {
    "recurring": true,
    "discountPercentage": 2500,
    "endTime": endTime,
    "metadata": {
      "campaign": "year_end_sale_2025"
    }
  }
}
```

**Result**: Customer gets 25% off until Dec 31, 2025, then pays full price.

***

## Creating External Discounts

### Subscription Creation

When creating a subscription via API, include the `discount` parameter:

**Merchant API**: `POST /api/merchant/subscription/create_submit`

```json theme={null}
{
  "planId": 123,
  "userId": 456,
  "discount": {
    "recurring": false,
    "discountAmount": 1000
  },
  "confirmTotalAmount": 9000,
  "confirmCurrency": "USD"
}
```

### Subscription Update

Apply discount when upgrading or downgrading a subscription:

**Merchant API**: `POST /api/merchant/subscription/update_submit`

```json theme={null}
{
  "subscriptionId": "sub_xxxxx",
  "newPlanId": 789,
  "discount": {
    "recurring": true,
    "discountPercentage": 1500,
    "cycleLimit": 6
  },
  "confirmTotalAmount": 8500,
  "confirmCurrency": "USD"
}
```

### Subscription Renewal

Apply discount during subscription renewal:

**Merchant API**: `POST /api/merchant/subscription/renew`

```json theme={null}
{
  "subscriptionId": "sub_xxxxx",
  "discount": {
    "recurring": false,
    "discountAmount": 500
  }
}
```

***

## Discount Parameters Explained

### Fixed Amount vs Percentage

**Fixed Amount (`discountAmount`)**:

* Use when you want a specific dollar amount off
* Example: "\$10 off" regardless of order total
* Best for: Consistent promotional offers

**Percentage (`discountPercentage`)**:

* Use when you want a percentage off
* Format: `100 = 1%`, `1000 = 10%`, `10000 = 100%`
* Best for: Scaling discounts with order value

> ⚠️ **Priority**: If both are specified, `discountAmount` takes priority.

### One-time vs Recurring

**One-time (`recurring: false`)**:

* Discount applies only to the first invoice
* Perfect for: Welcome offers, sign-up bonuses
* Cannot use `cycleLimit` or `endTime`

**Recurring (`recurring: true`)**:

* Discount applies to multiple billing cycles
* Perfect for: Long-term promotions, VIP discounts
* Can use `cycleLimit` or `endTime` to control duration

### Cycle Limit

**What it does**: Limits how many billing cycles the discount applies

**Examples**:

* `cycleLimit: 1` - First cycle only
* `cycleLimit: 3` - First 3 cycles
* `cycleLimit: 0` - No limit (until `endTime` or subscription ends)

**Only works when**: `recurring: true`

### End Time

**What it does**: Sets expiration date for the discount

**Format**: Unix timestamp (seconds since Jan 1, 1970)

**Example**:

```javascript theme={null}
// Discount expires Dec 31, 2025 at 11:59:59 PM UTC
const endTime = new Date('2025-12-31T23:59:59Z').getTime() / 1000;
```

**Only works when**: `recurring: true`

### Metadata

**What it does**: Stores custom information about the discount

**Use cases**:

* Track discount source
* Store campaign information
* Record business logic tags
* Enable reporting and analytics

**Example**:

```json theme={null}
{
  "metadata": {
    "campaign": "summer_sale",
    "source": "partner_api",
    "reason": "vip_customer",
    "notes": "Special discount for premium users"
  }
}
```

***

## Best Practices

### 1. Always Preview Before Submitting

Use the preview API to check discount calculations before finalizing:

```javascript theme={null}
// Step 1: Preview
const preview = await createSubscriptionPreview({
  planId: 123,
  discount: {
    recurring: true,
    discountPercentage: 2000
  }
});

// Step 2: Confirm with preview amount
const result = await createSubscription({
  planId: 123,
  discount: {
    recurring: true,
    discountPercentage: 2000
  },
  confirmTotalAmount: preview.totalAmount,
  confirmCurrency: preview.currency
});
```

### 2. Choose the Right Discount Type

**Use Fixed Amount when:**

* Offering consistent dollar-off promotions
* Order values vary significantly
* Need precise control over discount amount

**Use Percentage when:**

* Discount should scale with order value
* Running percentage-based campaigns
* Want simpler calculation

### 3. Set Appropriate Limits

**Cycle Limit Guidelines:**

* Short-term: 1-3 cycles
* Quarterly: 3 cycles
* Semi-annual: 6 cycles
* Annual: 12 cycles
* Unlimited: 0 (use carefully)

### 4. Use Metadata Effectively

Track important information in metadata:

* Campaign name
* Discount source
* User segment
* Business reason

This helps with reporting and analysis later.

### 5. Handle Errors Properly

Common errors to handle:

* Invalid discount percentage (must be 0-100%)
* Missing required parameters
* Invalid time settings
* Conflicting discount types

***

## Validation Rules

### Required Parameters

You must specify at least one discount type:

* ✅ `discountAmount` OR
* ✅ `discountPercentage`

### Discount Percentage

**Valid range**: Greater than 0 and less than or equal to 10000

* `100` = 1%
* `1000` = 10%
* `10000` = 100%

**Invalid examples**:

* ❌ `0` - Cannot be zero
* ❌ `15000` - Cannot exceed 100%

### Discount Amount

**Must be**: Greater than 0 (in cents)

**Automatically limited**: System won't allow discount to exceed order total

### Recurring Discount Rules

**cycleLimit**:

* Only valid when `recurring: true`
* Must be greater than or equal to 0
* `0` = unlimited (until `endTime` or subscription ends)

**endTime**:

* Only valid when `recurring: true`
* Must be a future time (Unix timestamp)
* Must be greater than or equal to current time

***

## Common Use Cases

### Use Case 1: API Integration Discount

Third-party system automatically applies discount based on user tier:

```json theme={null}
{
  "planId": 123,
  "userId": 456,
  "discount": {
    "recurring": true,
    "discountPercentage": 1500,
    "cycleLimit": 0,
    "metadata": {
      "source": "partner_api",
      "user_tier": "gold",
      "partner_id": "partner_123"
    }
  }
}
```

### Use Case 2: Dynamic Pricing

Adjust price based on market conditions or user behavior:

```json theme={null}
{
  "planId": 123,
  "userId": 456,
  "discount": {
    "recurring": false,
    "discountPercentage": 2500,
    "metadata": {
      "campaign": "dynamic_pricing",
      "discount_reason": "high_value_user",
      "market_condition": "competitive"
    }
  }
}
```

### Use Case 3: Win-Back Campaign

Offer discount to win back churned customers:

```json theme={null}
{
  "planId": 123,
  "userId": 456,
  "discount": {
    "recurring": true,
    "discountPercentage": 3000,
    "cycleLimit": 3,
    "metadata": {
      "campaign": "win_back",
      "churn_reason": "price",
      "win_back_date": "2025-01-15"
    }
  }
}
```

***

## Limitations and Considerations

### Checkout API Restriction

**Important**: Checkout API does NOT support external discounts.

If you need discounts on checkout pages:

1. **Option 1**: Pre-create discount codes in admin portal, then use `discountCode` parameter
2. **Option 2**: Use Merchant API or User API instead of Checkout API

### Single User Only

External discounts are created per user/subscription:

* Cannot be shared across multiple users
* Cannot set usage limits (quantity limits)
* Each discount is user-specific

### Cannot Combine with Internal Codes

If both `discountCode` (internal) and `discount` (external) are provided:

* External discount takes priority
* Internal discount code is ignored

***

## Troubleshooting

### Error: "one of discountAmount or discountPercentage should specified"

**Problem**: Missing discount type specification

**Solution**: Provide either `discountAmount` or `discountPercentage`

```json theme={null}
// ❌ Wrong
{
  "discount": {
    "recurring": true
  }
}

// ✅ Correct
{
  "discount": {
    "recurring": true,
    "discountPercentage": 2000
  }
}
```

### Error: "invalid discountPercentage"

**Problem**: Percentage out of valid range (0-10000)

**Solution**: Use valid percentage value

```json theme={null}
// ❌ Wrong (150% is invalid)
{
  "discountPercentage": 15000
}

// ✅ Correct (100% is maximum)
{
  "discountPercentage": 10000
}
```

### Error: "cycleLimit not available as recurring not enable"

**Problem**: Trying to set cycle limit without enabling recurring

**Solution**: Set `recurring: true` or remove `cycleLimit`

```json theme={null}
// ❌ Wrong
{
  "discount": {
    "recurring": false,
    "discountPercentage": 2000,
    "cycleLimit": 3
  }
}

// ✅ Correct
{
  "discount": {
    "recurring": true,
    "discountPercentage": 2000,
    "cycleLimit": 3
  }
}
```

### Error: "endTime not available as recurring not enable"

**Problem**: Trying to set end time without enabling recurring

**Solution**: Set `recurring: true` or remove `endTime`

***

## Related Topics

* [Discount Code Introduction](./discount-code-introduction) - Overview of all discount types
* [Standard Discount Codes](./create-edit-copy-and-archive) - Creating discount codes in admin portal
* [Batch Discount Codes](./batch-discount-codes) - Bulk discount code generation

***

## API Reference

For detailed API documentation, see:

* [Subscription Create Preview](/api-reference/subscription/create-subscription-preview)
* [Subscription Create Submit](/api-reference/subscription/create-subscription)
* [Subscription Update Preview](/api-reference/subscription-update/update-subscription-preview)
* [Subscription Update Submit](/api-reference/subscription-update/update-subscription)
* [Subscription Renew](/api-reference/subscription-update/renew-subscription)
