YeetCode
Guides

Payments Overview

Understand YeetCode's two payment systems and when to use each.

YeetCode ships with two payment integrations that cover different business models. You can use either or both depending on your market and pricing strategy.

Two Systems, Two Models

Polar.shYoco
ModelRecurring subscriptionsOne-time access purchases
CurrencyUSD (international)ZAR (South Africa)
BillingMonthly/yearly, auto-renewsPay once, access expires after a set duration
Customer managementPolar customer portal (upgrade, cancel, billing info)No portal — buy again when access expires
Best forSaaS with ongoing value (features, storage, seats)Courses, digital products, time-limited content
MarketGlobalSouth African businesses only

Polar.sh — Recurring Subscriptions

Polar handles subscription lifecycle management: checkout, billing cycles, upgrades, downgrades, cancellations, and customer portals. Think Stripe, but with a simpler API.

How it works:

  1. You define subscription tiers in config.yaml under pricing
  2. Customer clicks a plan on your marketing site
  3. Polar hosts the checkout page — handles card details, billing
  4. Polar sends webhooks to your Convex backend on subscription events
  5. Your backend tracks subscription status in the subscriptions table
  6. Access is ongoing while the subscription is active

What you get out of the box:

  • Checkout session creation
  • Webhook handlers for checkout.updated, order.created, subscription.created, subscription.updated, subscription.revoked
  • Subscription status tracking
  • Customer portal (manage billing, cancel, update payment method)
  • Discount code workflow (auto-generates 100% off codes for specific products)
  • Confirmation and cancellation emails via Resend

Setup guide: Connect Polar to Convex In-depth guide: Polar Pricing & Subscriptions

Yoco — One-Time Access Purchases

Yoco is a South African payment gateway. Instead of subscriptions, customers buy time-limited access packages — 3 months, 6 months, or lifetime. When access expires, they buy again.

How it works:

  1. You define access packages in config.yaml under accessPackages
  2. Customer picks a package on your marketing site
  3. Yoco hosts the checkout page — handles card and EFT payments
  4. Yoco sends a webhook when payment succeeds
  5. Your backend grants access for the package's duration (stored in accessGrants table)
  6. Cron job sends reminder emails as expiry approaches (14 days, 7 days, 1 day, at expiry)

What you get out of the box:

  • Checkout session creation via Yoco SDK
  • Webhook handler with HMAC-SHA256 signature verification
  • Access granting with duration stacking (buying again extends from current expiry, not from now)
  • Access query (hasAccess) for frontend gating
  • Expiry reminder emails at 14/7/1/0 days
  • Support for card and instant EFT payments

Setup guide: Connect Yoco to Convex In-depth guide: Yoco Pricing & Access Packages

Which Should I Use?

Use Polar if:

  • Your customers are international
  • You want recurring revenue with monthly/yearly billing
  • You need a customer portal for self-service billing management
  • Your product delivers ongoing value (features, storage, API calls)

Use Yoco if:

  • Your customers are in South Africa
  • You sell time-limited access (courses, content, tools with expiry)
  • You want to accept ZAR payments with local card and EFT support
  • You prefer a simpler "buy once, use for X days" model

Use both if:

  • You have an international audience AND a South African audience
  • You offer both subscription and one-time-purchase options

Both systems are fully independent — they use separate database tables, separate webhook endpoints, and separate config sections. You can enable one and ignore the other, or run both side by side.

Configuration

Both systems pull their product data from config.yaml at the repo root:

# Polar subscriptions (international, USD, recurring)
pricing:
  - id: "free"
    name: "Free"
    price: 0
    currency: "$"
    priceLabel: "/month"
    polarProductId: "your-polar-product-id"
    # ... features, cta, etc.

# Yoco access packages (South Africa, ZAR, one-time)
accessPackages:
  - id: "3-month"
    name: "3 Month Access"
    durationDays: 90
    priceInCents: 29900
    currency: "ZAR"

Edit these sections to define your products. The marketing site reads from this config to render pricing cards, and the backend uses it to create checkout sessions and grant access.

Architecture

Both payment flows follow the same pattern:

Marketing UI → Convex action (create checkout) → Hosted checkout page

                                                   Customer pays

Convex HTTP endpoint ← Webhook ← Payment provider

  Webhook handler (verify signature, deduplicate, persist)

  Database trigger (grant access / track subscription)

  Email notification (via Resend)

Webhook events are stored in the webhooks table for audit logging. Duplicate webhooks are detected by event ID and silently ignored.

On this page