The developer reference for Elite Balance 1.1.0: the public PHP API, the service container, idempotency keys, transaction types, every action and filter, custom migration and earlier history sources, template overrides, and the Store API data the checkout uses. It is written for developers building integrations or customizing a store. Store owners do not need anything on this page.
Ground rules
↑ Back to top- Never write to Elite Balance’s tables directly. Every guarantee (running balances, idempotency, wallet locking, the holds that reserve money) lives in the API. Reading the tables is fine; every write goes through the functions and services below.
- Start your integration on
rb_elite_balance_loaded. It fires once every service is registered and the requirements (WordPress 6.6, WooCommerce 9.0, PHP 7.4) are met. If the requirements are not met, the plugin stays dormant and the action never fires. - Amounts are decimal strings with up to four decimal places. The API accepts
'25','25.50'or a number, and returns canonical strings such as'25.5000'. Do not do float math on money. - Pass a deterministic idempotency key for anything that can run twice (see Idempotency keys).
- Wallets hold the store’s base currency (
get_woocommerce_currency()). There is one wallet per customer. - Staff access is the
rb_elbal_manage_walletscapability, granted to the Administrator and Shop manager roles on activation (filterrb_elite_balance_capability_map).
Database tables
↑ Back to topAll tables use your $wpdb->prefix.
| Table | Holds |
|---|---|
rb_elbal_wallets | One row per customer wallet: user, currency, balance, status (active or locked). |
rb_elbal_transactions | The append-only ledger. One row per movement with the signed amount, the balance after, the type, the reference, the actor, the note, JSON meta and a unique idempotency key. |
rb_elbal_holds | Reservations against a wallet’s available balance: pending, captured, released or expired. |
rb_elbal_withdrawals | Customer withdrawal requests and their lifecycle. |
rb_elbal_history | The earlier history archive copied from a previous wallet plugin (1.1.0). Never part of the ledger. |
Public functions
↑ Back to topThese functions are semver-stable public API. The write functions return a WP_Error instead of throwing.
| Function | Returns | What it does |
|---|---|---|
rb_elite_balance() | Plugin | The service container (see Service container). |
rb_elbal_credit( int $user_id, $amount, array $args = array() ) | Transaction|WP_Error | Credits a wallet. Creates the wallet when the customer has none. |
rb_elbal_debit( int $user_id, $amount, array $args = array() ) | Transaction|WP_Error | Debits a wallet. Fails when the amount exceeds the available balance or the wallet is locked. |
rb_elbal_balance( int $user_id ) | string | The ledger balance, canonical ('25.5000'). '0.0000' for a customer without a wallet. |
rb_elbal_available_balance( int $user_id ) | string | The balance minus pending holds: what checkout and withdrawals can use now. |
rb_elbal_wallet( int $user_id ) | Wallet|null | The wallet object, or null when the customer has none yet. |
Credit and debit arguments
↑ Back to top| Key | Type | Description |
|---|---|---|
idempotency_key | string | Deterministic key, 1 to 191 characters. Strongly recommended. When omitted, the functions generate a unique key per call, so a retried call moves money again. |
type | string | A registered transaction type whose direction allows the operation. Default credit for credits and debit for debits. |
note | string | Plain-text note. Staff always see it; customers only see notes on the types listed in rb_elite_balance_customer_note_types. |
meta | array | Structured data stored as JSON on the row. 'notify' => 'no' suppresses the Wallet credited or debited email for this transaction. |
reference_type | string | What the movement refers to, for example order, user, review or your own type. |
reference_id | int | The referenced object’s ID. |
actor_id | int | The user who acted. Default: the current user. 0 means the system. |
The underlying services also accept wallet_id in place of the user ID.
add_action( 'rb_elite_balance_loaded', function () {
$result = rb_elbal_credit( 42, '10.00', array(
'type' => 'credit',
'idempotency_key' => 'loyalty:2026-07:user:42',
'note' => 'July loyalty reward.',
'reference_type' => 'user',
'reference_id' => 42,
'meta' => array( 'notify' => 'no', 'campaign' => 'loyalty-2026-07' ),
) );
if ( is_wp_error( $result ) ) {
error_log( $result->get_error_code() . ': ' . $result->get_error_message() );
return;
}
$result->was_replayed(); // true when this key already ran: nothing moved this time.
$result->balance_after(); // '52.0000'
} );
Note: Call the API on or after rb_elite_balance_loaded, or later in the request (for example init or a WooCommerce order hook). The example wraps the call in the action only to show the entry point; do not credit on every page load.
Error codes
↑ Back to top| WP_Error code | When |
|---|---|
rb_elbal_invalid_amount | The amount is not a positive decimal with at most four decimal places. |
rb_elbal_insufficient_funds | A debit exceeds the available balance, or the customer has no wallet. |
rb_elbal_wallet_locked | A debit on a locked wallet. Credits to locked wallets are allowed. |
rb_elbal_wallet_not_found | An explicit wallet_id does not exist. |
rb_elbal_database_error | An unexpected database failure. Nothing was written. |
rb_elbal_invalid_argument | A bad key (empty or longer than 191 characters) or a type that is not registered for the operation. |
The services throw exceptions in the RoundBorders\EliteBalance\Ledger\Exceptions namespace (InvalidAmountException, InsufficientFundsException, WalletLockedException, WalletNotFoundException, DuplicateHoldException, HoldNotPendingException, LedgerDatabaseException, all extending LedgerException with an error_code() method). Withdrawal exceptions live in RoundBorders\EliteBalance\Withdrawals\Exceptions (codes rb_elbal_withdrawal_not_found, rb_elbal_withdrawal_not_actionable, rb_elbal_withdrawal_duplicate, rb_elbal_withdrawal_access_denied).
Value objects
↑ Back to top| Class | Methods |
|---|---|
Ledger\Transaction | id(), wallet_id(), type(), amount() (signed), balance_after(), currency(), reference_type(), reference_id(), idempotency_key(), actor_id(), note(), meta(), created_at() (UTC), was_replayed() |
Ledger\Wallet | id(), user_id(), currency(), balance(), status(), is_active(), created_at(), updated_at() |
Ledger\Hold | id(), wallet_id(), amount(), status() (pending, captured, released, expired), is_pending(), reference_type(), reference_id(), expires_at(), created_at(), updated_at() |
Withdrawals\WithdrawalRequest | id(), user_id(), hold_id(), txn_id(), amount(), fee(), net_amount(), method(), details(), status(), customer_note(), admin_note(), transfer_reference(), acted_by(), created_at(), updated_at(), is_pending(), is_processing(), is_active(), is_terminal() |
All classes live under the RoundBorders\EliteBalance namespace.
Service container
↑ Back to toprb_elite_balance() returns the container. get( $id ) resolves a service (created once, then cached) and throws InvalidArgumentException for an unknown ID; has( $id ) checks for one. The services most integrations need:
| Service ID | Class | Use it for |
|---|---|---|
transactions | Ledger\Transactions | Credits, debits and ledger queries. |
wallets | Ledger\Wallets | Wallet lookup, balances, locking. |
holds | Ledger\Holds | Reserving, capturing and releasing funds. |
transaction_types | Ledger\TransactionTypes | The type registry: all(), exists(), direction(), label(). |
withdrawals | Withdrawals\Requests | The withdrawal request lifecycle. |
earn_rules | Earn\Rules | Earning rules: all(), get(), enabled_for(), create(), update(), delete(). |
earn_engine | Earn\Engine | award_rule( $rule, $args ) to award through a rule with the engine’s guarantees. |
migration_runner | Migration\Runner | Registered migration sources and their reports. |
history_archive | History\Archive | Reading the earlier history archive. |
history_copier | History\Copier | Starting and inspecting earlier history copies. |
template_loader | Support\TemplateLoader | Rendering Elite Balance templates with the theme override chain. |
logger | Support\Logger | Writing to the elite-balance WooCommerce log source. |
Other registered IDs (mostly screens and listeners): requirements, withdrawal_account, withdrawal_retention, order_events, refunds, partial_payment, wallet_discount, order_panel, wallet_screen, transactions_screen, withdrawals_screen, support_screen, earning_screen, admin_menu, user_integration, audience, bulk_adjustments, bulk_screen, audience_screen, import_screen, account_endpoint, balance_shortcode, balance_block, topup, emails, earn_pending, earn_pending_release, birthday_field, birthday_scan, history_account, history_admin, history_privacy, anomaly_export, migration_screen, tools_screen, stats, privacy, overview_screen. Treat these as internal: their methods may change between versions.
To swap or add a service, use the rb_elite_balance_container_bindings filter. It runs once, when the container is first built on plugins_loaded, so add it from your plugin’s main file.
Transactions
↑ Back to top| Method | Description |
|---|---|
credit( array $args ), debit( array $args ) | As the public functions, but the idempotency_key is required and failures throw. Return a Transaction (check was_replayed()). |
get( int $txn_id ) | One transaction or null. |
find_by_idempotency_key( string $key ) | The transaction written with a key, or null. Useful to check whether an operation already ran. |
query( array $args ), count( array $args ) | Filters: wallet_id, user_id, type, types, meta_contains, reference_type with reference_id, date_after and date_before (UTC Y-m-d H:i:s, inclusive), after_id. Paging: limit (default 20, max 200), offset, orderby (txn_id, created_at, amount), order (default DESC). |
sum_for_wallet( int $wallet_id ), last_for_wallet( int $wallet_id ) | The arithmetic behind wp rb-elbal reconcile. |
Wallets
↑ Back to top| Method | Description |
|---|---|
get( int $wallet_id ), get_for_user( int $user_id ) | A wallet or null. |
get_or_create_for_user( int $user_id ) | Always returns a wallet (race-safe). |
balance( int $user_id ), available_balance( int $user_id ) | Canonical strings. |
pending_holds_total( int $wallet_id ) | The total reserved by pending holds. |
set_status( int $wallet_id, string $status ) | Wallet::STATUS_ACTIVE ('active') or Wallet::STATUS_LOCKED ('locked'). A locked wallet refuses new debits and holds; credits and captures of existing holds still work. |
Holds
↑ Back to topA hold reserves part of the available balance without changing the balance. Checkout partial payments and withdrawal requests use holds. A hold ends in exactly one way: captured into a debit, released, or expired.
| Method | Description |
|---|---|
place( array $args ) | Arguments: user_id or wallet_id, amount, reference_type and reference_id (both required; one pending hold per reference), optional expires_at (UTC). Throws on a locked wallet, insufficient funds or a duplicate reference. |
capture( array $args ) | Arguments: hold_id or reference_type with reference_id, idempotency_key (required), optional type (default hold_capture), actor_id, note, meta. Returns the debit Transaction. Idempotent. |
release( array $args ) | hold_id or the reference. Releasing an already released or expired hold returns it unchanged; releasing a captured hold throws. |
get(), get_pending_for_reference(), pending_for_wallet(), pending_by_reference_type() | Lookups. |
expire_stale( int $limit = 100 ) | Releases pending holds past their expires_at. Core never sets an expiry on its own holds. |
Withdrawals
↑ Back to topThe plugin records requests and reserves funds; it never transmits money.
| Method | Description |
|---|---|
create( array $args ) | user_id, amount, method (a payout method key, for example bank-transfer or paypal for the default methods), optional details and customer_note. Places a hold. One active (pending or processing) request per customer. The service does not check your minimum, maximum or method list; the customer form does. |
mark_processing( int $id, int $actor_id = 0 ) | Bookkeeping only. The hold stays. |
transfer( int $id, array $args ) | reference (required), fee (0 or more, less than the amount), admin_note, actor_id. Captures the hold into a withdrawal debit for the full amount, with key withdrawal:{id}:capture. Idempotent. |
reject( int $id, array $args ) | reason (required, shown to the customer), actor_id. Releases the hold. |
cancel( int $id, int $user_id ) | The customer’s own pending request only. Releases the hold. |
get(), for_user(), active_for_user(), query(), count_for(), count_by_status() | Reads. query() accepts status, statuses, user_id, search (name, login, email or ID), limit, offset, order. |
Payout details are personal data: they are excluded from exports and blanked after a request has been closed for 30 days (filter rb_elite_balance_withdrawal_details_retention_days).
Earning rules
↑ Back to topearn_rules stores rules as arrays keyed by rule ID. create( $raw ) returns array( $rule_id|null, $errors ); update( $id, $raw ) returns array( $ok, $errors ); delete( $id ) refuses (returns false) once a rule has awarded anything, so the ledger’s meta.rule_id always resolves. Raw fields: label, trigger (order_cashback, topup_bonus, signup, review, birthday), amount_type (percent for order cashback and top-up bonus only, or fixed), amount_value, conditions (min_total, products, categories, roles), window_start and window_end (YYYY-MM-DD), enabled, notify, count_wallet_part (order cashback, 1.1.0). Conditions a trigger cannot use are dropped on save.
Rules never act retroactively: an event must happen after the rule’s current enabled_at. Every award writes meta.rule_id, so per-rule reporting is a ledger query.
Idempotency keys
↑ Back to topEvery ledger write carries a unique idempotency key, enforced by a unique database index. When the same key arrives again (a gateway retrying a notification, a double click, a re-run script), the ledger returns the original transaction, flagged was_replayed(), and changes nothing. Events never fire for replays.
- Build keys from your own stable identifiers:
'loyalty:2026-07:user:42','myplugin:order:1234:bonus'. Never use timestamps or random values for operations that can be retried. - Prefix keys with your plugin’s name so they cannot collide with core keys.
- A key is permanent. Reusing a key for a different operation returns the old transaction and does not write the new one.
Keys Elite Balance uses itself (useful with find_by_idempotency_key()):
| Key | Written by |
|---|---|
order:{order_id}:capture | Order payment: the full wallet payment, or the capture of a partial payment hold. |
refund:{refund_id}:credit | Refund to wallet, anchored to the WooCommerce refund record. |
refund:{refund_id}:wallet-return | Return to the wallet (the wallet part of an order) after a refund record exists. |
topup_order:{order_id}:credit | Top-up credit. |
withdrawal:{request_id}:capture | Withdrawal transferred. |
migration:{source_id}:{user_id} | Migrated opening balance. |
admin_adjust:{token} | Single adjustment from the wallet screen or Edit user card. |
bulk:{token}:{wallet_id} | Bulk operation and CSV import rows. |
earn:{rule_id}:order:{order_id} | Order cashback. |
earn:{rule_id}:order:{order_id}:refund:{refund_id}, earn:{rule_id}:order:{order_id}:reverse | Proportional reversal per refund, and the final sweep on cancellation or full refund. |
earn:{rule_id}:topup:{order_id}, earn:{rule_id}:signup:{user_id}, earn:{rule_id}:review:{comment_id}, earn:{rule_id}:birthday:{user_id}:{year} | Top-up bonus, signup, review and birthday rewards. |
When a refund has no record (unusual), the refund keys fall back to per-order forms such as order:{order_id}:refund:{n}:credit.
Transaction types
↑ Back to topEvery ledger row has a registered type. The type sets the direction a row may take and the label staff see. Core types cannot be removed.
| Type | Label | Direction | Note shown to customers |
|---|---|---|---|
credit | Credit | credit | No |
debit | Debit | debit | No |
hold_capture | Order payment | debit | Yes |
refund_credit | Refund to wallet | credit | Yes |
topup_credit | Top-up | credit | Yes |
withdrawal | Withdrawal | debit | Yes |
cashback | Cashback | credit | Yes |
reward | Reward | credit | Yes |
earn_reversal | Reward reversal | debit | Yes |
admin_adjust | Admin adjustment (customers see “Balance adjustment”) | any | No |
migration | Migrated balance | any | Yes |
Register your own type with rb_elite_balance_transaction_types. Keys are lowercase snake_case, at most 32 characters; direction is credit, debit or any. Notes on custom types are hidden from customers unless you add the type to rb_elite_balance_customer_note_types; do that only when the notes are written by code, never typed by staff.
add_filter( 'rb_elite_balance_transaction_types', function ( $types ) {
$types['partner_credit'] = array(
'label' => __( 'Partner credit', 'my-plugin' ),
'direction' => 'credit',
);
return $types;
} );
add_filter( 'rb_elite_balance_customer_note_types', function ( $types ) {
$types[] = 'partner_credit';
return $types;
} );
The Wallet credited and Wallet debited emails are skipped for hold_capture, migration and withdrawal (filter rb_elite_balance_email_skipped_types).
Events: when actions fire
↑ Back to topThe ledger actions (rb_elite_balance_transaction_created, the hold actions, and the refund, top-up, withdrawal, award and reversal actions) fire after the database commit, deferred to the outermost transaction, and never for idempotency replays or rolled-back work. Acting on them is safe and happens once per real movement. The exception by design is rb_elite_balance_earn_deferred, which fires when a pending award is recorded, before any money moves.
add_action( 'rb_elite_balance_transaction_created', function ( $transaction ) {
if ( 'refund_credit' !== $transaction->type() ) {
return;
}
// Push the refund-to-wallet to your ERP, CRM or analytics.
my_plugin_sync( array(
'txn_id' => $transaction->id(),
'amount' => $transaction->amount(),
'balance' => $transaction->balance_after(),
'order' => $transaction->reference_id(),
) );
} );
Actions and filters
↑ Back to topEvery hook in Elite Balance 1.1.0 uses the rb_elite_balance_ prefix. This list is generated from the plugin source: 82 hooks, counting the dynamic rb_elite_balance_account_tab_{id} once. Hooks marked 1.1.0 are new in this version. Each hook’s docblock in the source has the full signature.
Lifecycle and container
↑ Back to top| Hook | Type | Parameters and purpose |
|---|---|---|
rb_elite_balance_loaded | action | $plugin. Fires once the plugin has booted. Start integrations here. |
rb_elite_balance_installed | action | $schema_version. After the schema installs or upgrades (per site on multisite). |
rb_elite_balance_container_bindings | filter | $bindings, $plugin. Add or swap service factories. |
rb_elite_balance_capability_map | filter | $capability_map. Which roles get rb_elbal_manage_wallets on install. |
rb_elite_balance_advanced_logging_enabled | filter | $enabled. Force debug and info logging on or off. |
Ledger
↑ Back to top| Hook | Type | Parameters and purpose |
|---|---|---|
rb_elite_balance_before_credit | filter | $args. Credit arguments before validation. The main interception point for credits. |
rb_elite_balance_before_debit | filter | $args. Debit arguments before validation. |
rb_elite_balance_before_hold_placed | filter | $args. Hold arguments before the hold reserves funds. |
rb_elite_balance_transaction_created | action | $transaction. After any transaction commits. |
rb_elite_balance_hold_placed | action | $hold. After a hold commits. |
rb_elite_balance_hold_captured | action | $hold, $transaction. After a hold becomes a debit. |
rb_elite_balance_hold_released | action | $hold, $expired. After a hold is released, or expired when $expired is true. |
rb_elite_balance_transaction_types | filter | $types. Register custom transaction types. |
rb_elite_balance_customer_note_types | filter | $types. Types whose notes customers may see. |
rb_elite_balance_customer_note | filter | $note, $transaction. The note a customer sees for one row ('' hides it). |
rb_elite_balance_wallet_created | action | $wallet. After a wallet is created. |
rb_elite_balance_wallet_status_changed | action | $wallet, $from. After a lock or unlock. |
Checkout, orders and refunds
↑ Back to top| Hook | Type | Parameters and purpose |
|---|---|---|
rb_elite_balance_gateway_is_available | filter | $is_available, $user_id, $gateway. Final say on offering the Wallet balance method. |
rb_elite_balance_gateway_description | filter | $description, $available. The method description, balance suffix included. |
rb_elite_balance_partial_payment_offered | filter | $offered, $user_id. Whether partial payment is available to this customer. |
rb_elite_balance_partial_payment_smart_offer | filter | $offer, $total. Whether to show the toggle for this cart (default: only when the balance cannot cover the cart). Return true to always show it. |
rb_elite_balance_partial_payment_max_amount | filter | $cap, $cart. The most wallet money a partial payment may apply (default: cart contents plus their tax, shipping excluded). |
rb_elite_balance_partial_payment_label | filter | $label. The wallet line label at checkout and on orders (default “Wallet payment”). |
rb_elite_balance_wallet_discount_label | filter | $label. The pay-by-wallet discount line label (default “Wallet payment discount”). |
rb_elite_balance_wallet_discount_base | filter | $base, $context. The amount the pay-by-wallet discount is computed on (cart or order). |
rb_elite_balance_orphan_hold_statuses | filter | $statuses. Order statuses whose leftover holds the hourly safety sweep releases. |
rb_elite_balance_wallet_collection_failed | action | $order, $reason. A paid order’s wallet part could not be collected. Alert staff here. |
rb_elite_balance_refund_credited | action | $transaction, $order, $refund_id. A refund was credited to a wallet. |
Top-ups
↑ Back to top| Hook | Type | Parameters and purpose |
|---|---|---|
rb_elite_balance_topup_amount_limits | filter | $limits. Top-up min and max after the settings. |
rb_elite_balance_topup_credited | action | $transaction, $order. A paid top-up credited a wallet. |
Customer wallet page, block and shortcode
↑ Back to top| Hook | Type | Parameters and purpose |
|---|---|---|
rb_elite_balance_account_endpoint_label | filter | $label. The page name after the setting. |
rb_elite_balance_account_endpoint_slug | filter | $slug. The URL slug after the setting. |
rb_elite_balance_account_tabs | filter | $tabs. The wallet page tabs (id => label, priority). All-digit IDs are dropped. |
rb_elite_balance_account_tab_{id} | action | None. Renders a custom tab’s content while it is active. |
rb_elite_balance_account_transactions_per_page | filter | $per_page. History rows per page (default 15). |
rb_elite_balance_account_wallet_after_summary | action | None. After the balance summary, before the tabs. |
rb_elite_balance_account_wallet_before_history | action | None. Before the history table. |
rb_elite_balance_account_wallet_after_history | action | None. After the history table. |
rb_elite_balance_balance_html | filter | $html, $context, $user_id. Final HTML of the Wallet Balance block and shortcode. |
Emails
↑ Back to top| Hook | Type | Parameters and purpose |
|---|---|---|
rb_elite_balance_email_skipped_types | filter | $types. Types that never send the credited or debited email. |
Earning
↑ Back to top| Hook | Type | Parameters and purpose |
|---|---|---|
rb_elite_balance_earn_base | filter | $base, $order. The eligible base for order cashback (default: items after discounts, excluding shipping and tax, minus any pay-by-wallet discount). |
rb_elite_balance_earn_wallet_paid | filter | $wallet, $order, $paid. How much of an order was paid from the wallet, for rules that do not count the wallet part. 1.1.0. |
rb_elite_balance_earn_awarded | action | $transaction, $rule, $order. A rule credited a wallet (at release time under a delay). $order is null for signup, review and birthday. |
rb_elite_balance_earn_deferred | action | $entry, $rule, $order. An award was recorded as pending under the release delay. No money moved. |
rb_elite_balance_earn_reversed | action | $transaction, $rule, $order. A released award was (partly) reversed after a refund or cancellation. $rule is null when the rule was deleted. |
rb_elite_balance_pending_release_batch | filter | $batch. Orders processed per hourly release run (default 200). |
rb_elite_balance_birthday_field_label | filter | $label. The birthday field label on Account details. |
Withdrawals
↑ Back to top| Hook | Type | Parameters and purpose |
|---|---|---|
rb_elite_balance_withdrawal_requested | action | $request. A request was created and its hold placed. |
rb_elite_balance_withdrawal_transferred | action | $request, $transaction. A request was transferred and its hold captured. |
rb_elite_balance_withdrawal_rejected | action | $request, $reason. A request was rejected and its hold released. |
rb_elite_balance_withdrawal_cancelled | action | $request. The customer cancelled a pending request. |
rb_elite_balance_withdrawal_transfer_note | filter | $note, $request, $net, $fee, $reference. The ledger note for a transfer. |
rb_elite_balance_withdrawal_amount_limits | filter | $limits. Per-request min and max (max 0.0000 means no maximum). |
rb_elite_balance_withdrawal_methods | filter | $methods. Parsed payout methods (key, label, instructions, fee). |
rb_elite_balance_withdrawal_default_fee | filter | $fee. The default fee after the setting. |
rb_elite_balance_rejection_reasons | filter | $reasons. Preset rejection reasons on the admin form. |
rb_elite_balance_withdrawal_details_retention_days | filter | $days. Days after a request closes before its payout details are blanked (default 30, minimum 1). |
Migration and earlier history
↑ Back to top| Hook | Type | Parameters and purpose |
|---|---|---|
rb_elite_balance_migration_sources | filter | $sources. Register migration sources (id => SourceInterface). |
rb_elite_balance_migration_completed | action | $source_id, $report. A balance migration finished. 1.1.0. |
rb_elite_balance_history_auto_copy | filter | $auto, $source_id. Whether a finished migration starts the earlier history copy (default true). 1.1.0. |
rb_elite_balance_history_entry | filter | $entry, $source_id. One history entry before it is archived; return false to skip it. 1.1.0. |
rb_elite_balance_history_kinds | filter | $kinds. Register earlier history kinds and their customer labels. 1.1.0. |
rb_elite_balance_history_copied | action | $source_id, $state. An earlier history copy finished. 1.1.0. |
rb_elite_balance_history_customer_visible | filter | $enabled. Whether customers see Earlier activity (default from the setting). 1.1.0. |
rb_elite_balance_history_per_page | filter | $per_page. Earlier activity entries per page (default 15). 1.1.0. |
Admin
↑ Back to top| Hook | Type | Parameters and purpose |
|---|---|---|
rb_elite_balance_overview_top | action | None. Top of the Overview tab, before the tiles. The finished-migration line mounts here. |
rb_elite_balance_overview_attention | filter | $items. Overview “Needs attention” items (id, tone, status, message, url, action). 1.1.0. |
rb_elite_balance_overview_quick_actions | filter | $actions. Overview quick actions (label, url). 1.1.0. |
rb_elite_balance_admin_wallet_links | filter | $links, $user_id, $context. Quick links on the wallet screen header and the Edit user Wallet card ('wallet' or 'profile'). 1.1.0. |
rb_elite_balance_admin_transaction_reference | filter | $html, $transaction. The Reference cell of a ledger row in admin tables. 1.1.0. |
rb_elite_balance_admin_wallet_after_history | action | $user_id. End of the wallet screen, under the history. 1.1.0. |
rb_elite_balance_migration_card_after | action | $source_id, $source, $state. End of a migration card on the Tools tab. 1.1.0. |
rb_elite_balance_tools_sections | action | None. After the built-in Tools sections and before Support. Add your own section. |
rb_elite_balance_settings_fields | filter | $settings, $section_id. Settings fields per section ('' for General, topups, earning, withdrawals, advanced). |
rb_elite_balance_adjustment_reasons | filter | $reasons. Preset reasons on adjustment forms (after the setting). |
rb_elite_balance_audience_conditions | filter | $conditions. Register custom bulk operation audience conditions. |
rb_elite_balance_batch_retention_days | filter | $days. Days bulk operation summaries are kept (default 90; ledger rows stay forever). |
rb_elite_balance_import_max_rows | filter | $rows. CSV import row limit (default 10,000). |
rb_elite_balance_import_max_bytes | filter | $bytes. CSV import file size limit (default 1 MB). |
rb_elite_balance_import_pending_ttl | filter | $seconds. How long an unconfirmed CSV upload stays reviewable (default one hour). |
Templates
↑ Back to top| Hook | Type | Parameters and purpose |
|---|---|---|
rb_elite_balance_locate_template | filter | $template, $template_name. The resolved template path; return '' to suppress output. |
rb_elite_balance_template_args | filter | $args, $template_name. The $args array passed into a template. |
Custom migration sources
↑ Back to topA migration source teaches Elite Balance where another wallet plugin keeps its balances. Register one and it gets everything the built-in sources have: a card in the Migration section of the Tools tab with the deactivate-first step, background chunking, at-most-once imports, the anomaly report, the reconciliation check, and wp rb-elbal migrate <your-id>.
SourceInterface
↑ Back to topImplement RoundBorders\EliteBalance\Migration\SourceInterface:
| Method | Returns | Purpose |
|---|---|---|
id() | string | Unique lowercase key, for example acme. |
label() | string | The name shown in the admin. |
detect() | array | array( 'available' => bool, 'blockers' => string[] ). Available means data exists. Blockers are hard blockers only (for example a network-activated source plugin). |
active_plugin_files() | string[] | Active plugin basenames to deactivate before a real run. Empty when nothing needs deactivating. |
count() | int | Customers with an importable (positive) balance. |
total() | string | The summed importable balance, canonical, for the reconciliation check. |
max_user_id() | int | The highest user ID with source data (the snapshot boundary). |
rows( int $cursor, int $max_user_id, int $limit ) | array | The next slice, by user ID above $cursor up to $max_user_id. Each row: user_id, amount (canonical, or null when unreadable), issue (null, or a label such as not_numeric or negative), raw (the stored value). |
rows() must return every user with source data exactly once across the walk, zeros and broken values included. Return unreadable values with amount => null and an issue; the engine decides what to skip and what to report. The engine assigns the idempotency key (migration:{source_id}:{user_id}), so re-runs never import twice.
add_filter( 'rb_elite_balance_migration_sources', function ( $sources ) {
$sources['acme'] = new Acme_Wallet_Source(); // implements SourceInterface
return $sources;
} );
The built-in WP Swings source (Migration\Sources\WpSwings, built on the abstract Migration\Sources\UserMetaSource) is a good model for a plugin that stores balances in user meta.
HistorySourceInterface (earlier history)
↑ Back to topNew in 1.1.0. Implement RoundBorders\EliteBalance\Migration\HistorySourceInterface on the same object to let Elite Balance copy the old plugin’s transaction log into the earlier history archive. The copy then starts automatically when your migration finishes, and works from the Tools card and wp rb-elbal history copy <your-id>.
| Method | Returns | Purpose |
|---|---|---|
history_count() | int | How many log entries the source holds (0 when the log table is missing). A progress estimate. |
history_rows( int $cursor, int $limit ) | array | The next slice of entries, oldest first, by the source’s own row ID above $cursor. Fewer than $limit means the end. Throw on a database error; never return an empty slice for an error. |
Each entry is an array:
| Key | Type | Description |
|---|---|---|
ref | int | The source’s row ID, strictly ascending. With the source ID it is the archive’s unique key, so re-runs never duplicate. |
user_id | int | The customer, or 0 when no registered customer matches (skipped and counted). |
occurred_at | string | UTC Y-m-d H:i:s, or ''. |
direction | string | credit or debit. |
amount | string|null | Canonical positive amount, or null when unreadable (skipped and counted). |
currency | string | Currency code, or ''. |
kind | string | A registered kind (customer label). Unknown kinds fall back to the generic credit or debit label. |
counted | bool | Whether the entry counted toward the old balance. Entries that did not are hidden from customers. |
status | string | The source’s status word, for staff. |
details, method, note | string | Original description, method and note, plain text. Staff only, never shown to customers. |
order_ids | int[] | Candidate order IDs. The first one that belongs to the customer is linked. |
balance_after | string|null | The source’s running balance, if it has one. |
Built-in kinds: order_payment, refund, topup, cashback, cashback_reversal, reward, transfer_in, transfer_out, withdrawal, fee, expired, carried_over, credit_adjustment, debit_adjustment, not_applied. Add your own, and map a store’s own descriptions to them before archiving:
add_filter( 'rb_elite_balance_history_kinds', function ( $kinds ) {
$kinds['gift_card'] = array( 'label' => __( 'Gift card', 'my-plugin' ) );
return $kinds;
} );
add_filter( 'rb_elite_balance_history_entry', function ( $entry, $source_id ) {
if ( is_array( $entry ) && false !== stripos( $entry['details'], 'gift card' ) ) {
$entry['kind'] = 'gift_card';
}
return $entry; // Return false to leave an entry out.
}, 10, 2 );
Template overrides
↑ Back to topCopy a template from the plugin’s templates/ folder into your theme and edit the copy. Templates receive one $args array; filter it with rb_elite_balance_template_args, or reroute a template with rb_elite_balance_locate_template.
| Template | Version | Override path |
|---|---|---|
myaccount/wallet.php | 0.9.0 | yourtheme/elite-balance/myaccount/wallet.php |
myaccount/topup-form.php | 0.9.0 | yourtheme/elite-balance/myaccount/topup-form.php |
myaccount/withdraw-form.php | 0.9.0 | yourtheme/elite-balance/myaccount/withdraw-form.php |
myaccount/pending-cashback.php | 1.1.0 | yourtheme/elite-balance/myaccount/pending-cashback.php |
myaccount/earlier-activity.php | 1.1.0 | yourtheme/elite-balance/myaccount/earlier-activity.php |
balance.php | 0.5.0 | yourtheme/elite-balance/balance.php |
checkout/partial-payment.php | 0.9.0 | yourtheme/elite-balance/checkout/partial-payment.php |
emails/wallet-credited.php and plain/ twin | 0.5.0 | yourtheme/woocommerce/emails/wallet-credited.php |
emails/wallet-debited.php and plain/ twin | 0.5.0 | yourtheme/woocommerce/emails/wallet-debited.php |
emails/low-balance.php and plain/ twin | 0.5.0 | yourtheme/woocommerce/emails/low-balance.php |
emails/withdrawal-notification.php and plain/ twin | 0.8.0 | yourtheme/woocommerce/emails/withdrawal-notification.php (shared by the four withdrawal emails) |
What each template renders is described on Customer Wallet Page, Block and Shortcode.
REST and Store API
↑ Back to topElite Balance registers no REST routes of its own. The Checkout block integration uses the WooCommerce Store API:
| Item | Details |
|---|---|
| Payment method | ID rb_elbal_wallet. Payment method data: title, description (with the available balance appended for logged-in customers), supports (products, refunds), discount (true while a pay-by-wallet discount is configured). |
| Cart extension data | Namespace rb-elbal-partial on the cart endpoint: offered (bool), enabled (bool), amount, amount_display, available_display (strings). The partial payment UI state for the current customer. |
Update callback rb-elbal-partial | Data { enabled: bool, amount: string }. Turns partial payment on or off and sets the requested wallet amount (empty for the maximum). Logged-in customers only. |
Update callback rb-elbal-wallet | Data { selected: true }. Records the wallet as the chosen payment method so the pay-by-wallet discount line matches the selection (1.1.0). |
Both checkouts re-validate the partial amount and the discount on the server when the order is placed.
Other identifiers
↑ Back to top| Identifier | What it is |
|---|---|
_rb_elbal_topup_order | Order meta that marks a top-up order. |
_rb_elbal_wallet_applied | Order meta: the wallet amount applied by a partial payment. |
_rb_elbal_wallet_discount | Order meta for the pay-by-wallet discount line. |
_rb_elbal_pending_awards | Order meta: cashback and top-up bonuses pending under the release delay. |
rb_elbal_birthday | User meta: the customer’s birthday from the opt-in Account details field. |
rb_elbal_wallet_credited, rb_elbal_wallet_debited, rb_elbal_low_balance, rb_elbal_withdrawal_requested, rb_elbal_new_withdrawal_request, rb_elbal_withdrawal_transferred, rb_elbal_withdrawal_rejected | Email IDs, for admin.php?page=wc-settings&tab=email§ion=... links and email filters. |
Action Scheduler group elite-balance | Recurring: rb_elbal_expire_holds (hourly), rb_elbal_earn_pending_release (hourly), rb_elbal_birthday_scan (daily), rb_elbal_blank_withdrawal_details (daily). Workers: rb_elbal_migration_chunk, rb_elbal_history_chunk, rb_elbal_prepare_anomaly_export, rb_elbal_process_bulk_chunk, rb_elbal_process_bulk_query_chunk, rb_elbal_process_bulk_rows_chunk. |
WP-CLI commands are documented on WP-CLI Commands.