Phoenix Wallet

Transfers

API endpoint for moving funds between wallets

Transfers move funds from one wallet to another. The system uses double-entry accounting to ensure the total balance remains consistent.

Create Transfer

Move funds from a source wallet to a destination wallet.

POST /transfers

Request Headers

HeaderRequiredDescription
AuthorizationYesBearer token
Content-TypeYesapplication/json
Idempotency-KeyYesUnique request identifier

Request Body

FieldTypeRequiredDescription
from_wallet_idstringYesSource wallet ID
to_wallet_idstringYesDestination wallet ID
amountstringYesAmount to transfer (decimal string)
assetstringYesAsset type (e.g., POINTS, BONUS)
referencestringNoYour reference for this transaction
metadataobjectNoCustom key-value pairs
lot_selectionobjectNoConfigure which lots to draw from

Lot Selection Options

FieldTypeDefaultDescription
lot_selection.strategystringfifoSelection strategy: fifo, lifo, expiring_first, specific
lot_selection.lot_idsarray-Specific lot IDs (required when strategy is specific)

Example Request

curl -X POST {{BASE_URL}}/transfers \
  -H "Authorization: Bearer {{API_KEY}}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: {{IDEMPOTENCY_KEY}}" \
  -d '{
    "from_wallet_id": "wal_abc123def456",
    "to_wallet_id": "wal_def456ghi789",
    "amount": "100.00",
    "asset": "POINTS",
    "reference": "peer_transfer_001",
    "metadata": {
      "reason": "gift",
      "initiated_by": "user_12345"
    },
    "lot_selection": {
      "strategy": "expiring_first"
    }
  }'

Example Response

{
  "data": {
    "id": "txf_lmn123opq456",
    "from_wallet_id": "wal_abc123def456",
    "to_wallet_id": "wal_def456ghi789",
    "amount": "100.00",
    "asset": "POINTS",
    "reference": "peer_transfer_001",
    "status": "completed",
    "lot_movements": [
      {
        "from_lot_id": "lot_xyz789abc123",
        "to_lot_id": "lot_new456def789",
        "amount": "100.00"
      }
    ],
    "metadata": {
      "reason": "gift",
      "initiated_by": "user_12345"
    },
    "created_at": "2024-01-15T11:00:00Z"
  }
}

Error Codes

CodeDescription
WALLET_NOT_FOUNDSource or destination wallet does not exist
WALLET_SUSPENDEDCannot transfer from/to a suspended wallet
INSUFFICIENT_BALANCESource wallet has insufficient available funds
INVALID_AMOUNTAmount must be a positive decimal
INVALID_ASSETAsset type is not configured
SAME_WALLETCannot transfer to the same wallet
LOT_NOT_FOUNDSpecified lot does not exist (specific strategy)
LOT_INSUFFICIENT_BALANCESpecified lot has insufficient balance
POLICY_VIOLATIONTransfer violates wallet policies
RESTRICTION_VIOLATIONLot restrictions prevent this transfer

Transfer with Lot Attributes

When transferring, you can preserve or modify lot attributes for the destination.

POST /transfers

Additional Request Body Fields

FieldTypeRequiredDescription
destination_lotobjectNoConfiguration for destination lot
destination_lot.preserve_expirybooleanNoKeep original expiration (default: true)
destination_lot.preserve_attributesbooleanNoKeep original attributes (default: true)
destination_lot.expires_atstringNoOverride expiration (requires preserve_expiry: false)
destination_lot.attributesobjectNoOverride attributes (requires preserve_attributes: false)

Example Request

curl -X POST {{BASE_URL}}/transfers \
  -H "Authorization: Bearer {{API_KEY}}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: {{IDEMPOTENCY_KEY}}" \
  -d '{
    "from_wallet_id": "wal_abc123def456",
    "to_wallet_id": "wal_def456ghi789",
    "amount": "50.00",
    "asset": "POINTS",
    "reference": "conversion_001",
    "destination_lot": {
      "preserve_expiry": false,
      "preserve_attributes": false,
      "expires_at": "2025-12-31T23:59:59Z",
      "attributes": {
        "source": "conversion",
        "original_asset": "BONUS"
      }
    }
  }'

