Skip to main content
Inflight transactions allow you to reserve funds temporarily without immediately deducting them from the available balance. This is essential for authorization holds, pre-orders, and pending payments.

How inflight transactions work

When you create an inflight transaction:
  1. Funds are moved from balance to inflight_balance
  2. The money is held but not permanently deducted
  3. You can later commit the hold to complete the transaction
  4. Or void the hold to release the funds back

Creating an inflight transaction

Create a transaction with the inflight flag set to true:
1

Record inflight transaction

POST /transactions
{
  "amount": 100.00,
  "precision": 100,
  "reference": "auth_hold_payment_001",
  "currency": "USD",
  "source": "bln_customer_wallet",
  "destination": "bln_merchant_wallet",
  "description": "Payment authorization hold",
  "inflight": true,
  "meta_data": {
    "order_id": "order_12345",
    "payment_method": "credit_card"
  }
}
2

Response

{
  "transaction_id": "txn_abc123xyz",
  "amount": 100.00,
  "precise_amount": "10000",
  "reference": "auth_hold_payment_001",
  "currency": "USD",
  "source": "bln_customer_wallet",
  "destination": "bln_merchant_wallet",
  "status": "INFLIGHT",
  "inflight": true,
  "created_at": "2024-01-15T10:30:00Z"
}
The transaction status is INFLIGHT, indicating the funds are on hold.
3

Check balance impact

GET /balances/bln_customer_wallet
{
  "balance_id": "bln_customer_wallet",
  "balance": "40000",
  "inflight_balance": "10000",
  "inflight_debit_balance": "10000",
  "credit_balance": "50000",
  "debit_balance": "0"
}
Notice:
  • balance decreased by $100 (available funds)
  • inflight_balance increased by $100 (held funds)
  • Total is still conserved: balance + inflight = credit - debit

Committing an inflight transaction

Commit the hold to permanently transfer the funds:
1

Commit the transaction

POST /transactions/txn_abc123xyz/inflight
{
  "status": "commit"
}
You can commit the full amount or a partial amount. See partial commits below.
2

Response

{
  "transaction_id": "txn_commit_abc123xyz",
  "parent_transaction": "txn_abc123xyz",
  "amount": 100.00,
  "precise_amount": "10000",
  "status": "APPLIED",
  "created_at": "2024-01-15T11:00:00Z"
}
3

Final balance state

{
  "balance_id": "bln_customer_wallet",
  "balance": "40000",
  "inflight_balance": "0",
  "credit_balance": "50000",
  "debit_balance": "10000"
}
After commit:
  • inflight_balance is cleared
  • debit_balance increased by $100 (permanent deduction)
  • balance remains at $400 (available funds)

Voiding an inflight transaction

Void the hold to release the funds back to the balance:
1

Void the transaction

POST /transactions/txn_abc123xyz/inflight
{
  "status": "void"
}
2

Response

{
  "transaction_id": "txn_void_abc123xyz",
  "parent_transaction": "txn_abc123xyz",
  "amount": 100.00,
  "precise_amount": "10000",
  "status": "VOID",
  "created_at": "2024-01-15T11:15:00Z"
}
3

Balance after void

{
  "balance_id": "bln_customer_wallet",
  "balance": "50000",
  "inflight_balance": "0",
  "credit_balance": "50000",
  "debit_balance": "0"
}
The funds are released back:
  • balance increases to $500 (funds restored)
  • inflight_balance is cleared

Partial commits

Commit only a portion of the held amount:
POST /transactions/txn_abc123xyz/inflight
{
  "status": "commit",
  "amount": 75.00
}
This commits 75andreleasestheremaining75 and releases the remaining 25 back to the balance.
You can only commit up to the original inflight amount. Attempting to commit more will result in an error.

Common use cases

Payment authorization

// Step 1: Hold funds when customer initiates checkout
POST /transactions
{
  "amount": 150.00,
  "precision": 100,
  "reference": "payment_auth_order_789",
  "currency": "USD",
  "source": "bln_customer_wallet",
  "destination": "bln_merchant_wallet",
  "description": "Order #789 payment authorization",
  "inflight": true,
  "meta_data": {
    "order_id": "789",
    "cart_items": ["item1", "item2"]
  }
}

