Research · 6 November 2026 · for PAM product, engineering & finance

How PAM should take money

We compare Stripe, Polar and Lemon Squeezy for the web, and the App Store and Google Play for mobile later. The page covers every money lifecycle (purchase, refund, promotion, pay-as-you-go and grace period), the billing problems we will run into, and the tax and finance work that follows.

The short version

Keep the PAM credit ledger as the source of truth. Treat every gateway as a plug-in pipe that sells credits into it.

  • The legal entity decides the gateway. Stripe does not onboard Vietnam-registered companies, so with only a VN entity we need a merchant of record. Polar is the pick.
  • With a Singapore or US entity, Stripe direct is the cheapest at scale and gives the most control. In exchange, we own the tax registrations.
  • Don't start new work on Lemon Squeezy. Stripe owns it and is moving merchants to Managed Payments.
  • Sell prepaid credits, not postpaid usage. One video generation costs real provider money in seconds, so credits are paid for first and burned afterwards.
Stripe direct, US card
4.1% + 30¢
Processing 2.9% + Billing 0.7% + Tax 0.5%. We file the tax ourselves.
Merchant of record
5–6.4% + 30–50¢
Polar, Lemon Squeezy, Paddle, Stripe Managed Payments. They collect, file and pay the tax.
App Store / Play
15–30%
IAP is required for credits consumed in-app. US link-out is 0% for now, under appeal.
Visa dispute ceiling
1.5%
VAMP "excessive" merchant threshold since 1 April 2026 (US, EU, AP).
What a $20 credit pack costs us
01 · The gateways

Two models: we are the seller, or someone else is

With a processor (Stripe direct), PAM is the legal seller and every tax, invoice and dispute is our job. With a merchant of record (Polar, Lemon Squeezy, Paddle, Stripe Managed Payments, the App Store, Google Play), the platform resells PAM to the customer. It carries that liability, and its higher fee pays for it.

Who owns which job

Dark cells are jobs PAM owns. Light cells are jobs the platform owns.

Stripe (direct)

Processor

The deepest API: Billing, meters, credit grants, Tax, Invoicing, Radar and Smart Retries. It acquired Metronome (usage billing) in early 2026.

  • 2.9% + 30¢ (US), plus 1.5% for international cards and 1% for FX conversion
  • Billing 0.7% of billed volume. Tax 0.5% per transaction, but it only calculates; filing is extra
  • Disputes cost $15 each, refunded if we win
  • Blocker: needs an entity in a Stripe-supported country. Vietnam is not one

Stripe Managed Payments

MoR

Stripe's own merchant of record, sold through Link. API support landed on 22 April 2026 (managed_payments on Checkout Sessions).

  • Standard processing + 3.5% ≈ 6.4% + 30¢ for a US card
  • Tax in 80+ countries, fraud, disputes and buyer support included
  • Eligibility is narrow: no Connect or marketplaces, hosted checkout only, supported regions only
  • This is where Lemon Squeezy merchants are being moved

Polar

MoR

An open-source, developer-first MoR. Usage billing is built in (events → meters → metered prices), and it has credit "benefits".

  • Tiered pricing since 27 May 2026: Starter 5% + 50¢ (free) · Pro 3.8% + 40¢ ($20/mo) · Growth 3.6% + 35¢ ($100/mo) · Scale 3.4% + 30¢ ($400/mo)
  • Reportedly +1.5% for non-US cards. New accounts get a 7-day payout delay
  • Doesn't block usage when a quota is exceeded. PAM must enforce that itself
  • Payouts run on Stripe Connect. Check that payout to a VN bank is supported

Lemon Squeezy

Sunsetting

Stripe acquired it in 2024. The entity was renamed "Sold through Link, LLC", and merchants are migrating to Managed Payments.

  • 5% + 50¢, plus surcharges for international cards and PayPal
  • Mature license keys and a hosted affiliate program
  • Reports of slower support and less development
  • Verdict: don't build a new integration on it

Paddle

MoR · reference

Not on the shortlist, but it's the benchmark MoR for B2B SaaS. Strong invoicing, B2B tax IDs and enterprise contracts.

  • 5% + 50¢ all-in
  • Better than Polar at sales-led invoices and POs
  • Weaker at real-time credit burn

App Store · Google Play

MoR · mobile

