Documentation / Elite Balance

about the plugin →

Custom migration sources

Plug any wallet plugin into the migration engine and inherit chunking, idempotency, the report, the UI, and the CLI for free.

What the engine gives you

Registering a source teaches Elite Balance where another wallet plugin keeps its balances. Everything else is inherited: background chunking, at-most-once imports per customer, the anomaly report, the reconciliation verdict, the Migration screen card with the deactivate-first step, and wp rb-elbal migrate your-source.

The contract

Implement RoundBorders\EliteBalance\Migration\SourceInterface:

MethodReturnsPurpose
id()stringUnique lowercase key, e.g. acme.
label()stringHuman name shown in the UI.
detect()array['available' => bool, 'blockers' => string[]]. Available means data exists on this site. Blockers are HARD blockers only (things the framework cannot fix, like a network-activated source plugin).
active_plugin_files()string[]Plugin basenames currently active that must be deactivated before a real run. The screen offers deactivating them as the one-click freeze step; return an empty array when nothing needs freezing.
count()intHow many customers hold an importable (positive) balance.
total()stringThe summed importable balance, canonical, for the reconciliation check.
max_user_id()intThe highest user ID carrying source data (the snapshot boundary).
rows( $cursor, $max, $limit )arrayThe next slice, keyset-paginated by user ID: each row is ['user_id' => int, 'amount' => string or null, 'issue' => string or null].

Two rules make the report trustworthy: rows() must return every user with source data exactly once across the walk, including zeros and broken values, and unparseable values must come back with amount => null and an issue label instead of being skipped. The engine decides what to skip and what to report; sources never silently drop anyone.

The engine assigns the idempotency key (migration:{source}:{user_id}), so re-runs replay automatically. You never handle that.

Registering

add_filter( 'rb_elite_balance_migration_sources', function ( $sources ) {
	$sources['acme'] = new Acme_Wallet_Source();
	return $sources;
} );

The source appears on the Migration screen with its own card, and works from the CLI immediately:

wp rb-elbal migrate acme --deactivate --yes

Model to copy: the built-in WP Swings source reads one user meta per customer with keyset pagination and classifies bad values instead of skipping them. Yours will usually be under a hundred lines.

Stuck, or found a gap in these docs? Tell us and a human who works on the plugin answers.

Contact support →