Developer Reference

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_wallets capability, granted to the Administrator and Shop manager roles on activation (filter rb_elite_balance_capability_map).

Database tables

↑ Back to top

All tables use your $wpdb->prefix.

TableHolds
rb_elbal_walletsOne row per customer wallet: user, currency, balance, status (active or locked).
rb_elbal_transactionsThe 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_holdsReservations against a wallet’s available balance: pending, captured, released or expired.
rb_elbal_withdrawalsCustomer withdrawal requests and their lifecycle.
rb_elbal_historyThe earlier history archive copied from a previous wallet plugin (1.1.0). Never part of the ledger.

Public functions

↑ Back to top

These functions are semver-stable public API. The write functions return a WP_Error instead of throwing.

FunctionReturnsWhat it does
rb_elite_balance()PluginThe service container (see Service container).
rb_elbal_credit( int $user_id, $amount, array $args = array() )Transaction|WP_ErrorCredits a wallet. Creates the wallet when the customer has none.
rb_elbal_debit( int $user_id, $amount, array $args = array() )Transaction|WP_ErrorDebits a wallet. Fails when the amount exceeds the available balance or the wallet is locked.
rb_elbal_balance( int $user_id )stringThe ledger balance, canonical ('25.5000'). '0.0000' for a customer without a wallet.
rb_elbal_available_balance( int $user_id )stringThe balance minus pending holds: what checkout and withdrawals can use now.
rb_elbal_wallet( int $user_id )Wallet|nullThe wallet object, or null when the customer has none yet.

Credit and debit arguments

↑ Back to top
KeyTypeDescription
idempotency_keystringDeterministic key, 1 to 191 characters. Strongly recommended. When omitted, the functions generate a unique key per call, so a retried call moves money again.
typestringA registered transaction type whose direction allows the operation. Default credit for credits and debit for debits.
notestringPlain-text note. Staff always see it; customers only see notes on the types listed in rb_elite_balance_customer_note_types.
metaarrayStructured data stored as JSON on the row. 'notify' => 'no' suppresses the Wallet credited or debited email for this transaction.
reference_typestringWhat the movement refers to, for example order, user, review or your own type.
reference_idintThe referenced object’s ID.
actor_idintThe 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 codeWhen
rb_elbal_invalid_amountThe amount is not a positive decimal with at most four decimal places.
rb_elbal_insufficient_fundsA debit exceeds the available balance, or the customer has no wallet.
rb_elbal_wallet_lockedA debit on a locked wallet. Credits to locked wallets are allowed.
rb_elbal_wallet_not_foundAn explicit wallet_id does not exist.
rb_elbal_database_errorAn unexpected database failure. Nothing was written.
rb_elbal_invalid_argumentA 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
ClassMethods
Ledger\Transactionid(), wallet_id(), type(), amount() (signed), balance_after(), currency(), reference_type(), reference_id(), idempotency_key(), actor_id(), note(), meta(), created_at() (UTC), was_replayed()
Ledger\Walletid(), user_id(), currency(), balance(), status(), is_active(), created_at(), updated_at()
Ledger\Holdid(), wallet_id(), amount(), status() (pending, captured, released, expired), is_pending(), reference_type(), reference_id(), expires_at(), created_at(), updated_at()
Withdrawals\WithdrawalRequestid(), 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 top

rb_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 IDClassUse it for
transactionsLedger\TransactionsCredits, debits and ledger queries.
walletsLedger\WalletsWallet lookup, balances, locking.
holdsLedger\HoldsReserving, capturing and releasing funds.
transaction_typesLedger\TransactionTypesThe type registry: all(), exists(), direction(), label().
withdrawalsWithdrawals\RequestsThe withdrawal request lifecycle.
earn_rulesEarn\RulesEarning rules: all(), get(), enabled_for(), create(), update(), delete().
earn_engineEarn\Engineaward_rule( $rule, $args ) to award through a rule with the engine’s guarantees.
migration_runnerMigration\RunnerRegistered migration sources and their reports.
history_archiveHistory\ArchiveReading the earlier history archive.
history_copierHistory\CopierStarting and inspecting earlier history copies.
template_loaderSupport\TemplateLoaderRendering Elite Balance templates with the theme override chain.
loggerSupport\LoggerWriting 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
MethodDescription
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
MethodDescription
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 top

A 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.

MethodDescription
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 top

The plugin records requests and reserves funds; it never transmits money.

MethodDescription
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 top

earn_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 top

Every 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()):

