Skip to content

Releases: ladekarl1234-commits/arvan-reseller

v1.1.0 — recurring billing, reconcilable provisioning, honest failure states

Choose a tag to compare

@ladekarl1234-commits ladekarl1234-commits released this 22 Aug 08:49

White-label ArvanCloud reseller platform for WordPress — Persian-first storefront, automated provisioning, wallet and recurring billing.

Install: download arvan-reseller-1.1.0.zip below, then in WordPress go to Plugins → Add New → Upload Plugin, choose the file, install and activate. No Composer, no build step, no source edits. The plugin starts in Demo Mode so you can walk the whole purchase flow before connecting a real ArvanCloud token.

Requires WordPress 6.0+ and PHP 7.4+.


What changed

This release works through all 141 findings from an independent 15-reviewer expert panel, and adds the two subsystems whose absence that panel called critical.

Recurring revenue

A "monthly package" used to be charged exactly once while ArvanCloud kept billing the reseller's upstream account — from month two, every active service was pure loss. Billing\Renewals adds term-based recurring charges, idempotent on three independent layers: the ledger's unique business key, the usage period key, and an atomic UPDATE … WHERE renews_at = <old> clock advance that two concurrent cron runners cannot both win.

Those renewal charges are also what makes the wallet, credit-policy and usage subsystems work in production. They were inert before, because ArvanCloud publishes no billing or metering API — and still does not. Usage debits now carry markup, and usage_records stores cost and price separately, so recurring margin is measured rather than assumed.

New reporting covers period revenue, cost, margin, MRR, churn and product mix. Lifetime totals could not reveal a month-two revenue cliff.

One payment can no longer become two billed servers

The API client retried non-idempotent POSTs on timeout while the provider discarded the idempotency key. Retries are now verb-aware — an unknown outcome raises timeout_indeterminate rather than duplicating a paid-for resource — and remote resources get deterministic names so a create can be reconciled by lookup even if the upstream ignores idempotency keys entirely. Customer-supplied region, image and flavor are validated against the live catalogue before the paid write.

The provisioning path no longer sleeps inside the payment callback.

The payment screen tells the truth

It previously announced «سرویس شما آماده است» even when provisioning had failed, and the customer was never told anything afterwards. It now renders from observed state, polls for a bounded period, and reports failure with a reference number and a support route.

Operations

Admin alerts are rendered — they were written to the database and displayed nowhere. Stale job claims are reaped, stuck orders are reclaimable, job payloads and full errors are visible, the audit log is filterable and exportable, orders are searchable by payment reference, and the services screen can resync, suspend and terminate.

Correctness fixes found while remediating

  • The negative-balance walk had credits and debits inverted, so every customer with any history would have been suspended and blocked from purchasing on day one.
  • The v5 renewal backfill starts the clock at upgrade time, not creation time — backdating billed one retroactive term per cron tick against real wallets.
  • is_demo is stamped from the originating row rather than the ambient request mode, so demo inventory cannot manufacture real revenue after go-live.
  • Admin refunds route through the settlement guard that refuses to mint credit against a purchase that was never ledgered.
  • CDN and object-storage creates refuse a name already live under another customer.

Verification

Gate 1.0.0 1.1.0
Unit tests / assertions 46 / 158 178 / 692
End-to-end checks in a real WordPress 46 123
PHP 7.4 grammar gate none 101 files, 0 violations
Schema unique keys proven at migration unverified all 6 verified
Translation catalogue none 836 strings

Validation runs against the packaged ZIP installed into a clean WordPress, not against the source tree — which is how three defects were caught that no amount of code review would have found: a runtime file missing from the archive that made the plugin impossible to license, a compiled catalogue whose generator self-verified with a more lenient reader than WordPress uses, and the balance-walk sign inversion above.

Known limitations

  • No production payment gateway ships. The sandbox adapter is the only one included, so real-mode checkout and top-up are refused until a PSP adapter is registered against PaymentProviderInterface. Demo Mode exercises the full flow.
  • Real-mode metered usage returns nothing — there is no upstream API for it. Recurring revenue comes from term charges instead.
  • Cloud-server root passwords and S3 access keys still require the reseller to retrieve them from the ArvanCloud panel; only CDN is fully hands-off.

These are documented in readme.txt and docs/API_INTEGRATION.md rather than implied away.