Required for digital credits bought and used inside a native app. Both stores handle VAT and GST worldwide.

  • Apple 30%, or 15% in the Small Business Program and for subscriptions after year one
  • Google 15% on subscriptions and on the first $1M a year
  • US link-out to web checkout: 0% today, and Apple is asking for up to 15% (Aug 2026)
  • EU link-outs pay 15% (10% reduced) from 1 Oct 2026
02 · Fees

The fixed fee is what hurts small top-ups

A 50¢ fixed fee is 10% of a $5 top-up and 0.25% of a $200 one. PAM's smallest pack should be priced so the fixed fee stays under about 2%, which means $20 or more.

Effective fee by ticket size

US domestic card, before tax and FX. Hover to read exact values.

Stripe direct includes Billing (0.7%) and Tax (0.5%). Polar Scale excludes its $400/mo plan fee. App stores take a flat percentage, so they don't fall as the ticket grows.

Rules of thumb

  • At $20, Stripe direct costs 5.6%, an MoR 7.5–7.9%, and Apple 15–30%.
  • At $200, Stripe direct costs 4.3% and an MoR 5.25–6.55%. The 1.2–2.3 point gap is the price of handing off tax compliance.
  • Polar tiers pay off at roughly $1.4k, $5.6k and $19k of monthly sales.
  • Refunds don't return fees on Stripe, Polar or Lemon Squeezy. Every refund is a net loss of the original fee.
  • Stripe takes its percentage on the gross amount, tax included.

Where $100 goes

A German consumer buys a $100 credit pack, VAT (19%) included, paying with a non-US card. Hover any segment.

Stripe uses US-entity reference pricing; a Singapore Stripe account prices differently, at 3.4% + S$0.50 domestic. VAT is the same tax in every row. The difference is who files it: with Stripe direct, PAM registers for non-Union OSS from the first euro, because the €10k threshold only applies to sellers established in the EU.

03 · Architecture

One ledger, many pipes

PAM already meters cost from the gateway response (credits = reported_cost_usd × 1,000) and decides refunds and grants in the CMS. Payment providers only turn money into grants on that ledger and never decide balances themselves. That way, adding iOS later is a new adapter, not a rewrite.

The adapter contract

interface PaymentProvider {
  createCheckout(org, sku, opts)
  createPortalSession(org)
  verifyWebhook(req): RawEvent
  normalize(raw): BillingEvent[]
  refund(paymentId, amount?)
  cancel(subId, atPeriodEnd)
}

Normalized events

payment.succeededpayment.failedpayment.refundeddispute.openeddispute.closedsub.startedsub.renewedsub.past_duesub.canceledsub.expiredsub.changed

Each event carries provider, provider_event_id (the idempotency key), occurred_at, the amount in minor units, the currency, and the tax split.

Three invariants

  • The ledger is append-only. Corrections are new entries, never edits.
  • Each provider event is processed once: a unique index on (provider, event_id).
  • Balance is derived from grants minus burns minus holds, and is never stored as a mutable number.
04 · Lifecycles

Every path the money can take

Each lifecycle is a state machine. Dark nodes are where the ledger changes; red nodes are failures we must handle. The tables underneath map each step to the real webhook per provider.

One-off credit pack

For example, 25,000 credits for $25. Credits are granted only from the webhook, never from the success redirect.

Webhook map

StepStripePolarLemon Squeezy
Checkout donecheckout.session.completedcheckout.updated (succeeded)—
Paid → grantcheckout.session.completed with payment_status=paidorder.paidorder_created (status paid)
Async method settlescheckout.session.async_payment_succeededorder.paidorder_created
Async method fails…async_payment_failed——
Abandonedcheckout.session.expired (24h)checkout expires—

Edge cases

  • The redirect arrives before the webhook. Show a "Confirming payment…" state and poll our own API, never the provider's.
  • 3-D Secure. The EU, India and others require SCA. The payment sits in requires_action, and the user can close the tab partway through.
  • Bank transfers and VietQR are asynchronous and can settle days later. Grant on settlement, not on checkout.
  • Double click creates two Checkout Sessions. Reuse an open session for the same org and SKU for 30 minutes.
  • Price changes mid-checkout. Snapshot the price ID into the session; the grant uses the snapshot.

Monthly plan with an included credit allowance

For example, Team at $5,000/month for 5.5M credits. Each renewal grants a fresh allowance with an expiry; purchased top-ups never expire.

Webhook map