KeyWritten by
order:{order_id}:captureOrder payment: the full wallet payment, or the capture of a partial payment hold.
refund:{refund_id}:creditRefund to wallet, anchored to the WooCommerce refund record.
refund:{refund_id}:wallet-returnReturn to the wallet (the wallet part of an order) after a refund record exists.
topup_order:{order_id}:creditTop-up credit.
withdrawal:{request_id}:captureWithdrawal 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}:reverseProportional 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 top

Every 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.

TypeLabelDirectionNote shown to customers
creditCreditcreditNo
debitDebitdebitNo
hold_captureOrder paymentdebitYes
refund_creditRefund to walletcreditYes
topup_creditTop-upcreditYes
withdrawalWithdrawaldebitYes
cashbackCashbackcreditYes
rewardRewardcreditYes
earn_reversalReward reversaldebitYes
admin_adjustAdmin adjustment (customers see “Balance adjustment”)anyNo
migrationMigrated balanceanyYes

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 top

The 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 top

Every 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
HookTypeParameters and purpose
rb_elite_balance_loadedaction$plugin. Fires once the plugin has booted. Start integrations here.
rb_elite_balance_installedaction$schema_version. After the schema installs or upgrades (per site on multisite).
rb_elite_balance_container_bindingsfilter$bindings, $plugin. Add or swap service factories.
rb_elite_balance_capability_mapfilter$capability_map. Which roles get rb_elbal_manage_wallets on install.
rb_elite_balance_advanced_logging_enabledfilter$enabled. Force debug and info logging on or off.

Ledger

↑ Back to top
HookTypeParameters and purpose
rb_elite_balance_before_creditfilter$args. Credit arguments before validation. The main interception point for credits.
rb_elite_balance_before_debitfilter$args. Debit arguments before validation.
rb_elite_balance_before_hold_placedfilter$args. Hold arguments before the hold reserves funds.
rb_elite_balance_transaction_createdaction$transaction. After any transaction commits.
rb_elite_balance_hold_placedaction$hold. After a hold commits.
rb_elite_balance_hold_capturedaction$hold, $transaction. After a hold becomes a debit.
rb_elite_balance_hold_releasedaction$hold, $expired. After a hold is released, or expired when $expired is true.
rb_elite_balance_transaction_typesfilter$types. Register custom transaction types.
rb_elite_balance_customer_note_typesfilter$types. Types whose notes customers may see.
rb_elite_balance_customer_notefilter$note, $transaction. The note a customer sees for one row ('' hides it).
rb_elite_balance_wallet_createdaction$wallet. After a wallet is created.
rb_elite_balance_wallet_status_changedaction$wallet, $from. After a lock or unlock.

Checkout, orders and refunds

↑ Back to top
HookTypeParameters and purpose
rb_elite_balance_gateway_is_availablefilter$is_available, $user_id, $gateway. Final say on offering the Wallet balance method.
rb_elite_balance_gateway_descriptionfilter$description, $available. The method description, balance suffix included.
rb_elite_balance_partial_payment_offeredfilter$offered, $user_id. Whether partial payment is available to this customer.
rb_elite_balance_partial_payment_smart_offerfilter$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_amountfilter$cap, $cart. The most wallet money a partial payment may apply (default: cart contents plus their tax, shipping excluded).
rb_elite_balance_partial_payment_labelfilter$label. The wallet line label at checkout and on orders (default “Wallet payment”).
rb_elite_balance_wallet_discount_labelfilter$label. The pay-by-wallet discount line label (default “Wallet payment discount”).
rb_elite_balance_wallet_discount_basefilter$base, $context. The amount the pay-by-wallet discount is computed on (cart or order).
rb_elite_balance_orphan_hold_statusesfilter$statuses. Order statuses whose leftover holds the hourly safety sweep releases.
rb_elite_balance_wallet_collection_failedaction$order, $reason. A paid order’s wallet part could not be collected. Alert staff here.
rb_elite_balance_refund_creditedaction$transaction, $order, $refund_id. A refund was credited to a wallet.

Top-ups

↑ Back to top
HookTypeParameters and purpose
rb_elite_balance_topup_amount_limitsfilter$limits. Top-up min and max after the settings.
rb_elite_balance_topup_creditedaction$transaction, $order. A paid top-up credited a wallet.

Customer wallet page, block and shortcode

