Variable-amount gift cards purchasable with any payment method. Code-based redemption at checkout (applied to cart like coupons). Partial use across multiple purchases, never expire. Shop owners control min/max amounts and can disable individual cards. Models: GiftCard, GiftCardTransaction, CartGiftCard + migration. Views: purchase page, cart apply/remove, shop admin manage/detail/toggle. Templates: gift_card.j2, gift_card_manage.j2, gift_card_detail.j2. Cart integration: gift cards deduct after coupons in all checkout paths. Tests: 10 new unit tests covering model logic (677 total pass).
2.7 KiB
MPS-11: Gift Card System — Purchase Flow
Problem
Buyers need a way to purchase gift cards for a shop. The shop owner sets a min/max amount range, and the buyer picks any amount within that range using a slider. The buyer can optionally enter a recipient email address so the gift card code is delivered to someone else.
Solution
Gift card "product" page
Gift cards are not regular products — they are a shop-level feature. A shop with
gift_card_enabled=True gets a /shop/{slug}/gift-card page.
The page contains:
- Shop name and branding
- Amount slider (range input) with min/max from shop settings
- Manual amount text input (synced with slider for precise entry)
- Optional "Gift to" email field
- Optional gift message (short text, stored on the card)
- "Add to Cart" button
Cart integration
Gift cards are added to the cart as a special line item. Since they have variable
pricing and are not regular products, they need a different storage approach in
json_cart:
Option A: Store gift card items in a separate json_gift_cards column on Cart.
Format: [{"shop_id": "...", "amount_in_cents": 2500, "gift_email": "...", "gift_message": "..."}]
This keeps gift cards cleanly separated from product line items and avoids
polluting the existing json_cart dictionary (which maps product UUIDs to
quantities).
Checkout
When the cart contains gift card items:
- Gift card amounts are included in the cart total
- After successful payment (Stripe, PayPal, or crypto), generate a
MpsGiftCardrecord for each gift card line item - Generate the unique code (
GC-prefix + 16 hex chars) - If
gift_emailis provided, send the code to the recipient - Always show the code to the purchaser in the order confirmation
Email delivery
When gift_email is set, send a simple email to the recipient containing:
- Shop name
- Gift card amount
- The redemption code
- Optional gift message
- Link to the shop
The email is informational only — the code IS the value. No account required.
Files Changed
| File | Change |
|---|---|
views/gift_card.py |
New: gift card page + add-to-cart handler |
templates/gift_card.j2 |
New: gift card purchase page with slider |
static/js/gift_card.js |
New: slider/input sync, amount formatting |
static/css/common.css |
Gift card page styles (using tokens) |
models/cart.py |
Add json_gift_cards column, gift card total methods |
views/cart.py |
Include gift card totals in checkout flow |
views/checkout.py |
Generate MpsGiftCard records after payment |
routes.py |
Add /shop/{slug}/gift-card route |
lib/email.py |
Gift card delivery email template |
templates/shop.j2 |
"Gift Cards" link when enabled |
Depends On
MPS-10 (models and migration).