Promo Code Management
Source: internal/api/v1/store/Controllers/promocode.js
Overview
The Promo Code controller manages platform-wide promotional codes that can be assigned to specific customers. Unlike coupons (which are connected account-specific), promo codes are created at the platform level and can be shared across accounts or restricted to individual customers.
Key Capabilities
- Create promo codes linked to coupons
- Assign to specific customers
- Set expiration dates and redemption limits
- Admin-only creation (DashClicks general access required)
- List promo codes for customers
MongoDB Collections
| Collection | Operations | Purpose |
|---|---|---|
_store.promo.codes | CRUD | Promo code storage |
_store.coupons | Read | Coupon validation |
_accounts | Read | Customer validation |
Service Methods
newPromoCode
Creates a new platform promo code linked to an existing coupon.
Authorization: Requires DashClicks general admin access if account_id provided
Request Body:
{
account_id: string, // Optional: target account (admin only)
code: string, // Promo code string
coupon_id: string, // MongoDB coupon _id
max_redemptions: number, // Optional: global redemption limit
expires_at: date // Optional: expiration date
}
Response: Created promo code object
Business Logic:
- Verify DashClicks admin access if
account_idprovided - Check for existing 'DASH20' code (one per account limit)
- Find target account
- Find linked coupon
- Create Stripe promo code with customer assignment
- Save to MongoDB
Special Logic:
// Admin check for account_id
if (req.body.account_id && !req.auth.user.dashclicks?.general) {
throw new Error('ACCESS_FORBIDDEN');
}
// DASH20 limit check (non-owners only)
if (!req.auth.user.is_owner) {
const existingCode = await StorePromoCode.countDocuments({
account: account.id,
code: 'DASH20',
});
if (existingCode) {
throw new Error('PROMOCODE_ALREADY_EXISTS');
}
}
getPromoCodes
Lists promo codes for a customer with optional filtering.
Authorization: Requires DashClicks admin access if account_id query parameter provided
Query Parameters:
{
account_id: string, // Optional: admin only
code: string, // Optional: filter by code
active: boolean // Optional: filter by active status
}
Response: List of promo codes
Business Logic:
- Resolve target account (authenticated or provided)
- Query Stripe with customer filter
- If no customer-specific codes found, search for global codes
- Return first matching global code or empty array
Fallback Logic:
let promoCodes = await stripe.promotionCodes.list({
customer: account.stripe_customer,
code: req.query.code,
});
if (!promoCodes?.data?.length) {
// Try without customer filter (global codes)
promoCodes = await stripe.promotionCodes.list({ code: req.query.code });
const globalCode = promoCodes?.data?.find(c => !c.customer);
promoCodes.data = globalCode ? [globalCode] : [];
}
Edge Cases & Business Rules
1. Platform vs Customer-Specific Codes
Customer-Specific: customer field set to Stripe customer ID
Global: customer field is null (available to all)
2. DASH20 Limitation
Non-owner admins can only create one 'DASH20' code per account. Prevents duplicate onboarding discounts.
3. Coupon Association
Promo codes must link to existing coupons. The coupon defines the actual discount; promo code is just the redemption mechanism.
4. Expiration Handling
Stripe expects Unix timestamps (seconds):
if (req.body.expires_at) {
promoCode.expires_at = Math.ceil(new Date(req.body.expires_at).getTime() / 1000);
}
Related Documentation
- Coupon Management - Coupon creation and validation
- Subscriptions - Promo code application