↑ Back to top
HookTypeParameters and purpose
rb_elite_balance_account_endpoint_labelfilter$label. The page name after the setting.
rb_elite_balance_account_endpoint_slugfilter$slug. The URL slug after the setting.
rb_elite_balance_account_tabsfilter$tabs. The wallet page tabs (id => label, priority). All-digit IDs are dropped.
rb_elite_balance_account_tab_{id}actionNone. Renders a custom tab’s content while it is active.
rb_elite_balance_account_transactions_per_pagefilter$per_page. History rows per page (default 15).
rb_elite_balance_account_wallet_after_summaryactionNone. After the balance summary, before the tabs.
rb_elite_balance_account_wallet_before_historyactionNone. Before the history table.
rb_elite_balance_account_wallet_after_historyactionNone. After the history table.
rb_elite_balance_balance_htmlfilter$html, $context, $user_id. Final HTML of the Wallet Balance block and shortcode.

Emails

↑ Back to top
HookTypeParameters and purpose
rb_elite_balance_email_skipped_typesfilter$types. Types that never send the credited or debited email.

Earning

↑ Back to top
HookTypeParameters and purpose
rb_elite_balance_earn_basefilter$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_paidfilter$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_awardedaction$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_deferredaction$entry, $rule, $order. An award was recorded as pending under the release delay. No money moved.
rb_elite_balance_earn_reversedaction$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_batchfilter$batch. Orders processed per hourly release run (default 200).
rb_elite_balance_birthday_field_labelfilter$label. The birthday field label on Account details.

Withdrawals

↑ Back to top
HookTypeParameters and purpose
rb_elite_balance_withdrawal_requestedaction$request. A request was created and its hold placed.
rb_elite_balance_withdrawal_transferredaction$request, $transaction. A request was transferred and its hold captured.
rb_elite_balance_withdrawal_rejectedaction$request, $reason. A request was rejected and its hold released.
rb_elite_balance_withdrawal_cancelledaction$request. The customer cancelled a pending request.
rb_elite_balance_withdrawal_transfer_notefilter$note, $request, $net, $fee, $reference. The ledger note for a transfer.
rb_elite_balance_withdrawal_amount_limitsfilter$limits. Per-request min and max (max 0.0000 means no maximum).
rb_elite_balance_withdrawal_methodsfilter$methods. Parsed payout methods (key, label, instructions, fee).
rb_elite_balance_withdrawal_default_feefilter$fee. The default fee after the setting.
rb_elite_balance_rejection_reasonsfilter$reasons. Preset rejection reasons on the admin form.
rb_elite_balance_withdrawal_details_retention_daysfilter$days. Days after a request closes before its payout details are blanked (default 30, minimum 1).

Migration and earlier history

↑ Back to top
HookTypeParameters and purpose
rb_elite_balance_migration_sourcesfilter$sources. Register migration sources (id => SourceInterface).
rb_elite_balance_migration_completedaction$source_id, $report. A balance migration finished. 1.1.0.
rb_elite_balance_history_auto_copyfilter$auto, $source_id. Whether a finished migration starts the earlier history copy (default true). 1.1.0.
rb_elite_balance_history_entryfilter$entry, $source_id. One history entry before it is archived; return false to skip it. 1.1.0.
rb_elite_balance_history_kindsfilter$kinds. Register earlier history kinds and their customer labels. 1.1.0.
rb_elite_balance_history_copiedaction$source_id, $state. An earlier history copy finished. 1.1.0.
rb_elite_balance_history_customer_visiblefilter$enabled. Whether customers see Earlier activity (default from the setting). 1.1.0.
rb_elite_balance_history_per_pagefilter$per_page. Earlier activity entries per page (default 15). 1.1.0.

Admin

↑ Back to top
HookTypeParameters and purpose
rb_elite_balance_overview_topactionNone. Top of the Overview tab, before the tiles. The finished-migration line mounts here.
rb_elite_balance_overview_attentionfilter$items. Overview “Needs attention” items (id, tone, status, message, url, action). 1.1.0.
rb_elite_balance_overview_quick_actionsfilter$actions. Overview quick actions (label, url). 1.1.0.
rb_elite_balance_admin_wallet_linksfilter$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_referencefilter$html, $transaction. The Reference cell of a ledger row in admin tables. 1.1.0.
rb_elite_balance_admin_wallet_after_historyaction$user_id. End of the wallet screen, under the history. 1.1.0.
rb_elite_balance_migration_card_afteraction$source_id, $source, $state. End of a migration card on the Tools tab. 1.1.0.
rb_elite_balance_tools_sectionsactionNone. After the built-in Tools sections and before Support. Add your own section.
rb_elite_balance_settings_fieldsfilter$settings, $section_id. Settings fields per section ('' for General, topups, earning, withdrawals, advanced).
rb_elite_balance_adjustment_reasonsfilter$reasons. Preset reasons on adjustment forms (after the setting).
rb_elite_balance_audience_conditionsfilter$conditions. Register custom bulk operation audience conditions.
rb_elite_balance_batch_retention_daysfilter$days. Days bulk operation summaries are kept (default 90; ledger rows stay forever).
rb_elite_balance_import_max_rowsfilter$rows. CSV import row limit (default 10,000).
rb_elite_balance_import_max_bytesfilter$bytes. CSV import file size limit (default 1 MB).
rb_elite_balance_import_pending_ttlfilter$seconds. How long an unconfirmed CSV upload stays reviewable (default one hour).

