Skip to main content
The Manual Wallet Debit feature allows you to manually deduct credits from a customer’s wallet. This is essential for handling refunds, billing corrections, chargebacks, and other administrative adjustments. Common Use Cases:
  • Refunds: Process customer refunds for overcharges or billing errors
  • Billing Adjustments: Correct incorrect credit allocations
  • Chargebacks: Handle payment disputes and chargebacks
  • Administrative Corrections: Fix manual entry errors or system issues
To close a wallet, terminate it instead (Terminate wallet in the wallet’s ⋯ menu, or POST /wallets/{id}/terminate). Termination debits the remaining balance for you.

How Manual Debit Works

When you debit a wallet, Flexprice automatically:
  1. Validates the Request: Checks that the credits are positive and the wallet is active
  2. Consumes Credits: Deducts credits using a priority-based algorithm (see below)
  3. Updates Balance: Reduces the wallet balance by the debited amount, even below zero (see Debits Larger Than the Balance)
  4. Creates Transaction Record: Maintains a complete audit trail
  5. Triggers Alerts: Checks the wallet’s low balance alert and auto top-up against the new balance

Credit Consumption Algorithm

Flexprice uses a smart Priority-Based FIFO algorithm to determine which credits to consume when processing a debit:

Consumption Order

Credits are consumed in the following order:
  1. Priority (Lower number = Higher priority)
    • Credits with priority 1 are consumed before priority 2
    • Credits without priority are consumed last
  2. Expiry Date (Earlier expiry first)
    • Credits expiring sooner are consumed first to prevent waste
    • Credits without expiry dates are consumed last
  3. Credit Amount (Larger amounts first)
    • Among credits with the same priority and expiry, larger amounts are consumed first
    • This optimizes the number of transaction updates required

Example Scenario

Suppose a wallet has the following credits: If you debit 150 credits, they will be consumed in this order:
  1. 50 credits from priority 1, expiring 2024-03-01
  2. 30 credits from priority 1, expiring 2024-03-01
  3. 70 credits from priority 1, expiring 2024-03-15 (partial)
The wallet will have 30 credits remaining from the third transaction, plus the untouched 75 and 200 credits.

Making a Manual Debit via Dashboard

You can debit credits from a customer’s wallet through the Flexprice dashboard:
1

Navigate to the wallet

Go to Customers, open the customer whose wallet you want to debit, and select the Wallet tab.
2

Open Debit wallet

Click Debit wallet next to Top up wallet.
Wallet tab with the Debit wallet button
3

Enter the debit details

  • Credits: the number of credits to remove from the wallet
  • Note (optional): why the credits are being removed
Click Debit to process the debit.
Debit wallet dialog with the credits to remove and a note
4

Verify the transaction

The wallet balance drops by the debited credits. The debit doesn’t get a row of its own in the wallet’s table of top-ups: expand a top-up it drew credits from to see it as a negative line, labelled with your note (or Manual debit when the note is empty or looks like an ID).
The dialog has no reference field: the dashboard generates an idempotency key each time you open Debit wallet, so clicking Debit again after an error doesn’t debit the wallet twice. That key belongs to the dialog alone, so if a retry shows “A wallet transaction with this idempotency key already exists”, the earlier attempt went through. To debit from your own systems, use the API and send your own idempotency_key, such as the ID of the refund or ticket the debit is for.

Making a Manual Debit via API

Endpoint

Request Parameters

Transaction Reasons

Use appropriate transaction reason codes to categorize debits:

Example Request

Success Response

The response is the updated wallet. It also includes auto_topup and alert_settings when the wallet has them configured.

Error Responses

A debit larger than the wallet’s balance is not an error. See Debits Larger Than the Balance.

Example Error Response

The details repeat the debit you sent, not the transaction that already holds the key.

Idempotency

The idempotency_key parameter is required and ensures that duplicate API requests (e.g., due to network timeouts) don’t result in multiple debits. If a key has already been used, Flexprice rejects the request with 409 already_exists and debits nothing. Keys are unique across all wallet transactions in the environment, not per wallet, so the key may belong to an earlier attempt of this debit, or to a top-up or a transaction on another wallet. A 409 alone doesn’t tell you which. To find the transaction that holds the key, search wallet transactions by idempotency_key:
Treat the debit as done only if the match is a debit on the same wallet_id for the same credit_amount. Otherwise the key belongs to another transaction: send the debit again with a new key.

Best Practices for Idempotency Keys

  • Use a unique identifier for each logical debit operation
  • Include context in the key, e.g., refund_invoice_123_20240115
  • Never reuse idempotency keys across different operations

Use Case Examples

Example: Administrative Correction

Important Considerations

Debits Larger Than the Balance

A manual debit isn’t limited to the wallet’s balance:
  • Flexprice consumes every available, unexpired credit, in the order described above
  • The part of the debit that no credit covers still counts, so the wallet’s credit balance goes below zero
  • The API returns success, not an error
  • The next top-up covers the negative amount first, so only the rest of its credits become available
Check the balance before a large debit if the wallet shouldn’t go negative.

Transaction Atomicity

All debit operations are atomic:
  • Credits are consumed and wallet balance is updated in a single database transaction
  • If any step fails, all changes are rolled back
  • This ensures data consistency and prevents partial debits

Audit Trail

Every manual debit creates a complete audit trail:
  • Transaction record with type debit
  • Before and after balances
  • Description and metadata
  • Transaction reason
  • Idempotency key for tracking
  • Timestamp and user information

Alert Integration

After a debit, Flexprice automatically:
  • Checks the wallet’s low balance alert against the new balance
  • Sends a webhook if the alert state changes
  • Tops up the wallet if auto top-up is on and the balance is at or below its threshold

Best Practices

💡 Always Use Idempotency Keys: Protect against duplicate debits by using unique idempotency keys for each operation 💡 Provide Clear Descriptions: Include descriptive text and metadata to make audit trails meaningful 💡 Choose Appropriate Reasons: Use the correct transaction reason code to categorize debits properly 💡 Check the Balance First: A manual debit larger than the balance still goes through and leaves the wallet below zero 💡 Handle Errors Gracefully: Don’t treat a 409 already_exists as proof that the debit went through. Find the transaction that holds the key first (see Idempotency) 💡 Monitor Alert Notifications: Watch for low balance alerts after processing debits

Troubleshooting

Negative Balance After a Debit

Problem: The wallet balance is below zero after a manual debit Solution:
  • Manual debits aren’t limited to the balance: the debit used every available credit and recorded the rest as a negative balance
  • Check the wallet’s balance before debiting
  • Top up the wallet to bring the balance back up

Duplicate Idempotency Key Error

Problem: API returns 409 already_exists with “A wallet transaction with this idempotency key already exists” Solution:
  • Find the transaction that holds the key by searching wallet transactions by idempotency_key (see Idempotency)
  • If it’s a debit on the same wallet for the same credits, your earlier request went through, so don’t send it again
  • If it’s a top-up or a transaction on another wallet, the key is already taken: send the debit again with a new key
  • Generate a new idempotency key for each distinct debit

Wallet Not Active Error

Problem: API returns 400 invalid_operation with “Wallet is not active” Solution:
  • The wallet was terminated, so its wallet_status is closed
  • Termination already debited the remaining balance, and a closed wallet can’t be reopened