POST /api/v1/flights/pay_order
Pay a held order, issue tickets, and debit the agency balance. Requires Read+Write permission.
Pay for a held booking and issue the tickets. Charges the agency balance by pricing.b2bPrice.
Permission: Read+Write
The charge amount and currency are resolved server-side from the stored booking. Do not
send amount or currency — the endpoint rejects them.
Identifying the booking
| Field | Description |
|---|---|
order_id | Preferred. Supplier order ID returned when the hold was created. |
booking_id | FX-Port booking ID |
pnr | Airline record locator — not unique, prefer order_id |
payment_type | Optional. "balance" (default), "card", or "arc_bsp_cash" |
PNRs are not globally unique across suppliers/GDS/airlines. Prefer order_id to
unambiguously identify the booking you intend to pay for.
Payment cannot revive an expired hold. pay_order fails if the PNR has expired or was
cancelled, the payment deadline is in the past, or the airline released the hold early. Airlines
can expire a PNR before the expected date or time. Treat paymentSucceeded and
paymentDetails.status from this response as the source of truth; do not confirm the traveler or
charge them in your system until payment succeeds.
Request example
curl --request POST \
--url https://api.fx-port.com/api/v1/flights/pay_order \
--header 'Authorization: Bearer fxp_test_YOUR_KEY' \
--header 'Content-Type: application/json' \
--data '{
"order_id": "eJzTd9ePMo_0NXMEAAtYAlQ",
"payment_type": "balance"
}'Response example
Response for the same held Amadeus order used throughout Book and
Get order quote — same currency both sides (DZD), so there is no
top-level exchangeRate here.
{
"environment": "sandbox",
"success": true,
"paymentSucceeded": true,
"requestId": "debe80df",
"orderId": "eJzTd9ePMo_0NXMEAAtYAlQ",
"processingTime": 3.163,
"paymentDetails": {
"paymentId": null,
"status": "succeeded",
"type": "issuance",
"paymentAmount": 5081.44,
"currency": "DZD",
"createdAt": "2026-08-27T18:14:30.624429",
"message": "Payment successful! Tickets have been issued."
},
"booking": {
"reference": "eJzTd9ePMo_0NXMEAAtYAlQ",
"status": "confirmed",
"pnr": "Z7YM6A",
"type": "instant",
"createdAt": "2026-08-27T18:14:30.624429",
"cancelledAt": null,
"availableActions": [],
"voidableUntil": "2026-08-27T23:00:00Z"
},
"pricing": {
"supplierCurrency": "DZD",
"agencyCurrency": "DZD",
"basePrice": 3160.0,
"taxesAndFees": 1921.44,
"agencyCommission": 5.09,
"finalPrice": 5086.53,
"b2bPrice": 5081.44,
"additionalServices": [],
"acd": { "applied": false }
},
"payment": {
"status": "paid",
"paidAt": "2026-08-27T18:14:30.624549",
"awaitingPayment": false
},
"documents": [
{
"type": "electronic_ticket",
"documentType": "ETICKET",
"uniqueIdentifier": "124-2442997961",
"status": "ISSUED",
"passengerIds": ["1"],
"segmentIds": ["1"]
}
],
"bookingReferences": [
{
"pnr": "Z7YM6A",
"carrier": { "iataCode": "AH", "name": "Air Algerie" }
}
]
}Field meanings
| Field | Meaning |
|---|---|
paymentSucceeded | Top-level boolean — check this and paymentDetails.status before treating payment as final |
paymentDetails.status | "succeeded", "pending", or "failed" — the single source of truth for payment outcome |
paymentDetails.type | Internal payment classification, e.g. "issuance" for a hold being paid and ticketed |
paymentDetails.paymentAmount | Amount actually debited from agency balance = pricing.b2bPrice |
booking.status | Now "confirmed" (was "pending" while held) |
booking.voidableUntil | Same-day void cutoff, now populated now that the ticket is issued |
documents[n].uniqueIdentifier | The e-ticket number |
pricing.acd | Algerian Currency Declaration flag on Amadeus Algeria bookings — see Flight pricing |
paymentDetails.currency | The agency currency of the debit |
pricing.b2bPrice | Debit amount = finalPrice − agencyCommission |
Supplier cost and commission internals (net fare, kiosk/system commission) are never returned. Only agency-facing amounts are exposed.