Promotions
Create discounts and coupon codes. Apply percentage or fixed-amount promotions to orders with configurable limits and validity periods.
Promotion Model
class Promotion {
id: string; // Unique UUID identifier
name: string; // Promotion name (e.g. "Summer Sale")
description: string | null; // Optional description
discountType: DiscountType; // Type of discount
discountValue: number; // Discount amount (percentage or cents)
minOrderAmount: number | null; // Minimum order total in cents (optional)
maxDiscountAmount: number | null; // Maximum discount cap in cents (optional)
validFrom: Date; // Start date
validTo: Date; // End date
isActive: boolean; // Active status (default: true)
}
enum DiscountType {
PERCENTAGE // Percentage off (e.g. 10 = 10%)
FIXED_AMOUNT // Fixed amount off in cents (e.g. 500 = $5.00)
}Coupon Model
class Coupon {
id: string; // Unique UUID identifier
code: string; // Unique coupon code (e.g. "SAVE10")
promotionId: string; // Associated promotion ID
maxUses: number | null; // Maximum number of uses (null = unlimited)
currentUses: number; // Current number of times used (default: 0)
isActive: boolean; // Active status (default: true)
}Promotion Operations
Create Promotions
Percentage discount:
import { createServices } from "commercio";
const { promotionService } = createServices();
// Create a 10% off promotion
const promo = await promotionService.createPromotion({
name: "Summer Sale",
description: "10% off all orders this summer",
discountType: "PERCENTAGE",
discountValue: 10, // 10%
minOrderAmount: 5000, // Minimum $50.00 order
maxDiscountAmount: 2000, // Cap discount at $20.00
validFrom: new Date("2026-06-01"),
validTo: new Date("2026-08-31"),
});
console.log(promo.id); // UUID
console.log(promo.name); // "Summer Sale"
console.log(promo.discountType); // "PERCENTAGE"
console.log(promo.discountValue); // 10
console.log(promo.minOrderAmount); // 5000
console.log(promo.maxDiscountAmount); // 2000
console.log(promo.isActive); // trueFixed amount discount:
// Create a $5 off promotion
const fixedPromo = await promotionService.createPromotion({
name: "Welcome Discount",
description: "$5 off your first order",
discountType: "FIXED_AMOUNT",
discountValue: 500, // $5.00 in cents
minOrderAmount: 2000, // Minimum $20.00 order
validFrom: new Date("2026-01-01"),
validTo: new Date("2026-12-31"),
});
console.log(fixedPromo.discountType); // "FIXED_AMOUNT"
console.log(fixedPromo.discountValue); // 500Discount Values
For PERCENTAGE discounts, the value is the percentage (e.g. 10 = 10%). For FIXED_AMOUNT discounts, the value is in cents (e.g. 500 = $5.00).
Complete Example
import { createServices } from "commercio";
const { promotionService } = createServices();
// 1. Create a 10% off promotion
const summerSale = await promotionService.createPromotion({
name: "Summer Sale 2026",
description: "10% off orders over $50",
discountType: "PERCENTAGE",
discountValue: 10,
minOrderAmount: 5000,
maxDiscountAmount: 2000,
validFrom: new Date("2026-06-01"),
validTo: new Date("2026-08-31"),
});
// 2. Create a coupon code for the promotion
const coupon = await promotionService.createCoupon({
code: "SUMMER10",
promotionId: summerSale.id,
maxUses: 500,
});
// 3. Customer enters coupon at checkout
const orderTotal = 12000; // $120.00
const result = await promotionService.applyCoupon("SUMMER10", {
orderAmount: orderTotal,
});
console.log(`Order total: $${orderTotal / 100}`); // $120.00
console.log(`Discount: $${result.discountAmount / 100}`); // $12.00
console.log(`Final amount: $${result.finalAmount / 100}`); // $108.00
// 4. Check coupon usage
const used = await promotionService.getCouponByCode("SUMMER10");
console.log(`Uses: ${used.currentUses}/${used.maxUses}`); // "Uses: 1/500"
// 5. View all valid promotions
const valid = await promotionService.getValidPromotions();
console.log(`Active promotions: ${valid.length}`);
// 6. End of season: deactivate the promotion
await promotionService.deactivatePromotion(summerSale.id);Best Practices
1. Set Maximum Discount Caps
Always set a maxDiscountAmount on percentage promotions to limit exposure on high-value orders:
// Good: Cap the discount
const promo = await promotionService.createPromotion({
name: "Flash Sale",
discountType: "PERCENTAGE",
discountValue: 20,
maxDiscountAmount: 5000, // Cap at $50 max discount
validFrom: new Date("2026-04-01"),
validTo: new Date("2026-04-02"),
});2. Use Minimum Order Amounts
Require a minimum order amount to prevent abuse of discount codes:
// Require at least $25 to use the coupon
const promo = await promotionService.createPromotion({
name: "Small Discount",
discountType: "FIXED_AMOUNT",
discountValue: 500, // $5.00 off
minOrderAmount: 2500, // Minimum $25.00 order
validFrom: new Date("2026-01-01"),
validTo: new Date("2026-12-31"),
});3. Limit Coupon Usage
Set maxUses on coupons to control how many times they can be redeemed:
// Limited-use coupon for a flash sale
const coupon = await promotionService.createCoupon({
code: "FLASH50",
promotionId: promo.id,
maxUses: 50, // First 50 customers only
});
// Check remaining uses
const current = await promotionService.getCouponByCode("FLASH50");
const remaining = current.maxUses - current.currentUses;
console.log(`${remaining} uses remaining`);4. Use Clear Coupon Codes
Use memorable, descriptive coupon codes that customers can easily type:
// Good: Clear and descriptive
await promotionService.createCoupon({ code: "SUMMER10", ... });
await promotionService.createCoupon({ code: "WELCOME5", ... });
await promotionService.createCoupon({ code: "FREESHIP", ... });
// Avoid: Hard to remember
await promotionService.createCoupon({ code: "X7K9M2P", ... });