- Developers
- Ticket pricing and multi-level markup
Ticket pricing and multi-level markup
An order within the Ferry ecosystem carries three distinct price figures depending on the perspective: the operator base price, the partner NET rate payable to upstream organizations, and the retail price paid by the end customer. The margin between these figures compounds along each tier of the ticket distribution hierarchy.
Three price tiers in the system
Section titled “Three price tiers in the system”The diagram below shows the three pricing perspectives and their corresponding settlement parties for a single order:
flowchart LR O["Single ticket order"] O --> G1["Operator base price<br/>(all markups excluded)"] O --> G2["Partner NET rate<br/>(upstream markups included)"] O --> G3["Retail customer price<br/>(all markups included)"] G1 --> X1["Ferry pays operator"] G2 --> X2["You pay upstream partner"] G3 --> X3["Customer pays you"] X3 --> V1["Vouchers and discounts apply here"] G2 --> V2["No vouchers applied"] G1 --> V3["No vouchers applied"]These three figures represent three distinct commercial relationships:
- Operator base price: The baseline fare published by the ferry operator, free of any agency commissions or markups.
- Partner NET rate: The cost your organization must settle with your direct upstream parent. This amount accumulates markups from all ancestor organizations above you.
- Retail customer price: The total fare charged to the passenger, including applicable markups and discounts. The customer perspective uses a tax-inclusive price, while the agency perspective uses the tax-exclusive base price. The difference between retail and NET prices therefore does not represent your markup alone.
Multi-tier markup accumulation mechanism
Section titled “Multi-tier markup accumulation mechanism”The diagram below illustrates how price additions accumulate down the agency hierarchy:
flowchart TD R["Root organization"] -->|"Add root surcharge"| L1["Tier 1 agency"] L1 -->|"Add Tier 1 surcharge"| L2["Tier 2 agency"] L2 -->|"Add Tier 2 surcharge"| U["Your organization"] U -->|"Add your own surcharge"| F["Final retail price"] F --> V["Deduct voucher if valid"] R -.->|"Strip all surcharges"| N["Operator base price"] U -.->|"Excludes your surcharge"| M["Partner NET rate"]Compounding percentage accumulation: When an organization tier configures a surcharge as a percentage, that percentage is applied against the price that already incorporates surcharges from all preceding upstream tiers.
A crucial consequence for revenue reconciliation: the overall chain markup rate does not equal the simple arithmetic sum of the percentages. For instance, a three-tier agency chain where each tier adds 10% produces an effective compounded increase of 33.1%, not 30%. When deducted amounts differ from initial estimates, verify this compounding rule before investigating discounts or tax rules.
Pre-booking price verification sequence
Section titled “Pre-booking price verification sequence”The diagram below outlines the sequence of API calls used to validate pricing and discounts before booking:
sequenceDiagram participant P as "Your system" participant F as "Ferry API" participant C as "Pricing engine" P->>F: "Check additions for order context" F->>C: "Aggregate surcharges along org chain" C-->>F: "Retail price and partner NET rate" F-->>P: "Both price figures with margin" P->>F: "Check voucher applicability" alt Voucher is applicable F-->>P: "Valid code with discount amount" else Not applicable F-->>P: "Rejection reason, retain original price" end P->>F: "Create new booking" F-->>P: "Booking ID and recorded price"The table below summarizes the actions at each step:
| Step | Your system | Ferry API | Partner takeaway |
|---|---|---|---|
| 1 | Define specific order context | Compares context against configured surcharge rules | Provide exact voyage code, seat tier, and passenger count |
| 2 | Call addition check (POST /ticket-price-additions/check) | Calculates and returns NET rate alongside retail price | This check does not require special administrative privileges |
| 3 | Call voucher check (POST /vouchers/check-aplicability) | Returns applicability status and discount amount | Note the identifier spelling check-aplicability |
| 4 | Evaluate gross margin | Compares the gap between retail price and NET rate | Confirm margin covers operational processing costs |
| 5 | Create booking and confirm issuance | Records booking and recalculates prices upon issuance | Debited funds are finalized at the moment of ticket issuance |
Both addition and voucher checks require a valid API key but no special permission. Creating additions or vouchers requires the corresponding create permission. Check prices using the exact voyage, seat class, passenger count, and passenger type; an existing addition may not apply when its conditions do not match.
Pricing invariants and rules
Section titled “Pricing invariants and rules”-
Recalculation at issuance: Ferry re-evaluates all fare components at the exact moment ticket confirmation is executed rather than relying on search-time prices. Prices seen during search are advisory estimates.
-
Currency conventions: All monetary figures are integers in Vietnamese Dong (VND), without fractional units or separate currency fields.
-
Voucher check endpoint naming: The voucher validation endpoint uses the exact path
POST /vouchers/check-aplicability(with a single ‘p’). Typing standard English spelling results in an HTTP 404. -
Vouchers apply only to retail price: Applying a voucher reduces the passenger’s payable amount; it never reduces your NET settlement cost with your upstream parent.
-
No idempotency on addition or voucher creation: Retrying after a timeout can create a second record. List existing records and compare them with the submitted data; reuse a matching record and create again only when none is found. Duplicate additions can charge the customer twice.
-
The default perspective is the end customer: Without an explicit perspective, the returned price is for quoting to the customer, not for settling with your upstream parent.
-
Price figures available to partners: Booking retail total, booking NET total, original total before a ticket change, NET total of each order leg, and the order’s refunded NET amount. Do not assume all other price fields are exposed to API keys; report an expected missing field to Ferry rather than retrying.
-
Do not assume rounding rules: The order of applying additions, tax, and vouchers, and the rounding rules, have not been fully confirmed. Reconcile using Ferry’s returned figures; availability of
cost,profit, andrevenuealso requires confirmation from Ferry.
Common errors and remedies
Section titled “Common errors and remedies”| Symptom | Probable cause | Recommended action | Retry safe |
|---|---|---|---|
| Retail price equals partner NET rate | Your organization has not created its own addition rule | Configure an addition rule via the API or dashboard | No, configure addition first |
| Voucher check returns HTTP 404 | Typo in the endpoint path using standard spelling | Use the exact path check-aplicability | Yes, after fixing URL |
| Voucher reports not applicable | Order does not satisfy date, route, or seat tier criteria | Inspect the rejection reason in the response | No, inspect conditions |
| Debited amount differs from search price | System recalculated prices at confirmation time | Use the confirmation response price for final accounting | No, this is standard behavior |
| Surcharges duplicated after network timeout | Surcharge creation was retried without checking existing records | Delete duplicate addition and verify pricing | Do not retry blind creates |
Where to look on Scalar
Section titled “Where to look on Scalar”To inspect exact request schemas and test calls directly, open the Scalar UI under the relevant tags:
| Capability | Scalar tag |
|---|---|
| Configure and verify price additions | Ticket Price Additions |
| Manage and validate vouchers | Vouchers |
| Inspect price fields on bookings | Bookings |
| View NET rates on individual order legs | Orders |
For instructions on configuring your API key in Scalar, see API Reference.
Read next
Section titled “Read next”| Page | Related topic |
|---|---|
| Voyage search and remaining seats | Discovering voyages and base timetables |
| The booking flow | Complete booking lifecycle and payment moments |
| Payments and balances | Balance deduction mechanics and credit limits |
| Ticket issuance | Step-by-step electronic ticketing execution |
| General conventions | Currency formatting and timeout handling |