Campaign & Offer Management
TanStack Ship campaign management system for creating discount offers, coupon codes, UTM-based automatic matching, and promotional pricing campaigns.
Overview
The campaign and offer management system in TanStack Ship enables sophisticated marketing promotions that drive conversions and customer engagement. It provides a complete toolkit for creating time-bound campaigns, defining multi-type discount offers, generating coupon codes, and tracking redemption performance — all managed from the admin dashboard.
As part of the platform, the campaign system integrates with UTM tracking for automatic offer matching based on traffic source, the pricing engine for dynamic discount application during checkout, and the billing system for Stripe-integrated coupon processing.
Campaign Lifecycle
Each campaign follows a structured lifecycle from creation through expiration:
Design Philosophy
The campaign and offer system is built on three design principles:
- Composable Discount Engine — Discounts from different sources (percentage, fixed amount, credit grant) are evaluated in a defined priority chain. Each source operates independently, enabling complex promotional strategies without modifying core pricing logic. Unlike Voucherify — which requires external API calls and webhook integrations for discount validation — our built-in offer engine evaluates pricing rules server-side within your own database, eliminating latency and third-party dependencies from the checkout flow.
- UTM-First Auto-Matching — Offers are automatically matched to users based on UTM parameters before checkout begins. This creates a zero-friction discount experience — users never need to find or enter a coupon code.
- Time-Boxed Campaigns — Every campaign has an explicit start and end date. The system automatically activates and deactivates offers based on these schedules, ensuring promotional pricing is never accidentally left running.
Core Capabilities
Campaign Management
Campaigns are high-level marketing initiatives that group together offers, UTM parameters, and targeting rules. Each campaign includes:
- Name & Description — Internal name for admin reference and customer-facing promotional text
- Date Range — Start and end dates for automatic activation and expiration
- UTM Parameters — Source, medium, and campaign name for attribution tracking
- Active Status — Toggle campaigns on and off without deleting configuration
- Holiday Association — Link campaigns to holiday schedules for seasonal promotions
Campaigns can be previewed before activation to verify configured offers and UTM links.
Offer Types
Three offer types are supported, each with distinct use cases:
| Type | Description | Best Use Case |
|---|---|---|
| Percentage | Discount by percentage off the base price | Seasonal sales, first-purchase discounts |
| Fixed Amount | Fixed discount in the billing currency | Loyalty rewards, cart-abandonment recovery |
| Credit Grant | Award bonus credit points to user balance | Referral bonuses, engagement incentives |
Offers can be stacked or applied individually, controlled by the pricing engine's priority logic.
Coupon Code System
Each offer can have one or more coupon codes with granular configuration:
- Custom Codes — Define brand-aligned codes (e.g.,
LAUNCH2024,SUMMER20) - Auto-generated Codes — System-generated unique codes for individual distribution
- Public vs. Private — Public codes are listed on the pricing page; private codes require direct sharing
- Plan-Specific Scoping — Limit offers to specific subscription plans (monthly, annual, or both)
- Usage Limits — Set maximum redemption counts per code
- Expiration — Individual code expiration independent of parent campaign dates
Example — Coupon code configuration:
{
"code": "WELCOME20",
"type": "percentage",
"value": 20,
"scope": "monthly",
"maxRedemptions": 500,
"expiresAt": "2025-12-31T23:59:59Z",
"visibility": "public"
}
Client-side coupon validation example:
import { useMutation } from '@tanstack/react-query'
import { useState } from 'react'
export function CouponInput() {
const [code, setCode] = useState('')
const validate = useMutation({
mutationFn: async (couponCode: string) => {
const res = await fetch('/api/offers/validate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ code: couponCode }),
})
if (!res.ok) throw new Error('Invalid or expired coupon')
return res.json() as Promise<{
valid: boolean
discount: { type: string; value: number }
description: string
}>
},
})
return (
<div className="rounded-lg border p-4">
<label className="mb-2 block text-sm font-medium">Coupon Code</label>
<div className="flex gap-2">
<input
className="flex-1 rounded-md border px-3 py-2"
value={code}
onChange={(e) => setCode(e.target.value)}
placeholder="Enter code"
/>
<button
className="rounded-md bg-primary px-4 py-2 text-white"
onClick={() => validate.mutate(code)}
>
Apply
</button>
</div>
{validate.isPending && <p className="mt-2 text-sm">Validating...</p>}
{validate.isError && (
<p className="mt-2 text-sm text-red-600">{validate.error.message}</p>
)}
{validate.isSuccess && (
<p className="mt-2 text-sm text-green-600">
{validate.data.description} — {validate.data.discount.value}{validate.data.discount.type === 'percentage' ? '%' : '$'} off
</p>
)}
</div>
)
}
UTM-Based Automatic Matching
When users arrive via a UTM-tagged URL, the system automatically matches them to applicable offers. This enables sophisticated marketing strategies:
- Ad Campaign Pricing — Special pricing for users from specific ad platforms (Google Ads, Facebook, LinkedIn)
- Partner Referrals — Custom UTM codes per partner for trackable referral offers
- A/B Testing — Different offers for different traffic sources to measure conversion performance
- Content Marketing — Exclusive offers for blog readers or newsletter subscribers via unique UTM links
The matching logic evaluates UTM source, medium, and campaign fields against configured campaign rules.
Holiday-Specific Campaigns
Campaigns can be linked to the holiday management system for automatic seasonal activation:
- Create campaigns that activate automatically on configured holidays
- Set different offers for different holidays (e.g., Christmas vs. Black Friday)
- Localize holiday campaigns per market (Germany, China, US)
Best Practices
Campaign Naming Conventions
Use consistent naming patterns: {TYPE}_{TARGET}_{YEAR} — for example, WELCOME_NEWUSER_2024, SALE_SUMMER_2024. This makes filtering and reporting in the admin dashboard significantly easier.
Limited-Time Offers
Always set explicit start and end dates. Time-limited offers create urgency and improve conversion rates. Expired campaigns deactivate automatically, so no manual cleanup is needed.
Test UTM Matching
Before launching a campaign, test your UTM links by simulating a visit with the configured parameters. Verify that the correct offer is applied during checkout.
Offer Stacking Strategy
Decide whether offers can stack (multiple discounts applied) or are mutually exclusive. Stacking should be limited to avoid margin erosion.
Frequently Asked Questions
How do I create a new campaign? Navigate to the campaign management page in the admin dashboard and click "New Campaign". Fill in the name, description, date range, and optional UTM parameters. Then create offers and associate them with the campaign.
Can I have multiple offers in one campaign? Yes. A campaign can contain multiple offers of different types. For example, a summer sale might include both a percentage discount and a credit grant.
How are offers applied during checkout? The pricing engine evaluates all active offers applicable to the user and plan. If a UTM-matched campaign is detected, its offer takes priority. Otherwise, the highest-value general offer is applied.
Can I limit an offer to new users only? Yes. Offers can be scoped to new users by configuring eligibility rules. The system checks registration date and subscription history when evaluating offer applicability.
How do I track campaign performance? The admin dashboard provides campaign analytics with metrics including offer redemptions, conversion rates, revenue impact, and UTM attribution data.
What happens when a campaign expires? Expired campaigns are automatically deactivated. Active offers within the campaign stop being applied. Historical redemption data is preserved.
Can I use the same coupon code across multiple campaigns? No, each coupon code belongs to a single offer within a single campaign. This prevents ambiguity in attribution tracking.
Configuration
Campaigns and offers are managed entirely from the admin dashboard. No environment variables are required specifically for campaigns — the system uses the existing billing and UTM configuration.
Integration Points
The campaign system integrates with these platform modules:
- Pricing Engine — Offers dynamically adjust prices during checkout
- UTM Tracking — Campaigns link to UTM parameters for automatic offer matching
- Billing — Discounts are applied at Stripe Checkout via coupon code integration
- Analytics Dashboard — Track offer redemption rates, campaign ROI, and conversion metrics
- Short Links — Create trackable short links for campaign distribution
- Holiday System — Link campaigns to holiday schedules for automated promotions
- Credit System — Credit grant offers award points to user balances