Skip to content

Payments: balances, credit limits, and debt ledgers

9 min read

Within the Ferry ecosystem, integrating partners do not call any standalone payment endpoint. The entire payment deduction process executes automatically inside the booking confirmation step, evaluated recursively up the organization hierarchy from the agency to the root organization.

PrerequisiteBusiness contextReference
Valid API keyAll balance, ledger, and debt query endpoints require partner authenticationAuthentication with an API key
Organization hierarchy levelUnderstand your tier position to anticipate recursive credit checksIntegration surface overview
Upstream parent detailsObtain exact bank account details and transfer message syntaxSee top-up instructions below
Knowledge of partner NET rateDebited amounts correspond to your NET rate rather than retail customer pricesTicket pricing and multi-level markup
Currency format conventionsAmounts are integers in Vietnamese Dong (VND), without decimals or currency fieldsGeneral conventions

Deduction mechanics during ticket confirmation

Section titled “Deduction mechanics during ticket confirmation”

The diagram below illustrates the recursive balance validation and fund-holding sequence inside the confirmation step:

sequenceDiagram
autonumber
participant P as "Your system"
participant F as "Ferry API"
participant B as "Your organization balance"
participant U as "Upstream parent organization"
participant K as "Customer balance"
P->>F: "Confirm ticket issuance (confirmToIssue)"
F->>B: "Check available balance and credit limit"
alt Your organization has insufficient funds
B-->>F: "Insufficient balance"
F-->>P: "Organization balance error (top up to resolve)"
else Your organization has sufficient funds
B-->>F: "Sufficient funds"
F->>U: "Check credit limits recursively up the parent tree"
alt An upstream parent exhausts credit
U-->>F: "Upstream credit limit exhausted"
F-->>P: "Balance error (contact upstream parent or Ferry)"
else All ancestors have sufficient credit
U-->>F: "Credit confirmed up to root"
F->>K: "Check end-customer available balance"
alt Customer lacks funds and cannot incur debt
K-->>F: "Insufficient funds"
F-->>P: "Customer balance error"
else Customer has funds or credit authorized
K-->>F: "Valid"
F-->>P: "Funds locked successfully, proceeding to operator issuance"
end
end
end

Effective spending limits and recursive parent checks

Section titled “Effective spending limits and recursive parent checks”

An organization’s spending capacity is calculated as Available Balance + Credit Limit.

During ticket confirmation, the system recursively inspects every ancestor organization up to the root:

  • Each child tier creates a settlement obligation toward its parent equal to the NET rate at that tier’s vantage point.
  • Risk of upstream exhaustion: Your order can be rejected due to an upstream organization running out of credit, even if your own balance is fully funded. When this happens, topping up your own account will not resolve the issue; you must contact your upstream parent or Ferry operations to request a credit limit expansion.

Ferry also checks the end-customer wallet. Customer spending capacity is balance minus funds held for withdrawal requests. If funds are insufficient and debt is not allowed, the booking remains unchanged. If debt is allowed, the parent organization lends to the customer and payment status becomes paid by debt. Once the customer repays the debt in full, it automatically changes to paid, with no additional API call.

The diagram below traces the path of inbound funds from bank transfer to balance crediting:

flowchart TB
A["Bank transfer out-of-band<br/>using upstream parent instructions"] --> B["Ferry banking gateway detects transaction"]
B --> C["System automatically credits balance,<br/>no confirmation API call needed"]
C --> D["Partner available balance increases"]
D --> E["Ticket confirmation debits from this balance"]
E --> F["Transaction log and debt ledgers updated"]
F --> G["Partner queries ledger for periodic reconciliation"]

The table below summarizes the actions at each step:

StepYour systemFerry APIPartner takeaway
1Fetch upstream top-up instructionsReturns account numbers and reference syntaxAlways pull details via the API rather than reusing old emails
2Transfer funds out-of-bandBanking gateway detects the transactionInclude the exact transfer message syntax for auto-matching
3Query available balance and creditReturns live balance and remaining credit lineConfirm adequate funds prior to batch ticket issuance
4Confirm ticket issuanceDebits balance based on booking NET rateFunds are deducted leg by leg automatically
5Inspect transaction ledgerReturns list of financial ledger entriesMatch transaction codes against booking identifiers
6Track debt ledgersUpdates outstanding debt balances between tiersRelevant for agencies managing sub-partner networks

If upstream channel details are suspected of being compromised, organizations can invoke the security code refresh endpoint (Organizations). Upon refresh, old top-up channel credentials become invalid immediately.

Partners do not handle bank payment notifications; banks send them directly to Ferry. The partner API also has no direct refund operation: refunds follow the cancellation and refund flow.

The system records all financial movements in the transaction ledger using standardized codes:

CodeTypeTrigger event
PBBooking paymentSuccessfully confirmed booking ticket issuance
POOrder leg paymentGenerated alongside PB at the individual leg level
DPCustomer depositFunds deposited into an end-customer wallet
ODAgency depositInbound bank transfer credited to partner account
SOOperator syncInternal settlement reconciliation with the ferry operator
BLInformational entryZero-value checkpoint entry recording milestones
UKUnknown transactionFunds received but beneficiary entity not yet matched
CBCredit borrowingBooking issued under an authorized customer debt arrangement
CRCredit repaymentCustomer settles outstanding debt
CHChargeback / reversalTechnical payment failure reversal
RFCancellation refundCancellation request approved all the way to the root organization
DRDebt reconciliationNetting of inter-organization debt balances
RTTop-up reversalCancellation or reversal of a deposit entry
WDWallet withdrawalEnd-customer withdraws funds from wallet
MAManual adjustmentFerry operations manually adjusts balance with audit trail

Each transaction holds three critical reconciliation attributes:

  • Status: Succeeded, failed, or cancelled. Only sum transactions marked as Succeeded when computing balances.
  • Direction: Inflow (credit) or outflow (debit); read the direction attribute rather than inferring it from the amount’s sign.
  • Subject: Customer, booking, order leg, operator, organization, or unknown.

If you encounter entries with code UK (unknown), call the transaction categorization API to associate the funds with the correct booking or account, avoiding accounting discrepancies.

Key timing constraints and in-flight transaction behaviors:

  • Issuance lock (600 seconds): Retrying confirmation while issuance is ongoing yields a processing error; wait for completion and query booking details.
  • Payment lock (180 seconds): Retrying while payment deduction is active triggers a 180-second payment lock requiring a wait before retry.
  • Partial issuance failure: For multi-leg bookings, if one leg succeeds and a subsequent leg fails, Ferry refunds the failed leg while keeping funds for the confirmed leg (booking lacks a ticket but balance is partially debited).
  • Paid bookings awaiting tickets: Background reconciliation jobs reconcile with the operator after several minutes without requiring partner intervention.
  • Refund settlement cycle (15 minutes): Sub-partner cancellation refunds run on a 15-minute background cycle, reclaiming stuck records after 10 minutes. Credits may arrive up to 15 minutes later, sometimes longer; this is not a guaranteed refund deadline.
  • Balance is the source of truth: Account balance is the primary source of truth; transaction logs are reference records. Temporary discrepancies occur while background jobs run; discrepancies exceeding 15 minutes warrant investigation.

During integration, you may encounter three distinct balance-related error responses:

  1. Booking balance insufficient: Your account or an upstream parent lacks the funds required to cover the booking NET rate.
  2. Customer balance insufficient: The end-customer’s wallet has insufficient funds and is not permitted to incur debt.
  3. Cancellation fee balance insufficient: Account balance is insufficient to cover standard ticket cancellation processing fees.

None of these errors can be resolved by blindly retrying the call. You must identify which entity is deficient and ensure funds are deposited before proceeding.

Classify errors by code, not only by message: 120205 concerns booking balance, 130205 customer balance, and 160105 the balance required to create a cancellation request. Ticket issuance also uses 120120 for organization balance and 120101 for customer balance. See Errors and how to handle them before deciding whether to retry.

SymptomProbable causeRecommended actionRetry safe
Balance error right after bank transferTransfer still in transit or reference syntax was incorrectCheck transaction ledger; verify transfer reference stringAwait bank settlement
Balance error despite healthy account fundsAn upstream ancestor in the chain has exhausted its credit limitContact upstream partner or Ferry to increase credit lineDo not retry
Customer balance insufficient errorEnd-customer wallet lacks funds and debt is disabledTop up customer wallet or enable debt allowance if allowedDo not retry
Ledger entry shows Unknown (UK) codeReceived funds could not be automatically matched to an entityUse transaction classification API to assign the entryYes, after classification
Refunded funds not yet showing in balanceBackground refund settlement jobs run on a 15-minute cycleWait for the 15-minute cycle to complete before queryingDo not retry rapidly
Balance and ledger temporarily out of syncBackground reconciliation worker running in-flightRe-query after one 15-minute cycleYes, after waiting
Partial issuance failure, balance debitedOne leg confirmed, subsequent leg rejectedInspect leg-by-leg order details and contact FerryDo not recreate booking

To inspect exact request schemas and test calls directly, open the Scalar UI under the relevant tags:

CapabilityScalar tag
Query transaction ledger, filter by type and entityTransactions
Assign entity to unknown transactionsTransactions
Track inter-organization debt ledgersDebt Ledgers
View upstream top-up account detailsOrganizations
Query organization credit limit and balanceOrganizations
Refresh top-up channel security credentialsOrganizations

Note that there is no “Payments” tag for the partner tier on Scalar, as all payment processing is handled automatically within the Bookings group.

For instructions on configuring your API key in Scalar, see API Reference.

PageRelated topic
The booking flowOrder lifecycle and fund deduction timing
Ticket issuanceDetailed sequence of payment verification and issuance
Ticket pricing and multi-level markupNET rate calculations and margin distribution
Cancellation and refundRefund workflows and settlement timing
General conventionsCurrency conventions and ledger pagination rules
QuestionStatus
Upstream credit limit exhaustion alerts for multi-tier partnersNo automated alert is triggered when an upstream parent nears credit exhaustion; contact operations upon error.
Bank transfer crediting durationGoverned by banking gateways and external settlement times; no hard SLA is defined in the API.
Automatic processing of unknown transactions (UK)Automatic processing time is undetermined; for now, partners must assign these entries manually through the API.