Templates

↑ Back to top
HookTypeParameters and purpose
rb_elite_balance_locate_templatefilter$template, $template_name. The resolved template path; return '' to suppress output.
rb_elite_balance_template_argsfilter$args, $template_name. The $args array passed into a template.

Custom migration sources

↑ Back to top

A 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 top

Implement RoundBorders\EliteBalance\Migration\SourceInterface:

MethodReturnsPurpose
id()stringUnique lowercase key, for example acme.
label()stringThe name shown in the admin.
detect()arrayarray( '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()intCustomers with an importable (positive) balance.
total()stringThe summed importable balance, canonical, for the reconciliation check.
max_user_id()intThe highest user ID with source data (the snapshot boundary).
rows( int $cursor, int $max_user_id, int $limit )arrayThe 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 top

New 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>.

MethodReturnsPurpose
history_count()intHow many log entries the source holds (0 when the log table is missing). A progress estimate.
history_rows( int $cursor, int $limit )arrayThe 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:

KeyTypeDescription
refintThe source’s row ID, strictly ascending. With the source ID it is the archive’s unique key, so re-runs never duplicate.
user_idintThe customer, or 0 when no registered customer matches (skipped and counted).
occurred_atstringUTC Y-m-d H:i:s, or ''.
directionstringcredit or debit.
amountstring|nullCanonical positive amount, or null when unreadable (skipped and counted).
currencystringCurrency code, or ''.
kindstringA registered kind (customer label). Unknown kinds fall back to the generic credit or debit label.
countedboolWhether the entry counted toward the old balance. Entries that did not are hidden from customers.
statusstringThe source’s status word, for staff.
details, method, notestringOriginal description, method and note, plain text. Staff only, never shown to customers.
order_idsint[]Candidate order IDs. The first one that belongs to the customer is linked.
balance_afterstring|nullThe 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 top

Copy 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.

TemplateVersionOverride path
myaccount/wallet.php0.9.0yourtheme/elite-balance/myaccount/wallet.php
myaccount/topup-form.php0.9.0yourtheme/elite-balance/myaccount/topup-form.php
myaccount/withdraw-form.php0.9.0yourtheme/elite-balance/myaccount/withdraw-form.php
myaccount/pending-cashback.php1.1.0yourtheme/elite-balance/myaccount/pending-cashback.php
myaccount/earlier-activity.php1.1.0yourtheme/elite-balance/myaccount/earlier-activity.php
balance.php0.5.0yourtheme/elite-balance/balance.php
checkout/partial-payment.php0.9.0yourtheme/elite-balance/checkout/partial-payment.php
emails/wallet-credited.php and plain/ twin0.5.0yourtheme/woocommerce/emails/wallet-credited.php
emails/wallet-debited.php and plain/ twin0.5.0yourtheme/woocommerce/emails/wallet-debited.php
emails/low-balance.php and plain/ twin0.5.0yourtheme/woocommerce/emails/low-balance.php
emails/withdrawal-notification.php and plain/ twin0.8.0yourtheme/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 top

Elite Balance registers no REST routes of its own. The Checkout block integration uses the WooCommerce Store API:

ItemDetails
Payment methodID 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 dataNamespace 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-partialData { 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-walletData { 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
IdentifierWhat it is
_rb_elbal_topup_orderOrder meta that marks a top-up order.
_rb_elbal_wallet_appliedOrder meta: the wallet amount applied by a partial payment.
_rb_elbal_wallet_discountOrder meta for the pay-by-wallet discount line.
_rb_elbal_pending_awardsOrder meta: cashback and top-up bonuses pending under the release delay.
rb_elbal_birthdayUser 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_rejectedEmail IDs, for admin.php?page=wc-settings&tab=email&section=... links and email filters.
Action Scheduler group elite-balanceRecurring: 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.

Related

↑ Back to top
Use of your personal data
We and our partners process your personal data (such as browsing data, IP Addresses, cookie information, and other unique identifiers) based on your consent and/or our legitimate interest to optimize our website, marketing activities, and your user experience.