Features

Everything You Need to Sell on Your Terms

💰 Payment Plans

Create reusable payment structures that fit your products and customers:

  • Deposit — Pay a percentage (e.g., 50% now) or fixed amount (e.g., $500 now) at checkout. Balance is charged later on fulfillment.
  • Pre-order — Collect a deposit to reserve inventory. Balance is auto-charged when the product launches or ships.
  • Deferred / Split — Split the full amount into N installments after a configurable down payment.

Each plan has a name, description, deposit type (percent or fixed), deposit value, installment count, and auto-charge flag. Plans can be paused or archived without deleting them.

⚙️ Plan Rules Engine

Automate which plan applies to which order with a flexible rules engine:

  • AND conditions: Match on product (specific SKUs), collection (entire categories), minimum order value, or customer tags
  • Priority ordering: Rules are evaluated top-to-bottom — the first matching rule wins
  • Propose vs Require: propose auto-applies the plan when conditions match; require flags it for merchant review
  • Enable/disable individual rules without losing their configuration

Example use cases

"All products in the Handmade collection → 50% deposit, balance on fulfillment"

"Orders over $500 → deferred, split into 3 installments"

"VIP customer tag → 10% deposit only"

🤖 AI Suggestions (MODE B)

When an order doesn't match any manual rule, the AI engine analyzes the order context and suggests a payment plan:

  • Heuristic scoring based on order total bands, product type, and customer signals
  • Suggested split: deposit amount, balance amount, with a confidence percentage
  • Approve — apply the suggested plan
  • Override — choose a different active plan
  • Reject — no plan assigned (merchant handles manually)

All suggestions are recorded with their reason and confidence score, so merchants always know why a plan was proposed.

🔗 Stripe Payments

All money movement happens through Stripe — reliable, PCI-compliant, globally available:

  • Stripe Checkout Sessions: Customers pay on Stripe's hosted, mobile-optimized payment page
  • Shareable deposit links: Each order gets a unique, unguessable payment URL
  • Manual capture for deposits: Authorize now, capture on fulfillment (reduces refund risk)
  • Auto-capture for balances: Once the balance is due, it's captured immediately
  • Webhook integration: payment_intent.succeeded and payment_intent.payment_failed are handled with full idempotency — no double charges

📋 Orders Dashboard

Track every order with a payment plan in one place:

Column Details
Status awaiting_depositdeposit_paidbalance_paid / failed / voided
Deposit link Copy and send to customer
Charge balance Manual trigger for non-autocharge plans
Refund Refund captured deposits and balances
History Charge attempts, dunning events, AI recommendations

❤️ Dunning (Payment Recovery)

Failed payments don't mean lost sales — the dunning engine automatically escalates:

  • 4 stages: Reminder 1 → Reminder 2 → Final Notice → Escalation
  • Configurable timing: Defaults 3 → 7 → 14 days between stages
  • Full event log: Every notification is recorded with timestamp and stage
  • Extensible: Designed to connect to email/SMS for customer-facing notifications

🔄 Installments

Deferred plans support splitting the balance into multiple payments:

  • Configurable installment count (2, 3, 4, 6, etc.)
  • Equal payment amounts per installment
  • Schedule tracked on the OrderPayment record
  • Each installment creates its own ChargeAttempt

⏰ Autocharge Cron

A standalone script (npm run autocharge) runs on a schedule to collect outstanding balances:

  • Finds orders with status deposit_paid, past due date, and auto-charge enabled
  • Creates a Stripe PaymentIntent for the balance
  • Records a pending ChargeAttempt
  • Transitions status to auto_charging
  • Success/failure is reconciled by the Stripe webhook

🔐 Security

  • Stripe secret keys are never stored in the database — only referenced by environment variable name
  • All Stripe webhooks verify the stripe-signature HMAC before processing
  • Idempotency keys prevent duplicate processing of the same event
  • Payment tokens are crypto.randomUUID() — unguessable, no PII leakage
  • No customer payment data (credit card numbers) ever touches our servers — Stripe handles it directly