# Coupon Apply
URL: https://remocn.dev/docs/product-scenes/coupon-apply

A checkout order summary rejects one coupon, accepts another and the total drops

- Install: `npx shadcn@latest add @remocn/coupon-apply`
- Vibe: clean
- Natural length: 155f @ 30fps

## Installation

```bash
npx shadcn@latest add @remocn/coupon-apply
```

## Usage

```tsx
// src/Root.tsx
import { Composition } from "remotion";
import { CouponApply } from "@/components/remocn/coupon-apply";

const CouponApplyScene = () => (
  <CouponApply merchant="Orbit" code="WELCOME20" invalidCode="WELCOME" percentOff={20} />
);

export const RemotionRoot = () => (
  <Composition
    id="CouponApply"
    component={CouponApplyScene}
    durationInFrames={180}
    fps={30}
    width={1280}
    height={720}
  />
);
```

An order summary and a payment form appear side by side. A cursor types a code that is rejected with a shake, retypes a valid one, the discount chip lands, the old total is struck through and the new total rolls in before the pay button lights up. Pass `merchant`, `items` (name, detail, amount), `invalidCode`, `code` and `percentOff`. The `theme` prop ships light and dark.

The ground is a live gradients.sh shader (`GshGround`), installed with the component as `@remocn/gsh`. Pick another look with the `ground` preset prop.

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `merchant` | `string` | `"Lumen"` | Merchant name shown at the top of the order summary. |
| `items` | `CouponLineItem[]` | `DEFAULT_ITEMS` | Order line items with name, detail and numeric amount. |
| `invalidCode` | `string` | `"LAUNCH"` | First attempt, rejected with a shake. Set to "" to skip the invalid beat. |
| `code` | `string` | `"LAUNCH24"` | Code that works. If it starts with `invalidCode`, only the rest is typed on retry. |
| `percentOff` | `number` | `10` | Discount percentage applied to the subtotal. |
| `currency` | `string` | `"$"` | Currency symbol placed before amounts. |
| `payLabel` | `string` | `"Subscribe"` | Text on the pay button. |
| `email` | `string` | `"maya@kitebase.com"` | Email address shown in the payment form. |
| `cardholder` | `string` | `"Maya Chen"` | Cardholder name shown in the payment form. |
| `theme` | `"light" \| "dark"` | `"light"` | Light or dark checkout styling. |
| `accent` | `string` | `"#3B5BFD"` | Accent color for the pay button and focus states. |
| `speed` | `number` | `1` | Playback speed multiplier for the whole timeline. |
| `ground` | `GshPresetId` | — | Preset id for the shader background. |
| `groundParams` | `Partial<GradientParams>` | — | Overrides for the shader background parameters. |

## Use when
- A billing or subscription launch beat where a discount code visibly lowers the order total.
- Showing a checkout that handles errors gracefully, with a rejected code before the valid one lands.
- A promo or launch-offer video that needs the discount moment shown on a real payment form.

## Don't use when
- The story is the shopper picking a product and adding it to a cart — use `cart-add`.
- You only need a settled invoice with a PAID stamp, no code entry — use `invoice-paid`.