Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt

Use this file to discover all available pages before exploring further.

Discount codes overview cover
Discount codes let you run targeted promotions and incentives. Create percentage or fixed-amount discounts, set limits and expirations, restrict to products, and apply them seamlessly in checkout.

Checkout Sessions

Apply one or more stacked codes during hosted checkout with discount_codes and UI controls.

Validate Discount

Check if a discount is valid by its ID.

Get Discount by Code

Look up and validate a discount using its code name (e.g., “SAVE20”).

Create Discount (API)

Programmatically create new discount codes.

List & Update Discounts

Browse and manage existing discounts; update or delete as needed.

Plan Change Discounts

Apply discount codes when upgrading or downgrading subscription plans.

What Are Discount Codes?

Discount codes are promotional tokens that reduce order totals at checkout. They’re ideal for:
  • Seasonal campaigns: Black Friday, product launches, or anniversaries
  • Acquisition offers: First‑purchase incentives or referral rewards
  • Retention: Win‑back or loyalty rewards for existing customers
  • B2B deals: Contracted or negotiated pricing via private codes

Key Benefits

  • Flexible discounts: Percentage or fixed amount off
  • Stackable codes: Apply up to 20 codes per checkout, payment, or subscription — combine campaigns (e.g. WELCOME10 + BLACKFRIDAY20) without creating bespoke codes
  • Targeted control: Restrict by product and subscription cycles
  • Campaign governance: Expiration dates and usage limits
  • Seamless checkout: UI field and API support via checkout sessions

Creating Discount Codes

Create discount codes in your Dodo Payments dashboard, then apply them in hosted checkout or via API.

Dashboard setup

  • Discount Name (required): Internal and dashboard display name
  • Code (required): The string customers enter at checkout
  • Type & Amount (required): Set a percentage or fixed‑amount value, or generate a random code using the button provided
  • Expiration Date (optional): Date after which the code becomes invalid
  • Usage Limit (optional): Max total redemptions across all customers
  • Product Restriction (optional): Limit applicability to selected products
  • Subscription Cycle Limit (optional): Number of billing cycles the discount applies to
  • Metadata (optional): Attach custom key–value pairs for internal tracking or integrations
Use cycle limits for introductory pricing on subscriptions (e.g., “50% off for 3 months”).

Checkout Experience

  1. Shoppers enter the code in the checkout field.
  2. Eligible discounts are applied and totals update immediately.
In Checkout Sessions, pass discount_codes (an array) to pre‑apply one or more codes, and set feature_flags.allow_discount_code to show the input field. Codes are applied in array order, up to a maximum of 20.

Stacking Discount Codes

Checkout sessions, payments, and subscriptions accept up to 20 stacked codes via the discount_codes array (max 20 entries). Codes are applied in array order, so the first eligible code reduces the base price first, the next code reduces the already-discounted price, and so on. The full set of applied discounts is returned in the response under discount_ids (on payments/subscriptions) and discounts (richer per-discount detail, including position and remaining subscription cycles).
const session = await client.checkoutSessions.create({
  product_cart: [{ product_id: 'prod_abc', quantity: 1 }],
  discount_codes: ['WELCOME10', 'BLACKFRIDAY20'], // applied in this order
  customer: { email: 'user@example.com' },
  return_url: 'https://yoursite.com/return'
});
The singular discount_code field is deprecated but still fully supported for backward compatibility — existing integrations continue to work without changes. It cannot be combined with discount_codes in the same request. We recommend migrating to discount_codes (the array form) when convenient, even for single codes, to take advantage of stacking and the richer response shape.

API Management

Create discount codes programmatically with type and amount.

API Reference

View the create discount API.
List all discounts or retrieve details for management and auditing.

API Reference

Browse listing and retrieval APIs.
Look up a discount using its human-readable code (e.g., “SAVE20”) instead of the internal ID.

API Reference

Retrieve discount by code name.
Modify discount configuration such as amount, expiration, or restrictions.

API Reference

Learn how to update discount details.
Check whether a discount is valid and applicable before applying.

API Reference

Validate discount usage.
Deactivate or remove discounts that are no longer needed.

API Reference

Delete a discount.

Common Use Cases

  • Intro offers: Limited‑time launch promotions for new products
  • Bulk or B2B: Contracted discounts for select product sets
  • Retention plays: Win‑back codes in churn‑prevention workflows
  • Seasonal campaigns: Holiday or event‑based promotions

Integration Examples

Create a discount with metadata

Attach custom key–value pairs for internal tracking.
const discount = await client.discounts.create({
  type: 'percentage',
  amount: 1500, // 15%
  code: 'SUMMER2025',
  metadata: {
    campaign: 'summer_promo',
    source: 'email_blast'
  }
});
Use metadata to tag discounts by campaign, source, or internal reference ID so you can reconcile usage and measure ROI later.

Apply discounts in Checkout Sessions

Pre‑apply one or more stacked discounts and show the code input UI.
const session = await client.checkoutSessions.create({
  product_cart: [
    { product_id: 'prod_abc', quantity: 1 }
  ],
  discount_codes: ['BLACKFRIDAY2024', 'NEWUSER5'], // stacked in array order
  customer: { email: 'user@example.com', name: 'Jane Doe' },
  return_url: 'https://yoursite.com/return'
});

Apply discounts during plan changes

Offer promotional pricing when customers upgrade or downgrade their subscription.
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'prorated_immediately',
  discount_codes: ['UPGRADE20']
});
discount_codes valueBehavior on plan change
undefined / null (not provided)Existing discounts with preserve_on_plan_change=true are preserved if applicable to the new product.
[] (empty array)All existing discounts are removed from the subscription.
['CODE_A', 'CODE_B', ...]Replaces any existing discounts with this stacked set, applied in array order.
Read all applied discounts off the subscription via the new discounts array on the subscription response. Each entry includes discount_id, position, cycles_remaining (for subscriptions), and the original code.

Enable discount entry without pre‑applying

Let customers enter a code at checkout without passing one upfront.
const session = await client.checkoutSessions.create({
  product_cart: [
    { product_id: 'prod_abc', quantity: 1 }
  ],
  feature_flags: {
    allow_discount_code: true
  },
  return_url: 'https://yoursite.com/return'
});

Best Practices

  • Name clearly: Use recognizable codes that match campaign names
  • Time‑box: Add expirations to drive urgency and prevent misuse
  • Scope wisely: Limit to specific products to avoid margin leakage
  • Validate early: Check code applicability before confirming checkout
  • Monitor impact: Track usage and conversion by campaign
Discount codes are powerful levers for acquisition and retention. Start with simple, well‑named offers, validate thoroughly, and iterate based on performance.
Last modified on May 18, 2026