StateStripePolarLemon Squeezy
Trial / startcustomer.subscription.created (trialing)subscription.createdsubscription_created
Activeinvoice.paidsubscription.activesubscription_payment_success
Renewalinvoice.paid (billing_reason=subscription_cycle)order.paid (cycle)subscription_payment_success
Past dueinvoice.payment_failedsubscription.past_duesubscription_payment_failed
Recoveredinvoice.paidsubscription.activesubscription_payment_recovered
Plan changecustomer.subscription.updatedsubscription.updatedsubscription_updated
Cancel at end…updated (cancel_at_period_end)subscription.canceledsubscription_cancelled
Endedcustomer.subscription.deletedsubscription.revokedsubscription_expired

Plan-change rules for PAM

  • Upgrade: charge the prorated difference now and grant the difference in allowance immediately. Don't regrant the full block.
  • Downgrade: takes effect at period end. The current allowance stays until it expires.
  • Cancel: always at period end. The allowance stays usable; purchased packs survive cancellation.
  • Seats: unlimited at every tier (a pricing decision), so there's no seat proration to handle.
  • Annual: grant monthly, not 12× upfront. That limits refund exposure and breakage disputes.

Prepaid wallet with auto top-up (recommended)

Every generation first holds its estimated cost, then settles to the reported cost and releases the rest. When the balance drops below the threshold, we charge the saved card.

A month of a wallet

Illustrative: threshold 10k credits, top-up 40k. From day 19 the saved card is declined at the next top-up, so the wallet drains and generation stops (on_empty: stop).

BalanceAuto top-upTop-up declined

Prepaid vs postpaid

PrepaidPostpaid
Bad-debt riskNoneFull month
Cash timingUpfront+30 days
RevenueDeferred until burnOn invoice
FrictionTop-up stepNone
FitsSelf-serveEnterprise contract

Postpaid only for orgs with a signed contract and a credit limit, invoiced through Stripe Invoicing or bank transfer.

Hold → settle

Video and image jobs run for minutes. Reserve the estimate at queue time. Concurrent jobs then can't push the balance negative, and a failed job releases its hold, so failed work is never charged.

Auto top-up guards

At most N top-ups a day, a monthly cap the owner sets, and an email on every charge. Use an off-session PaymentIntent with the saved mandate; SCA can still demand the customer, so fall back to an email link.

On Polar

Polar meters bill usage on the next invoice (postpaid) and never block. For prepaid, sell top-up packs as one-off products and keep burn in PAM. Use Polar meters only for reporting.

Failed renewal: 21 days from decline to read-only

Access steps down gradually. Purchased credits remain the customer's at every step, because they paid for them; only the plan allowance is paused.

Store-side grace periods are not ours to set

PlatformGraceThen
StripeSmart Retries, configurable 1–4 week windowWe choose: cancel, mark unpaid, or leave past_due
PolarIts own retries → past_duesubscription.revoked
AppleBilling grace period of 3, 16 or 28 days (opt-in)Billing retry up to 60 days → EXPIRED
Google PlayConfigurable grace periodAccount hold → EXPIRED

A cross-platform org can be "active" on web and "in hold" on iOS at the same time. Entitlement is the union of active sources.

Dunning stack

  • Before it fails: an "Your card expires this month" email at day −14; network card updaters (Visa VAU, Mastercard ABU) on Stripe.
  • Retries: Smart Retries picks the timing. Don't run a second retry tool alongside it, or the same invoice gets charged twice.
  • Communication: email on day 0, 3 and 7, plus an in-app banner for the owner only. Members just see "Workspace needs attention".
  • Recovery: one link to the hosted portal to update the card, which pays the open invoice and reactivates at once.
  • Enterprise: no automatic lockout. Escalate to the account owner in the CMS.

Refund (decided by us) and dispute (decided by the bank)

Refunds are decided only in the CMS, never by customer owners. The credit clawback is computed from the ledger: unused credits are refunded pro rata, and consumed credits are not refundable.

Webhook map

StepStripePolarApple / Google
Refund issuedcharge.refunded, refund.updatedrefund.created, order.refundedREFUND · Voided Purchases API
Refund failedrefund.failed——
Dispute openedcharge.dispute.createdhandled by Polarn/a (store refunds)
Evidence duecharge.dispute.updated—CONSUMPTION_REQUEST
Closedcharge.dispute.closed (won/lost)—REFUND_REVERSED
Early fraud warningradar.early_fraud_warning.created——

