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
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:
- Generates a unique discount code (format:
excode_{merchantId}_{userId}_{source}_{timestamp}{random})
- Creates the discount with your specified rules
- Activates the discount immediately
- 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:
{
"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:
{
"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:
{
"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:
// 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
{
"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
{
"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
{
"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:
// 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
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:
{
"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:
// 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)
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:
{
"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:
{
"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:
{
"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:
- Option 1: Pre-create discount codes in admin portal, then use
discountCode parameter
- 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
// ❌ 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
// ❌ 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
// ❌ 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
API Reference
For detailed API documentation, see: