Stripe & invoices
Checkout, webhooks and accounting mirrors
Stripe is authoritative for payment lifecycle. Mivama Core mirrors Stripe objects into Frappe so Portal, provisioning and accounting can operate from controlled local records.
Checkout sequence
The Core blocks duplicate active subscriptions and concurrent pending checkouts. A plan must map to a Stripe Price and an ERPNext Item before checkout. Stripe Customer IDs are attached to a customer-specific billing profile.
Webhook processing
Stripe webhook signatures are verified before the event is stored. Mivama Stripe Event records provide deduplication, processing status and retry context. The handler covers checkout completion, subscription changes/deletion and invoice lifecycle.
Failures do not silently discard the event. The hourly scheduler retries pending events; daily reconciliation queries current Stripe subscriptions to repair missed or delayed delivery.
Subscription mirror
Mivama Stripe Subscription stores Stripe IDs, plan mapping, status, billing period, cancellation timestamps and the local Customer. Its insert/update hooks call the hosting lifecycle reconciler. Active commercial state can create or resume a Hosting Service; cancellation state starts the controlled retention path.
Stripe remains authoritative when local and remote status differ. Local records must not fabricate an active subscription.
Invoice accounting
Mivama Stripe Invoice links a Stripe invoice to one ERPNext Sales Invoice. Final Stripe totals, currency, tax and timestamps replace ERPNext-derived estimates. A configured Stripe clearing account receives the Payment Entry when Stripe reports payment.
Important guards:
- one local invoice per Stripe invoice ID;
- exact customer/company/plan mapping;
- Stripe tax account must exist and belong to the configured company;
- Frappe grand total must equal the finalized Stripe total;
- paid amount must reconcile with outstanding amount;
- voids or unsupported divergence require manual review, not guessed accounting.
The Sales Invoice on_submit hook sends the localized invoice notification. Future customers receive an invoice through the same webhook-driven path rather than a checkout-page side effect.
Customer management
Portal requests a short-lived Stripe Customer Portal URL for payment method, invoice and cancellation management. Plan changes validate that exactly one subscription item exists and use Stripe confirmation. Portal does not edit Stripe objects directly.
Primary source: mivama_core/api/_portal_stripe.py, _portal_billing.py and provisioning/lifecycle.py.