Arvan Reseller Platform
White-label ArvanCloud reseller platform for WordPress — automatic provisioning, wallet ledger, usage accounting, credit policies.
by Arvan Reseller Team · github.com/ladekarl1234-commits/arvan-reseller · website
Install
The author publishes release zips, so WP-CLI can install straight from GitHub:
wp plugin install https://github.com/ladekarl1234-commits/arvan-reseller/releases/download/v1.1.0/arvan-reseller-1.1.0.zipReadme
Arvan Reseller Platform
Turn any WordPress site into a white-label cloud provider. Customers buy Cloud Servers, CDN and Object Storage on your site, pay in your currency, and the plugin provisions the resource on ArvanCloud automatically — no panel round-trips, no manual credential copy-paste.
Why this exists
ArvanCloud resellers today sell manually: an order arrives on their site, they log into the ArvanCloud panel, create the server by hand, copy the IP and password, and email it back. Every sale costs minutes of human time, every step can be mistyped, and the customer waits.
This plugin removes the human from the loop:
Customer pays on reseller site → order claimed atomically → Arvan API provisions
→ service appears in customer dashboard → usage syncs → wallet debited → policy engine watches credit
What it does
| Area | Capability |
|---|---|
| Licensing | Plugin Access Token gate (bcrypt allowlist, plaintext never stored) — separate from the Arvan API token |
| Onboarding | 7-step wizard: token → brand → Arvan credential (+connection test) → pricing → automatic page creation → validation |
| Storefront | Persian-first RTL pages for Cloud Server / CDN / Object Storage with real plan configuration, created idempotently |
| Pricing | Pricing Engine: global / per-product / per-customer markup, discounts, fixed adjustments; immutable pricing snapshot per order |
| Payments | PaymentProviderInterface + fully working sandbox gateway; callbacks verified server-side, idempotent, replay-safe |
| Provisioning | Instant post-payment provisioning through documented Arvan APIs, layered idempotency (atomic claim + UNIQUE(order_id)), retry jobs with backoff |
| Wallet | Append-only ledger (no mutable balance column); derived balances, reservations, reconciliation views |
| Usage | Idempotent per-period ingestion → ledger debits → configurable credit policy (warning / critical / grace / restricted) |
| Multi-credential | Several encrypted Arvan API tokens with per-product routing, priority and health tracking |
| Admin | Dashboard (revenue/margin/health), customers, orders, services, credentials, pricing, policies, audit log, System Health with Sync-now |
| Demo mode | Simulates only the external boundary (Arvan + gateway); every internal flow is real, so judges can run the whole story without credentials |
Demo
- Persian demo script:
docs/demo-script-fa.md(6–8 minute walkthrough) - Demo checklist (laptop + 390 px mobile):
docs/demo-checklist.md - Demo activation token & seed instructions:
DEVELOPMENT.md
| Storefront | Customer dashboard (live E2E data) | Admin dashboard |
|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Architecture
flowchart TB
subgraph WP[WordPress Plugin — modular monolith]
subgraph UI[Presentation]
SF[Storefront shortcodes]
CD[Customer dashboard]
AD[Admin pages + wizard]
REST[REST API arvan-reseller/v1]
end
subgraph APP[Application core]
PR[Pricing Engine]
OR[Order Service + State Machine]
PAY[Payment Service]
PROV[Provisioner]
LED[Wallet Ledger]
USE[Usage Engine]
POL[Policy Engine]
NOT[Notifier]
end
subgraph INF[Infrastructure]
AC[ArvanClient HTTP]
CRED[Encrypted credentials]
JOBS[Durable jobs + WP-Cron]
DB[(12 custom tables)]
end
end
CU((Customer)) --> SF --> REST
RA((Reseller admin)) --> AD
REST --> OR --> PR
PAYGW[Payment gateway<br/>sandbox / future PSPs] <--> PAY
PAY --> LED
PAY --> PROV --> AC --> ARVAN[(ArvanCloud API)]
JOBS --> PROV
JOBS --> USE --> LED
USE --> POL --> NOT
APP --> DB
Deep-dives: ARCHITECTURE.md · docs/architecture/ · docs/DATA_MODEL.md
How a purchase works
sequenceDiagram
actor C as Customer
participant S as Storefront
participant O as OrderService
participant G as Gateway (sandbox)
participant P as PaymentService
participant V as Provisioner
participant A as ArvanCloud API
participant L as Ledger
C->>S: configure plan, buy
S->>O: POST /checkout (server-side price)
O-->>C: redirect to gateway (payment_ref)
C->>G: pay
G->>P: POST /payment/callback (proof)
P->>P: verify(proof, amount) server-side
P->>O: UPDATE … SET paid WHERE payable AND amount matches (atomic claim)
Note over P: duplicate callback → 0 rows → idempotent replay answer
P->>L: payment credit + purchase debit (INSERT IGNORE on payment_ref)
P->>V: provision(order)
V->>V: existing service? claim paid→provisioning?
V->>A: create resource (documented endpoint)
A-->>V: remote_id + connection info
V->>O: provisioning→active
V-->>C: «سرویس شما آماده است»
Technical stack — and why
| Choice | Why (short) |
|---|---|
| PHP 7.4+, namespaced, zero runtime Composer deps | Installs on any standard host; Composer/PHPUnit are dev-only. |
| Server-rendered PHP + vanilla JS/CSS | One 16 KB JS file total, RTL trivial, no build step, no React version drift inside wp-admin. Rejected React/Vue with evidence: docs/STACK_EVALUATION.md |
| 12 custom tables | Financial rows (ledger, orders, usage, top-ups) need indexes, uniqueness constraints and aggregate queries that wp_options/meta cannot provide. ADR-0003 |
| Durable jobs table + WP-Cron runner | WP-Cron is traffic-triggered, so durability lives in the table; production scaling = point real cron at wp-cron.php, zero code change. ADR-0004 |
| Provider interfaces (Arvan, Payment) | DemoProvider ↔ RealProvider swap without touching business logic; future PSP adapters implement one interface. ADR-0005, ADR-0006 |
| Append-only ledger | Balance = Σ(entries); replay-safety via UNIQUE(ref_type, ref_id, type) + INSERT IGNORE. ADR-0007 |
| libsodium secretbox for credentials | Authenticated encryption keyed from WP salts via HMAC; Base64 or reversible obfuscation rejected. ADR-0008 |
| "ابرآروان" teal design system, Vazirmatn (SIL OFL) | The whole UI implements a Claude Design artboard set (storefront, product, dashboard, auth, payment, wizard, admin) — glassy header, gradient hero/CTAs, radio-dot plan cards, pill tabs. The brand palette derives from one --arvrs-brand token so a reseller's brand color recolors everything. Vazirmatn is bundled (Sorkhab's Yekan Bakh is commercial). |
Security
Security is a first-class deliverable (70/300 points). Highlights — full detail in SECURITY.md and docs/THREAT_MODEL.md:
- Customer isolation: every
/me/*handler scopes by session user ID; IDs never come from the request (Services::get_owned). - Payment integrity: prices recomputed server-side; callback proof is an HMAC over
(ref|amount|type); amount mismatch fails verification; atomic single-UPDATEclaim kills replays and races. - Provisioning idempotency: three layers — service-row check, state-machine claim,
UNIQUE(order_id). - Secrets: sodium-encrypted at rest, masked (
••••last4) in UI, never in REST responses, redacted from logs by key-pattern. - CSRF/XSS/SQLi: nonces on every state change, escaping at sink, 100%
$wpdb->prepare(). - Licensing: bcrypt allowlist; only a SHA-256 fingerprint of the accepted token is stored.
- Auditability: credential changes, pricing changes, refunds, license events → append-only audit log with IP.
Independent expert review
This codebase was put through a 15-agent expert evaluation panel. Each reviewer took one dimension, read the source (not the README), scored it 0–100 against a published scale, and filed evidence-backed findings with file:line references. They shared no context, so where two of them land on the same defect, that is corroboration rather than coordination.
Weighted result: 72.5 / 100 — 141 findings: 6 critical, 43 high, 64 medium, 28 low.
| Strongest | Weakest | ||
|---|---|---|---|
| Documentation | 85 | Business viability | 56 |
| Code quality | 84 | Scalability | 62 |
| Security | 84 | Visual design / Testing / a11y / Integration | 66 |
| Product completeness | 82 | Operational readiness | 68 |
The panel did not return a clean bill of health, and the record is published unedited on purpose — it describes the code as it stood at review time, not as it stands today. Its headline conclusions, and their current status:
ArvanClientretries non-idempotentPOSTs on timeout/5xx — found independently by two reviewers, and the single most serious defect: a slow upstream create can charge once and provision twice. Fixed: retries are now verb-aware; POST/PATCH raisetimeout_indeterminateand are reconciled by deterministic remote name instead of repeated (ArvanClient.php,RealProvider::remote_name).- The recurring-revenue model is not implemented — a "monthly package" is charged exactly once; there is no renewal path in the code. Fixed:
Billing\Renewalscharges each service's own term clock on a daily job. - In real mode the wallet/usage/credit-policy subsystem is inert, because ArvanCloud publishes no usage API (documented, but the consequence is larger than the docs imply). Addressed: recurring revenue in real mode now comes from
Billing\Renewals(a wallet debit), which makes the credit ladder reachable in real mode too; metered usage sync itself is still demo-only, because the upstream API still does not exist. - The payment screen can tell a customer the service is ready when provisioning failed. Fixed: the payment result now reports the true post-payment provisioning state.
A full re-review has not been run against this round — treat the fixes above as verified against the source (file/line cited), not as a second panel score. docs/review/ISSUE_BACKLOG.md's status column reflects the same verification.
Full record — process, per-dimension scores with reasoning, convergence analysis, and every finding with evidence and a fix:
- 📋 docs/EXPERT_REVIEW.md — the panel, the scores, the reasoning
- 🐛 docs/review/ISSUE_BACKLOG.md — all 141 findings, each with ID, evidence, impact, fix and effort
- 🤖 docs/review/panel-results.json — machine-readable results
Installation
Requirements: WordPress 6.2+, PHP 7.4+ with libsodium (standard), MySQL 5.7+/MariaDB 10.3+.
- Download/build the plugin ZIP (see
DEVELOPMENT.md→ Create plugin ZIP), or copy this repo intowp-content/plugins/arvan-reseller. - Activate Arvan Reseller Platform in wp-admin → the onboarding wizard launches automatically.
- Enter your Plugin Access Token (judges: demo token in
DEVELOPMENT.md). - Follow the wizard: brand → Arvan API token (or skip for Demo Mode) → pricing → automatic page creation → done.
No WooCommerce, no page builder, no theme requirement, no Node.js at runtime.
Development & testing
git clone https://github.com/ladekarl1234-commits/arvan-reseller.git
cd arvan-reseller
composer install # dev tooling only
composer test # unit suite — count in TESTING.md
Full environment (wp-env / wp-cli + SQLite), seed data and E2E scenario: DEVELOPMENT.md · TESTING.md
Read the full README on GitHub →
Releases
| Tag | Published | Asset | Downloads |
|---|---|---|---|
| v1.1.0 | Aug 22, 2026 | arvan-reseller-1.1.0.zip | 1 |








