Architecture
Developer reference
This page documents Wallet Central's internal PHP / asset structure. If you're an admin or store owner, you can skip — the customer-facing UI works without touching anything here.
The PHP + asset structure of wkwc_wallet_central/. Loader → endpoint → router → views → partials.
Folder Layout
wkwc_wallet_central/
├─ class-wkwp-central-loader.php ← entry point
├─ index.php
├─ assets/
│ ├─ css/
│ └─ js/
├─ includes/
│ ├─ class-wkwp-central-i18n.php
│ ├─ class-wkwp-central-context.php
│ ├─ class-wkwp-central-router.php
│ ├─ class-wkwp-central-renderer.php
│ ├─ class-wkwp-central-assets.php
│ ├─ class-wkwp-central-cta-button.php
│ ├─ class-wkwp-central-endpoint.php
│ ├─ class-wkwp-central-bridge.php
│ ├─ class-wkwp-central-settings-ajax.php
│ ├─ partials/ (16 partial classes)
│ └─ views/ (12 view classes)
└─ templates/
├─ chrome.php
└─ index.php
Boot Sequence
WKWP_Central_Loader::__construct():
- Load files — every class file required once
- Check enable flag (
_wkwp_central_enable) — exit if off - Boot singletons in order:
WKWP_Central_Endpoint— registers rewrite + template_redirectWKWP_Central_Assets— registers CSS/JS bundlesWKWP_Central_CTA_Button— wires the legacy My Wallet CTAWKWP_Central_Bridge— bridges into other Webkul modules (referral, KYC, etc.)WKWP_Central_Settings_Ajax— wires the customer-side settings AJAX
Class Map
| Class | Role |
|---|---|
WKWP_Central_Loader | Singleton entry point. Loads + boots everything |
WKWP_Central_I18n | Translates strings, registers WPML / Polylang contexts |
WKWP_Central_Context | Per-request context object — current view, user, balance, KYC status |
WKWP_Central_Router | Reads query vars, resolves to view slug, builds URLs |
WKWP_Central_Endpoint | Rewrite rules, template_redirect interception, render dispatch |
WKWP_Central_Renderer | Renders the chrome + view + partials |
WKWP_Central_Assets | Enqueues bundle CSS/JS, lazy-loads html5-qrcode for QR view |
WKWP_Central_CTA_Button | Injects the discovery banner on legacy My Wallet |
WKWP_Central_Bridge | Hooks into wallet engine actions to power KPIs / pending counts |
WKWP_Central_Settings_Ajax | Handles wp_ajax_wkwp_central_settings_save — debounced toggles |
Views (one per route)
includes/views/:
| View slug | File |
|---|---|
home | class-wkwp-central-view-home.php |
transactions | class-wkwp-central-view-transactions.php |
send | class-wkwp-central-view-send.php |
withdraw | class-wkwp-central-view-withdraw.php |
withdrawals | class-wkwp-central-view-withdrawals.php |
withdrawal-detail | class-wkwp-central-view-withdrawal-detail.php |
add-to-wallet | class-wkwp-central-view-add-funds.php |
requests | class-wkwp-central-view-requests.php |
qr | class-wkwp-central-view-qr.php |
referral | class-wkwp-central-view-referral.php |
settings | class-wkwp-central-view-settings.php |
kyc | class-wkwp-central-view-kyc.php |
Each view exposes a single static render( WKWP_Central_Context $ctx ) method called by the renderer.
Partials (composable building blocks)
includes/partials/:
| Partial | Used by |
|---|---|
Partial_Icons | shared icon SVG library |
Partial_Greeting | home, transactions |
Partial_Hero | home (3 variants) |
Partial_Action_Grid | home (2×2 tiles) |
Partial_Add_Funds | home + add-to-wallet |
Partial_Activity | home + transactions |
Partial_Referral | home + referral |
Partial_Modal_KYC | every gated view |
Partial_Modal_Redeem | home (Redeem code dialog) |
Partial_Tweaks | every view (density / accent / variant picker) |
Partial_Quick_Actions | sidebar |
Partial_Right_Rail | home + transactions |
Partial_KPIs | home (4-card strip) |
Partial_Quick_Topup | home (mini Add Funds) |
Partial_Pending_Requests | home right-rail |
Partial_Saved_Payees | home right-rail + send |
Partial_Linked_Accounts | home right-rail + settings |
Partial_Limits | home right-rail + settings |
Partial_Refundable | home right-rail |
Partial_Help_Strip | every view (FAQ / Support / Admin pills) |
Templates
templates/:
| File | Purpose |
|---|---|
index.php | Outer <!doctype html> + <head> + <body class="wcc-body"> + boot of root mount |
chrome.php | Sidebar + top bar + view container — rendered inside <body> |
Templates are simple — most logic lives in Renderer and partials.
Render Flow
WKWP_Central_Endpoint::maybe_render:
1. Check query var wkwp_central=1 → bail if not present
2. Check auth → redirect anon to wp_login_url
3. Build context: WKWP_Central_Context::for_user( $current_user )
- balance, kyc status, locks, settings, currency, etc.
4. Resolve view: WKWP_Central_Router::resolve()
5. Send headers (no-cache, content-type)
6. Include templates/index.php
- includes templates/chrome.php
- calls Renderer::render( $view, $ctx )
- Renderer dispatches to View_<view>::render( $ctx )
- View calls Partials it needs
7. exit
Asset Bundles
WKWP_Central_Assets::register:
| Handle | Type | Loaded on |
|---|---|---|
wkwp-central-core | CSS + JS | every Wallet Central page |
wkwp-central-home | CSS + JS | home view only |
wkwp-central-add-funds | CSS + JS | add-to-wallet view |
wkwp-central-withdraw | CSS + JS | withdraw view |
wkwp-central-send | CSS + JS | send view |
wkwp-central-qr | CSS + JS | qr view (lazy-loads html5-qrcode) |
wkwp-central-referral | CSS + JS | referral view |
wkwp-central-settings | CSS + JS | settings view |
wkwp-central-kyc | CSS + JS | kyc view + every gated view |
wkwp-central-tweaks | CSS + JS | every view (Tweaks panel) |
Lazy view-specific bundles keep first-paint fast — typical home page ships ~80 KB CSS + 60 KB JS.
Bridge Class
WKWP_Central_Bridge listens to wallet-engine actions and pushes them into Wallet Central caches:
| Listens to | Action |
|---|---|
wkwp_wallet_balance_changed | bust per-user balance cache |
wkwp_kyc_status_changed | bust per-user KYC gate cache |
wkwc_wallet_withdrawal_approved | bust right-rail counts |
wkwp_referral_reward_credited | bust referral stats cache |
wkwp_central_request_created | bust pending count |
Means Wallet Central never has its own duplicate event system — it shares the engine's events.
Context Object
WKWP_Central_Context is the per-request data bag passed to every view + partial:
| Property | Source |
|---|---|
user_id | get_current_user_id() |
display_name | get_user_meta |
balance | wallet meta + cache |
currency | active WC currency |
kyc_status | _wkwp_kyc_status |
kyc_features | resolved gate list |
transfer_locked | _wkwp_transfer_locked |
wallet_settings | merged admin options |
pending_requests_count | bridge cache |
outstanding_bnpl | bridge cache |
unread_kyc | bridge cache |
Built once on template_redirect. Cheap to pass around (object reference, not array copy).
Central vs Engine
| Layer | Responsibility |
|---|---|
Wallet engine (wkwc_wallet/, root files) | Ledger writes, gateway, withdrawal handler, payouts, hooks |
Wallet Central (wkwc_wallet_central/) | UI surface only — never writes ledger directly |
Means Wallet Central never duplicates engine logic. Every state change flows through the engine.
Adding a Custom Partial
// 1. Create partial class (file: includes/partials/class-wkwp-central-partial-points.php)
final class WKWP_Central_Partial_Points {
public static function render( WKWP_Central_Context $ctx ) {
?>
<div class="wcc-card wcc-points">
<h3><?php esc_html_e( 'Loyalty points', 'mytheme' ); ?></h3>
<p class="wcc-points-value"><?php echo esc_html( get_user_meta( $ctx->user_id, '_my_points', true ) ); ?></p>
</div>
<?php
}
}
// 2. Register the file (filter the loader file list)
add_filter( 'wkwp_central_files', function( $files, $base ) {
$files[] = $base . 'partials/class-wkwp-central-partial-points.php';
return $files;
}, 10, 2 );
// 3. Render it inside an existing view
add_action( 'wkwp_central_render_view', function( $view, $ctx ) {
if ( 'home' !== $view ) return;
WKWP_Central_Partial_Points::render( $ctx );
}, 10, 2 );
Hooks (architecture-level)
| Hook | Type | When |
|---|---|---|
wkwp_central_files | filter | mutate the loader's file include list |
wkwp_central_boot | action | after all singletons booted |
wkwp_central_render_view | action | inside the renderer per view |
wkwp_central_context_built | action | after Context constructed |
wkwp_central_send_headers | action | inject extra HTTP headers |
Performance
| Metric | Target |
|---|---|
| First paint (home) | < 200ms (cached context) |
| TTI (home) | < 400ms |
| Total CSS | ~80 KB gzip per view |
| Total JS | ~60 KB gzip per view |
| API calls per view | 0 (server-rendered) |
Lazy-load policy:
- View-specific bundles only on their view
html5-qrcodelibrary only onqrview- Tweaks panel JS deferred (no blocking)
Test Plan
/wallet-central/→ confirm 1 CSS + 2 JS bundles loaded (core + home + tweaks)/wallet-central/qr/→ confirmhtml5-qrcodelazy-loaded/wallet-central/foo/→ router falls back to home- Disable plugin → confirm
/wallet-central/404s - Toggle
_wkwp_central_enable=0→ confirm rewrite rules removed (404s)