Transfer from Reservation

Convert a held reservation into a transfer to another wallet.

POST /transfers/from-reservation

Request Body

FieldTypeRequiredDescription
reservation_idstringYesReservation to convert
to_wallet_idstringYesDestination wallet ID
amountstringNoPartial amount (defaults to full reservation)
referencestringNoYour reference for this transaction
metadataobjectNoCustom key-value pairs

Example Request

curl -X POST {{BASE_URL}}/transfers/from-reservation \
  -H "Authorization: Bearer {{API_KEY}}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: {{IDEMPOTENCY_KEY}}" \
  -d '{
    "reservation_id": "rsv_abc123def456",
    "to_wallet_id": "wal_merchant_001",
    "reference": "order_completion_789"
  }'

Example Response

{
  "data": {
    "id": "txf_rst789uvw012",
    "from_wallet_id": "wal_abc123def456",
    "to_wallet_id": "wal_merchant_001",
    "amount": "75.00",
    "asset": "POINTS",
    "reference": "order_completion_789",
    "status": "completed",
    "reservation_id": "rsv_abc123def456",
    "reservation_status": "committed",
    "created_at": "2024-01-15T12:00:00Z"
  }
}

Error Codes

CodeDescription
RESERVATION_NOT_FOUNDReservation does not exist
RESERVATION_EXPIREDReservation has expired
RESERVATION_ALREADY_COMMITTEDReservation was already committed
RESERVATION_ALREADY_RELEASEDReservation was already released
AMOUNT_EXCEEDS_RESERVATIONRequested amount exceeds reservation

Get Transfer

Retrieve details of a specific transfer.

GET /transfers/{{TRANSFER_ID}}

Path Parameters

ParameterTypeDescription
transfer_idstringThe transfer ID (e.g., txf_lmn123opq456)

Example Request

curl -X GET {{BASE_URL}}/transfers/{{TRANSFER_ID}} \
  -H "Authorization: Bearer {{API_KEY}}"

Example Response

{
  "data": {
    "id": "txf_lmn123opq456",
    "from_wallet_id": "wal_abc123def456",
    "to_wallet_id": "wal_def456ghi789",
    "amount": "100.00",
    "asset": "POINTS",
    "reference": "peer_transfer_001",
    "status": "completed",
    "lot_movements": [
      {
        "from_lot_id": "lot_xyz789abc123",
        "to_lot_id": "lot_new456def789",
        "amount": "100.00"
      }
    ],
    "metadata": {
      "reason": "gift",
      "initiated_by": "user_12345"
    },
    "created_at": "2024-01-15T11:00:00Z"
  }
}

List Transfers

Retrieve a paginated list of transfers for a wallet.

GET /wallets/{{WALLET_ID}}/transfers

Path Parameters

ParameterTypeDescription
wallet_idstringThe wallet ID

Query Parameters

ParameterTypeDefaultDescription
limitinteger20Number of results (max 100)
cursorstring-Pagination cursor
directionstring-Filter by incoming or outgoing
assetstring-Filter by asset type
from_datestring-Filter transfers after this date (ISO 8601)
to_datestring-Filter transfers before this date (ISO 8601)

Example Request

curl -X GET "{{BASE_URL}}/wallets/{{WALLET_ID}}/transfers?direction=outgoing&limit=10" \
  -H "Authorization: Bearer {{API_KEY}}"

Example Response

{
  "data": [
    {
      "id": "txf_lmn123opq456",
      "from_wallet_id": "wal_abc123def456",
      "to_wallet_id": "wal_def456ghi789",
      "amount": "100.00",
      "asset": "POINTS",
      "reference": "peer_transfer_001",
      "status": "completed",
      "created_at": "2024-01-15T11:00:00Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  }
}