Rules

  • Refund by default when a Visa early fraud warning arrives. A $25 refund beats a $15 fee, a lost dispute and a hit to the VAMP ratio.
  • Freeze, don't delete. On dispute.opened, put the grant's unused credits on hold. On a lost dispute, debit them; if the balance is already spent, the org goes negative and is blocked.
  • Apple refunds unilaterally. Answer CONSUMPTION_REQUEST within 12 hours with consumption data; it changes the outcome.
  • EU 14-day withdrawal right: waived for digital content only if the consumer explicitly agrees at checkout to immediate supply. Add the checkbox.
  • "Result missed the brief" credit-back is a grant in credits, not a money refund. It doesn't exist in the product yet.

Five kinds of promotion, two mechanisms

A money discount lowers what the gateway charges (a coupon). A credit grant adds balance with no money moving. Keep them separate, because accounting treats them differently.

Grant priority (burn order)

  1. Promotional and free grants, soonest expiry first
  2. Plan allowance for this period
  3. Purchased packs, oldest first, no expiry

This matches Stripe credit-grant ordering (priority, then expiry, then effective date). Burning free credits first protects paid value and makes refunds simple.

Abuse vectors

  • Sign-up credits farmed through disposable emails. Gate on a verified work domain or a card check.
  • Card testing on the cheapest pack: Radar rules, CAPTCHA after 2 failures, and a minimum pack of $20.
  • Referral loops. Pay the reward only after the referee's first paid purchase clears its refund window.
  • Coupon leaks to deal sites. Use single-use codes, or limit by customer and redemptions.

Stacking policy

  • One coupon per checkout.
  • Tier discounts never stack with the −70% internal rate (already decided).
  • Free grants always expire (30–90 days); paid credits never do.
  • Any promotion over 500K credits needs CMS approval.
05 · Billing problems

What will break, and the fix

These are the problems every usage-billed AI product runs into, grouped by where they hurt. Filter by area.

06 · Tax & finance

The work that starts after the payment

Fees are the visible cost. Tax registrations, revenue recognition and reconciliation are where the hours go. With an MoR most of the tax work disappears; with a direct processor it doesn't.

EU · VAT
17–27%
  • B2C: the customer's country rate. A non-EU seller uses non-Union OSS from the first euro.
  • B2B: reverse charge at 0% once the VAT ID is validated in VIES. The invoice must say "reverse charge".
  • Location evidence: two non-contradicting pieces (IP, billing country, card BIN).
US · sales tax
~half of states tax SaaS
  • Economic nexus per state, typically $100k in sales (some states also count 200 transactions).
  • Taxability varies: TX, NY, WA, PA, OH and others tax SaaS; CA mostly doesn't.
  • Stripe Tax monitors thresholds, but registering and filing is our job (or Tax Complete from $90/mo).
Singapore · GST
9%
  • Overseas vendor registration (OVR) for digital services once the turnover tests are met (global over S$1M and SG B2C over S$100k).
  • For a Singapore-entity PAM: local GST registration over S$1M taxable turnover, with exports zero-rated.
Vietnam

Two different situations

  • VSF (VN entity) sells to VN customers: VAT 10% (temporarily 8% for qualifying services until 31 Dec 2026). E-invoices are mandatory (Decree 123/2020, amended by 70/2025). Domestic rails such as Napas cards, VietQR, MoMo and VNPay beat international cards here.
  • A foreign entity sells into Vietnam: foreign contractor tax on digital services, either self-registered on the GDT e-portal or withheld by the VN buyer. Decree 252/2026 (effective 1 Jul 2026) can make platforms withholding agents.
  • A VN entity receives MoR payouts from abroad: this counts as service export revenue. Check with VSF Tax how Polar or Lemon Squeezy payouts are invoiced and booked (FX receipt, 0% VAT on exported services, supporting contracts).

Rates and thresholds come from secondary sources (PwC, EY, advisory blogs). VSF Tax must confirm them before launch.

Revenue recognition · IFRS 15 / ASC 606

Credits are a liability until they are burned

  • A $5,000 credit pack lands as deferred revenue, not revenue. Revenue is recognized as credits burn.
  • Breakage (credits that will never be used) is recognized in proportion to usage once it can be estimated, or else at expiry. Paid credits that never expire mean breakage rarely arises.
  • Plan allowances that expire monthly: the unused share is recognized at period end.
  • Free and promotional credits carry no revenue; they reduce the price of what's burned alongside them.
  • Finance needs a monthly ledger export: opening liability, plus grants, minus burns, minus refunds, minus expiry, equals closing liability.

