Wallet Callbacks
Implement debit, credit, and rollback endpoints for Phoenix
Your wallet remains the source of truth for player balances. Phoenix asks your backend to move money when a player places or settles a prediction.
Phoenix derives callback URLs from your wallet base URL:
{wallet_base_url}/debit
{wallet_base_url}/credit
{wallet_base_url}/rollbackUse HTTPS in all shared environments. Local http://localhost is only for development.
Common Request Fields
| Field | Type | Description |
|---|---|---|
player_id | string | Your player ID, copied from the player JWT sub claim |
amount | integer | Amount in cents, floored by Phoenix |
game | string | prediction_market_v1 |
instance_id | string | Phoenix instance identifier |
action_id | string | Player-scoped action identifier |
tx_id | string | Idempotency key for this wallet operation |
POST /debit
Phoenix calls debit before accepting a bet. If your backend rejects the debit, the bet is not placed.
{
"player_id": "operator-player-123",
"amount": 1000,
"game": "prediction_market_v1",
"instance_id": "phoenix_prediction_default",
"action": "BET",
"action_id": "operator-player-123:018f8f6d-...",
"tx_id": "debit:operator-player-123:018f8f6d-..."
}Return success after you have reserved or deducted the funds:
{
"type": "SUCCESS",
"balance": "990.00",
"timestamp": "2026-05-18T12:00:00Z"
}Return a business rejection with HTTP 200 and type: "ERROR":
{
"type": "ERROR",
"code": "insufficient_funds",
"balance": "5.00"
}Phoenix maps insufficient_funds to a user-facing insufficient funds state. Other error codes are preserved for diagnostics.
POST /credit
Phoenix calls credit after a market settles. Winners receive their settlement amount. Losing positions can still receive a credit call with amount: 0 so every bet has a settlement notification.
{
"player_id": "operator-player-123",
"amount": 2400,
"game": "prediction_market_v1",
"instance_id": "phoenix_prediction_default",
"action": {
"type": "BET",
"round_id": "market-uuid",
"wager": 1000,
"won": 2400
},
"action_id": "operator-player-123:wager-uuid",
"tx_id": "credit:wager-uuid"
}Return success after the settlement has been recorded in your ledger.
{
"type": "SUCCESS",
"balance": "1014.00",
"timestamp": "2026-05-18T12:05:00Z"
}Phoenix retries failed credit notifications with backoff. Your tx_id handling must make repeated credit calls safe.
POST /rollback
Phoenix calls rollback when a previously accepted debit must be reversed.
{
"player_id": "operator-player-123",
"amount": 1000,
"game": "prediction_market_v1",
"instance_id": "phoenix_prediction_default",
"action": "BET",
"action_id": "operator-player-123:wager-uuid",
"tx_id": "rollback:wager-uuid",
"round_id": "market-uuid"
}Treat rollback as a refund for the referenced debit. Return the same response for repeated rollback calls with the same tx_id.
HTTP Status Rules
Use HTTP 200 with type: "ERROR" when the request is valid but the wallet rejects it for a business reason, such as insufficient funds.
Use 401 when the Phoenix signature is missing or invalid.
Use 5xx only for temporary infrastructure failures. A 5xx on credit will be retried. A 5xx on debit can cause the player action to fail immediately.