// Step 2: Commit when order is confirmed
POST /transactions/txn_xyz/inflight
{
  "status": "commit"
}

// Or void if order is cancelled
POST /transactions/txn_xyz/inflight
{
  "status": "void"
}

Hotel booking deposit

// Hold deposit amount
POST /transactions
{
  "amount": 200.00,
  "precision": 100,
  "reference": "hotel_deposit_booking_456",
  "currency": "USD",
  "source": "bln_guest_wallet",
  "destination": "bln_hotel_wallet",
  "description": "Hotel booking deposit",
  "inflight": true,
  "inflight_expiry_date": "2024-03-15T15:00:00Z",
  "meta_data": {
    "booking_id": "456",
    "check_in": "2024-03-01",
    "check_out": "2024-03-05"
  }
}

// Commit actual charges after checkout
POST /transactions/txn_hotel/inflight
{
  "status": "commit",
  "amount": 180.00
}
This commits 180fortheactualstayandreleasestheremaining180 for the actual stay and releases the remaining 20.

Escrow service

// Buyer pays into escrow (inflight)
POST /transactions
{
  "amount": 500.00,
  "precision": 100,
  "reference": "escrow_sale_contract_999",
  "currency": "USD",
  "source": "bln_buyer_wallet",
  "destination": "bln_seller_wallet",
  "description": "Escrow for service contract",
  "inflight": true,
  "meta_data": {
    "contract_id": "999",
    "service": "web_development"
  }
}

// Release to seller when work is approved
POST /transactions/txn_escrow/inflight
{
  "status": "commit"
}

// Or refund to buyer if work is rejected
POST /transactions/txn_escrow/inflight
{
  "status": "void"
}

Setting expiry dates

Automatically void holds after a certain time:
POST /transactions
{
  "amount": 100.00,
  "precision": 100,
  "reference": "temp_hold_001",
  "currency": "USD",
  "source": "bln_customer_wallet",
  "destination": "bln_merchant_wallet",
  "inflight": true,
  "inflight_expiry_date": "2024-01-20T23:59:59Z",
  "description": "Hold expires in 5 days"
}
If not committed before the expiry date, Blnk will automatically void the transaction and release the funds.

Handling errors

Cannot commit already committed transaction

{
  "error": "cannot commit. Transaction already committed"
}

Commit amount exceeds inflight amount

{
  "error": "commit amount exceeds remaining inflight amount"
}

Transaction not in inflight status

{
  "error": "transaction is not in inflight status"
}

Best practices

Set expiry dates

Always set inflight_expiry_date to prevent funds from being held indefinitely.

Track parent transactions

Store the parent transaction ID to track commit/void operations.

Handle partial commits

Support partial commits for scenarios like tips, taxes, or adjusted final amounts.

Monitor inflight balances

Track inflight_balance in your dashboards to monitor held funds.

Implementation code (from transaction.go:1069-1120)

The inflight commit logic in Blnk:
func (l *Blnk) CommitInflightTransaction(ctx context.Context, transactionID string, amount *big.Int) (*model.Transaction, error) {
    // Acquire lock for the transaction
    lockKey := fmt.Sprintf("inflight-commit:%s", transactionID)
    locker := redlock.NewLocker(l.redis, lockKey, model.GenerateUUIDWithSuffix("loc"))
    
    err := locker.Lock(ctx, l.Config().Transaction.LockDuration)
    if err != nil {
        return nil, fmt.Errorf("failed to acquire lock: %w", err)
    }
    defer l.releaseSingleLock(ctx, locker)
    
    // Fetch and validate the inflight transaction
    transaction, err := l.fetchAndValidateInflightTransaction(ctx, transactionID)
    if err != nil {
        return nil, err
    }
    
    // Validate and update amount
    if err := l.validateAndUpdateAmount(ctx, transaction, amount); err != nil {
        return nil, err
    }
    
    // Finalize the commitment
    return l.finalizeCommitment(ctx, transaction, false)
}

Next steps

Balance Monitoring

Set up alerts for inflight balance thresholds

Webhooks

Receive notifications for inflight status changes

Build docs developers (and LLMs) love