Reconciliation: three numbers that must agree every month

CheckWhenCatches
Every provider payment has exactly one grantNightlyMissed or duplicate webhooks
Every provider refund has a CMS decisionNightlyRefunds made in a provider dashboard
Payout total = sum of balance transactionsPer payoutFees, reserves, dispute debits
Deferred revenue roll-forward balancesMonth endLedger bugs, expiry jobs that didn't run

Other finance problems

  • FX: price in USD (decided). Local-currency display adds 1–2% FX for every non-USD card. Consider fixed local prices in EUR and GBP later.
  • Payout timing: Stripe rolls 2–7 days; Polar holds new accounts for 7 days; the stores pay roughly 30–45 days after the month ends. Plan cash flow around it.
  • Reserves: processors can hold a rolling reserve after a dispute spike.
  • Intercompany: Group P&Ls pay by invoice and bank transfer. Card rails give no benefit there.
  • PCI: hosted Checkout and Elements keep us at SAQ A. Never let card data touch PAM servers.
  • Escheat and unclaimed property: breakage on non-expiring credits can be claimed by some US states. Another reason to keep paid credits non-expiring and avoid booking breakage.
  • Invoices: sequential numbering, legal entity, tax IDs, reverse-charge text. An MoR issues them in its own name; with direct Stripe they are ours.
07 · Mobile, later

Same ledger, store-shaped adapter

Credits used inside the app are digital goods, so Apple guideline 3.1.1 and Google Play policy require in-app purchase. Guideline 3.1.3(b) (multiplatform services) lets a user spend credits bought on the web inside the app, as long as the same packs can also be bought through IAP.

Decisions for mobile

  • Product type: consumable IAP packs (credits), mirroring web packs at store price points. Price them about 15–30% higher on iOS, or accept the margin.
  • Subscriptions on iOS only if the plan is a consumer one. Enterprise orgs buy on web.
  • US storefront: add an "Buy on web" link-out (0% commission today; watch the 15% proposal).
  • Server truth: App Store Server API v2 + notifications, and Play Developer API + RTDN. Never trust the client receipt alone.
  • RevenueCat: optional. It saves receipt and notification plumbing, but it's another vendor between the store and the ledger.
  • Identity: pass appAccountToken (Apple) or obfuscatedAccountId (Google) set to the PAM org ID, so a purchase maps to the right org.
08 · Recommendation

Pick by entity, ship in four steps

Decision tree

Step 0 · now

Invoice the Group P&Ls

No gateway. Grants are issued from the CMS against a signed order, then invoice and bank transfer. Build the normalized event table and the hold/settle ledger now, because everything later depends on them.

Step 1

Web credit packs

One adapter (Stripe or Polar), hosted checkout, $20+ packs, grants from webhooks, CMS refunds with clawback, an EU withdrawal checkbox, and a monthly liability export for Finance.

Step 2

Plans & auto top-up

Subscriptions with monthly allowance grants, auto top-up with caps, dunning, a 21-day grace ladder, the customer portal, and promotion codes and grants.

Step 3

Mobile

StoreKit 2 and Play Billing consumables through the same adapter, server notifications, a US link-out, and cross-platform entitlement as the union of sources.

Open questions to decide

1. Entity. Does VSF have, or will it create, a Singapore or US company for PAM's global sales? This one answer settles Stripe or Polar.

2. Smallest pack. $20 keeps fees under 8% on an MoR. $10 would push them to 10%.

3. Expiry. Paid credits never expire and free credits expire in 90 days: confirm with Finance (breakage and escheat).

4. VN domestic market. Do we sell to Vietnamese SMEs in VND with e-invoices? That requires a VN gateway (VNPay or MoMo), a separate adapter.

5. Dispute policy. Auto-refund on early fraud warnings below what amount?

6. Video margin. Prepaid makes video safe from bad debt, but not from the ×4-vs-Higgsfield price gap. That is a separate pricing decision.

Sources

Where the numbers come from

Many fee figures come from third-party write-ups, some of them by competitors. Check the provider's own pricing page before signing anything. Fetched 6 November 2026.