Coupons and promotions

Share this article

Overview

Coupons are discount codes for your outfitter account. Each code can take either a percentage off or a fixed dollar amount off (USD), with an optional expiration date. New codes are created as one-time-use duration coupons in the dashboard (duration: once in the product implementation)—other duration modes are not exposed in the create form here.

Codes belong to the outfitter, not to an individual listing. When you send a quote (booking invite) or create a booking in the dashboard, you pick a listing first; the coupon picker then loads every coupon for that listing’s outfitter. The GraphQL API does not accept a listing ID when creating a coupon, so this dashboard does not offer per-listing coupon restrictions. If you need a discount to apply only to certain trips, use separate codes or campaigns operationally unless another Mallard Bay surface adds listing rules.

You can manage coupons on the dedicated Coupons page (/coupons) and from My Outfitter → Payments & Financials (the coupons block uses the same add coupon modal).

Not verified from this codebase: how guests enter codes on your public website or booking widget, whether max_redemptions or name are set only on the server, and where reports show coupon usage. The data model includes max_redemptions and name, and the coupons table can display them, but the create form only collects custom code, discount type/amount, and optional expiration.

Prerequisites

  • Coupons on your plan — The Coupons area checks the Coupons feature (FeatureKey.Coupons). If it is off or your account has hit its coupon limit, opening Create Coupon shows upgrade or limit messaging instead of the form (FeatureUpsellModal).
  • Outfitter context — Codes are created for the currently selected outfitter (the modal title is Add coupon for … plus the outfitter name). Users without a selected outfitter may see the all coupons query instead of a single outfitter’s list (implementation switches between couponsByOutfitter and allCoupons).
  • Permissions — In quote and booking flows, New coupon is hidden when dashboard action permissions disallow it (shouldShowActions); other entry points may still be available depending on role.

Step-by-step: Create and manage coupons (`/coupons`)

  1. Open Coupons in the dashboard (/coupons). The page is wrapped in the same Coupons feature gate as creation.
  2. Select Create Coupon in the page header. If you see an upgrade or limit dialog, your plan or coupon count is blocking new codes.
  3. In the modal, complete the form:
    • Custom code — Required (for example a guest-facing code like WINTER20).
    • Discount typePercent off or Amount off.
    • Discount amount — Required; must be greater than zero. For dollar discounts the value is stored as a money amount with USD currency on create.
    • Expiration date — Optional. After this timestamp, the code is treated as expired in selectors (redeem_by compared to the current time).
  4. Submit. The app creates the coupon and refreshes coupon queries.
  5. Use the table search to filter by coupon code (search matches custom_code, case-insensitive).
  6. Review columns where applicable: name, code (with copy control), discount amount, limit (shows max_redemptions when present), expiration, and outfitter (helpful in multi-outfitter contexts).
  7. To remove a code, use delete on the row and confirm. Deletion is permanent once confirmed (confirmation copy comes from COUPON_CONFIRMATION strings).

Step-by-step: Coupons from **My Outfitter**

  1. Go to My Outfitter and open Payments & Financials.
  2. Find the Coupons section.
  3. Use Add coupon from the section menu (same modal as elsewhere; Add coupon can appear locked if the Coupons feature is disabled).
  4. Existing coupons list code, name (or “No name entered”), optional expiration (M/d/yyyy), clipboard copy on the code, and delete.

Step-by-step: Apply a coupon on a **quote (booking invite)**

  1. Start or edit a quote flow and reach the step labeled Payments (this step hosts coupon selection).
  2. Pick a coupon card, or tap New coupon (when allowed) to create one inline; new coupons are applied via the same picker after creation.
  3. Use search and Show expired / Hide expired if you have many codes; expired coupons are disabled with an “expired” tooltip.
  4. Optionally use Editable at checkout for the coupon field so guests can change it when they complete checkout—unless the invite is invoice-style, in which case those toggles are hidden and the backend drives editability.

Step-by-step: Apply a coupon when **creating a booking** (dashboard)

  1. In the create booking flow, open the Payment step (combined Payment information and Coupon UI).
  2. Choose a coupon from the grid; options come from couponsByOutfitter for the selected listing’s outfitter.
  3. When the flow is backed by a quote, changing the coupon triggers applyQuoteCoupon / removeQuoteCoupon (the mutation argument is named couponCode but the dashboard passes the coupon’s internal id—guests still use the custom code).
  4. Finish the flow as usual. Coupons interact with quoted totals and payments for that reservation path.

Implementation note for operators: Coupon changes after a quote exists are applied via those quote mutations. If a selection does not seem to affect totals, confirm the quote/pricing has finished loading and try selecting the coupon again once the quote is present.

Common pitfalls

  • Plan or limitCreate Coupon may open upsell/limit messaging instead of the form even when the Coupons section is visible elsewhere.
  • Expired codes — They appear disabled in pickers; use show expired only if you need to see old codes.
  • No per-listing targeting in this UI — All outfitter coupons can surface for any of that outfitter’s listings in these flows unless enforced outside this dashboard.
  • Display name and redemption limit — The create dialog does not ask for a name or max redemptions; cards may show a blank title where name is empty, and limits only appear if the backend populated them.
  • Inline “New coupon” — Hidden without action permissions even if coupons are enabled.

Related workflows

  • Quotes and booking invites — Optional coupon on the Payments step; editable at checkout controls guest flexibility for the coupon field (non-invoice invites).
  • Bookings and payments — Coupon sits on the Payment step next to payment details; quote-backed bookings sync coupon changes through quote mutations.
  • Listings — Listing choice determines which outfitter’s coupon list loads, linking trips to your codes in practice while codes remain outfitter-owned.

Related knowledge articles

Website performance insights

The Web Performance area (/web-performance) in the Mallard Bay admin dashboard is where you review t...

Read
Mallard Bay Logo
Pricing
Mallard Bay Logo

Quick Links

Pricing

Sitemap

FAQs

Get in Touch

+1 (225) 831-8219

sales@mallardbay.com

Made in Houston Texas