Payments and allocation
Payments, refunds and their allocation to order lines, with balances at group, trip, purchase order and passenger level.
| Operation | Endpoint |
|---|---|
| Read a balance | GET /oms-ops/balances/{level}/{ref} |
| Read a balance by passenger | GET /oms-ops/balances/{level}/{ref}/passengers |
| List payments at a scope | GET /oms-ops/balances/{level}/{ref}/payments |
| Re-run allocation at a scope | POST /oms-ops/balances/{level}/{ref}/reallocate |
| Record a payment or a refund | POST /oms-ops/payments |
| Read a payment and its allocation | GET /oms-ops/payments/{paymentId} |
| Read a payment's allocation by passenger | GET /oms-ops/payments/{paymentId}/passengers |
Read a balance
/oms-ops/balances/{level}/{ref}Who paid how much for what, at group, trip or purchase order level.
Parameters
| Name | In | Required | Notes |
|---|---|---|---|
level | path | yes | one of group, trip, purchase_order |
ref | path | yes |
Response 200
/oms-ops/balances/trip/TRP-B2BD5A9771E4Read the trip balancecurl -X GET "$BASE/oms-ops/balances/trip/TRP-B2BD5A9771E4" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Request-Id: req-0009"
HTTP/1.1 200
X-Request-Id: req-0009
{
"scope": {
"level": "trip",
"ref": "TRP-B2BD5A9771E4"
},
"currency": "EUR",
"amountMinor": 293500,
"paidMinor": 78460,
"openMinor": 215040,
"unallocatedMinor": 0,
"status": "partially_paid",
"purchaseOrders": [
{
"poId": "PO-5BEE8AAD2A57",
"amountMinor": 268800,
"paidMinor": 53760,
"status": "partially_paid"
},
{
"poId": "PO-71B4D4926EDD",
"amountMinor": 24700,
"paidMinor": 24700,
"status": "paid"
}
],
"trips": [
{
"tripId": "TRP-B2BD5A9771E4",
"amountMinor": 293500,
"paidMinor": 78460,
"status": "partially_paid"
}
],
"lines": [
{
"lineId": "L-BB4F731FB7C8",
"tripId": "TRP-B2BD5A9771E4",
"poId": "PO-5BEE8AAD2A57",
"productKind": "beverage",
"amountMinor": 30800,
"paidMinor": 0,
"openMinor": 30800,
"status": "unpaid",
"byPayer": [],
"byPayment": []
},
{
"lineId": "L-A610167BDD4D",
"tripId": "TRP-B2BD5A9771E4",
"poId": "PO-5BEE8AAD2A57",
"productKind": "cruise",
"amountMinor": 238000,
"paidMinor": 53760,
"openMinor": 184240,
"status": "partially_paid",
"byPayer": [
{
"payerRef": "CUST-20419",
"payerRole": "booker",
"paidMinor": 53760
}
],
"byPayment": [
{
"paymentId": "pay_6ac1a14d-7a36-4c41-b7bc-db35708558e0",
"paidMinor": 53760
}
]
},
{
"lineId": "L-FDAF4DA2CF1A",
"tripId": "TRP-B2BD5A9771E4",
"poId": "PO-71B4D4926EDD",
"productKind": "excursion",
"amountMinor": 17800,
"paidMinor": 17800,
"openMinor": 0,
"status": "paid",
"byPayer": [
{
"payerRef": "CUST-20419",
"payerRole": "booker",
"paidMinor": 17800
}
],
"byPayment": [
{
"paymentId": "pay_f64cf55a-93e1-4f1e-bdbd-2f1ae6d5ee6b",
"paidMinor": 17800
}
]
},
{
"lineId": "L-93A9D925FCE1",
"tripId": "TRP-B2BD5A9771E4",
"poId": "PO-71B4D4926EDD",
"productKind": "excursion",
"amountMinor": 6900,
"paidMinor": 6900,
"openMinor": 0,
"status": "paid",
"byPayer": [
{
"payerRef": "CUST-20419",
"payerRole": "booker",
"paidMinor": 6900
}
],
"byPayment": [
{
"paymentId": "pay_f64cf55a-93e1-4f1e-bdbd-2f1ae6d5ee6b",
"paidMinor": 6900
}
]
}
]
}
/oms-ops/balances/trip/TRP-B2BD5A9771E4Read the balance after the change and refundscurl -X GET "$BASE/oms-ops/balances/trip/TRP-B2BD5A9771E4" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Request-Id: req-0016"
HTTP/1.1 200
X-Request-Id: req-0016
{
"scope": {
"level": "trip",
"ref": "TRP-B2BD5A9771E4"
},
"currency": "EUR",
"amountMinor": 268800,
"paidMinor": 48760,
"openMinor": 220040,
"unallocatedMinor": 0,
"status": "partially_paid",
"purchaseOrders": [
{
"poId": "PO-5BEE8AAD2A57",
"amountMinor": 268800,
"paidMinor": 48760,
"status": "partially_paid"
},
{
"poId": "PO-71B4D4926EDD",
"amountMinor": 0,
"paidMinor": 0,
"status": "no_charge"
}
],
"trips": [
{
"tripId": "TRP-B2BD5A9771E4",
"amountMinor": 268800,
"paidMinor": 48760,
"status": "partially_paid"
}
],
"lines": [
{
"lineId": "L-BB4F731FB7C8",
"tripId": "TRP-B2BD5A9771E4",
"poId": "PO-5BEE8AAD2A57",
"productKind": "beverage",
"amountMinor": 30800,
"paidMinor": 0,
"openMinor": 30800,
"status": "unpaid",
"byPayer": [],
"byPayment": []
},
{
"lineId": "L-A610167BDD4D",
"tripId": "TRP-B2BD5A9771E4",
"poId": "PO-5BEE8AAD2A57",
"productKind": "cruise",
"amountMinor": 238000,
"paidMinor": 48760,
"openMinor": 189240,
"status": "partially_paid",
"byPayer": [
{
"payerRef": "CUST-20419",
"payerRole": "booker",
"paidMinor": 48760
}
],
"byPayment": [
{
"paymentId": "pay_6ac1a14d-7a36-4c41-b7bc-db35708558e0",
"paidMinor": 48760
}
]
},
{
"lineId": "L-FDAF4DA2CF1A",
"tripId": "TRP-B2BD5A9771E4",
"poId": "PO-71B4D4926EDD",
"productKind": "excursion",
"amountMinor": 0,
"paidMinor": 0,
"openMinor": 0,
"status": "no_charge",
"byPayer": [],
"byPayment": []
},
{
"lineId": "L-93A9D925FCE1",
"tripId": "TRP-B2BD5A9771E4",
"poId": "PO-71B4D4926EDD",
"productKind": "excursion",
"amountMinor": 0,
"paidMinor": 0,
"openMinor": 0,
"status": "no_charge",
"byPayer": [],
"byPayment": []
}
]
}
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request failed validation. The message names the first failing field; oms-ops and group surfaces also return every issue in details. |
| 401 | unauthenticated | The bearer token is missing, invalid, expired or minted for another purpose. |
| 403 | scope_forbidden | The token is scoped to an agency or an access scope; this surface requires an unscoped tenant token. |
| 404 | oms_ops_not_enabled | Order operations are not enabled for the tenant. |
| 500 | internal | Unexpected failure. Retry with the same Idempotency-Key. |
Read a balance by passenger
/oms-ops/balances/{level}/{ref}/passengersThe balance split to passenger units, with the fee and refund each passenger would get if cancelled as of asOf.
Parameters
| Name | In | Required | Notes |
|---|---|---|---|
level | path | yes | one of group, trip, purchase_order |
ref | path | yes | |
asOf | query | The date cancellation tiers are read at. Default now. |
Response 200
/oms-ops/balances/trip/TRP-B2BD5A9771E4/passengersRead the balance split by passengercurl -X GET "$BASE/oms-ops/balances/trip/TRP-B2BD5A9771E4/passengers?asOf=2026-11-02T10%3A00%3A00Z" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Request-Id: req-0010"
HTTP/1.1 200
X-Request-Id: req-0010
{
"scope": {
"level": "trip",
"ref": "TRP-B2BD5A9771E4"
},
"currency": "EUR",
"amountMinor": 293500,
"paidMinor": 78460,
"openMinor": 215040,
"purchaseOrders": [
{
"poId": "PO-5BEE8AAD2A57",
"tripId": "TRP-B2BD5A9771E4",
"sequence": 1,
"amountMinor": 268800,
"paidMinor": 53760,
"openMinor": 215040,
"lines": [
{
"lineId": "L-BB4F731FB7C8",
"productKind": "beverage",
"status": "booked",
"quoteLineRef": "q-line-2",
"categoryRef": null,
"policy": {
"id": "refundable",
"label": "Refundable before departure",
"source": "product_kind",
"tier": {
"minDaysBefore": 0,
"feePercent": 0,
"feeMinorPerPassenger": 0
}
},
"amountMinor": 30800,
"paidMinor": 0,
"openMinor": 30800,
"units": [
{
"lineId": "L-BB4F731FB7C8",
"poId": "PO-5BEE8AAD2A57",
"tripId": "TRP-B2BD5A9771E4",
"productKind": "beverage",
"passengerRef": "PAX-01",
"passengerName": null,
"amountMinor": 15400,
"paidMinor": 0,
"openMinor": 15400,
"cancelled": false
},
{
"lineId": "L-BB4F731FB7C8",
"poId": "PO-5BEE8AAD2A57",
"tripId": "TRP-B2BD5A9771E4",
"productKind": "beverage",
"passengerRef": "PAX-02",
"passengerName": null,
"amountMinor": 15400,
"paidMinor": 0,
"openMinor": 15400,
"cancelled": false
}
]
},
{
"lineId": "L-A610167BDD4D",
"productKind": "cruise",
"status": "booked",
"quoteLineRef": "q-line-1",
"categoryRef": "BALCONY-B2",
"policy": {
"id": "cruise-fare",
"label": "Cruise fare",
"source": "default",
"tier": {
"minDaysBefore": 90,
"feePercent": 10,
"feeMinorPerPassenger": 0
}
},
"amountMinor": 238000,
"paidMinor": 53760,
"openMinor": 184240,
"units": [
{
"lineId": "L-A610167BDD4D",
"poId": "PO-5BEE8AAD2A57",
"tripId": "TRP-B2BD5A9771E4",
"productKind": "cruise",
"passengerRef": "PAX-01",
"passengerName": null,
"amountMinor": 119000,
"paidMinor": 26880,
"openMinor": 92120,
"cancelled": false
},
{
"lineId": "L-A610167BDD4D",
"poId": "PO-5BEE8AAD2A57",
"tripId": "TRP-B2BD5A9771E4",
"productKind": "cruise",
"passengerRef": "PAX-02",
"passengerName": null,
"amountMinor": 119000,
"paidMinor": 26880,
"openMinor": 92120,
"cancelled": false
}
]
}
]
},
{
"poId": "PO-71B4D4926EDD",
"tripId": "TRP-B2BD5A9771E4",
"sequence": 2,
"amountMinor": 24700,
"paidMinor": 24700,
"openMinor": 0,
"lines": [
{
"lineId": "L-FDAF4DA2CF1A",
"productKind": "excursion",
"status": "booked",
"quoteLineRef": null,
"categoryRef": null,
"policy": {
"id": "refundable",
"label": "Refundable before departure",
"source": "product_kind",
"tier": {
"minDaysBefore": 0,
"feePercent": 0,
"feeMinorPerPassenger": 0
}
},
"amountMinor": 17800,
"paidMinor": 17800,
"openMinor": 0,
"units": [
{
"lineId": "L-FDAF4DA2CF1A",
"poId": "PO-71B4D4926EDD",
"tripId": "TRP-B2BD5A9771E4",
"productKind": "excursion",
"passengerRef": "PAX-01",
"passengerName": null,
"amountMinor": 8900,
"paidMinor": 8900,
"openMinor": 0,
"cancelled": false
},
{
"lineId": "L-FDAF4DA2CF1A",
"poId": "PO-71B4D4926EDD",
"tripId": "TRP-B2BD5A9771E4",
"productKind": "excursion",
"passengerRef": "PAX-02",
"passengerName": null,
"amountMinor": 8900,
"paidMinor": 8900,
"openMinor": 0,
"cancelled": false
}
]
},
{
"lineId": "L-93A9D925FCE1",
"productKind": "excursion",
"status": "booked",
"quoteLineRef": null,
"categoryRef": null,
"policy": {
"id": "refundable",
"label": "Refundable before departure",
"source": "product_kind",
"tier": {
"minDaysBefore": 0,
"feePercent": 0,
"feeMinorPerPassenger": 0
}
},
"amountMinor": 6900,
"paidMinor": 6900,
"openMinor": 0,
"units": [
{
"lineId": "L-93A9D925FCE1",
"poId": "PO-71B4D4926EDD",
"tripId": "TRP-B2BD5A9771E4",
"productKind": "excursion",
"passengerRef": "PAX-02",
"passengerName": null,
"amountMinor": 6900,
"paidMinor": 6900,
"openMinor": 0,
"cancelled": false
}
]
}
]
}
],
"passengers": [
{
"passengerRef": "PAX-01",
"passengerName": null,
"tripId": "TRP-B2BD5A9771E4",
"travelling": true,
"lines": 3,
"amountMinor": 143300,
"paidMinor": 35780,
"openMinor": 107520,
"feeIfCancelledMinor": 11900,
"refundIfCancelledMinor": 23880
},
{
"passengerRef": "PAX-02",
"passengerName": null,
"tripId": "TRP-B2BD5A9771E4",
"travelling": true,
"lines": 4,
"amountMinor": 150200,
"paidMinor": 42680,
"openMinor": 107520,
"feeIfCancelledMinor": 11900,
"refundIfCancelledMinor": 30780
}
]
}
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request failed validation. The message names the first failing field; oms-ops and group surfaces also return every issue in details. |
| 401 | unauthenticated | The bearer token is missing, invalid, expired or minted for another purpose. |
| 403 | scope_forbidden | The token is scoped to an agency or an access scope; this surface requires an unscoped tenant token. |
| 404 | oms_ops_not_enabled | Order operations are not enabled for the tenant. |
| 500 | internal | Unexpected failure. Retry with the same Idempotency-Key. |
List payments at a scope
/oms-ops/balances/{level}/{ref}/paymentsParameters
| Name | In | Required | Notes |
|---|---|---|---|
level | path | yes | one of group, trip, purchase_order |
ref | path | yes | |
within | query | true to include payments held at any level below the scope. |
Response 200
{ payments }.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request failed validation. The message names the first failing field; oms-ops and group surfaces also return every issue in details. |
| 401 | unauthenticated | The bearer token is missing, invalid, expired or minted for another purpose. |
| 403 | scope_forbidden | The token is scoped to an agency or an access scope; this surface requires an unscoped tenant token. |
| 404 | oms_ops_not_enabled | Order operations are not enabled for the tenant. |
| 500 | internal | Unexpected failure. Retry with the same Idempotency-Key. |
Re-run allocation at a scope
/oms-ops/balances/{level}/{ref}/reallocateParameters
| Name | In | Required | Notes |
|---|---|---|---|
level | path | yes | one of group, trip, purchase_order |
ref | path | yes |
Headers: Idempotency-Key, plus X-Request-Id.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
actor | object | yes | |
actor.channel | string | max 60 chars | |
actor.id | string | yes | 1–200 chars |
actor.name | string | max 200 chars | |
actor.role | string | yes | 1–100 chars |
Response 200
{ runId, releasedMinor, appliedMinor }.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request failed validation. The message names the first failing field; oms-ops and group surfaces also return every issue in details. |
| 401 | unauthenticated | The bearer token is missing, invalid, expired or minted for another purpose. |
| 403 | scope_forbidden | The token is scoped to an agency or an access scope; this surface requires an unscoped tenant token. |
| 404 | oms_ops_not_enabled | Order operations are not enabled for the tenant. |
| 409 | idempotency_in_progress | A request with this Idempotency-Key is still running. Retry after the Retry-After interval. |
| 422 | idempotency_key_reused | The Idempotency-Key was used for a different request. |
| 500 | internal | Unexpected failure. Retry with the same Idempotency-Key. |
Record a payment or a refund
/oms-ops/paymentsRecords money received (kind payment) or paid back (kind refund, with refundOf) against a group, trip or purchase order, and allocates it to order lines by the scenario's allocation method. Amounts are always positive. A body idempotencyKey returns the existing payment with 200.
Headers: Idempotency-Key, plus X-Request-Id.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
actor | object | yes | |
actor.channel | string | max 60 chars | |
actor.id | string | yes | 1–200 chars |
actor.name | string | max 200 chars | |
actor.role | string | yes | 1–100 chars |
allocation | object | ||
allocation.manual | array of object | ||
allocation.manual[].amountMinor | integer | yes | > 0 |
allocation.manual[].lineId | string | yes | 1–200 chars |
allocation.method | enum: proportional, sequential, manual, rule | ||
amountMinor | integer | yes | > 0 |
anchor | object | yes | |
anchor.level | enum: group, trip, purchase_order | yes | |
anchor.ref | string | yes | 1–200 chars |
currency | string | yes | pattern ^[A-Z]{3}$ |
externalRef | string | max 200 chars | |
idempotencyKey | string | 1–200 chars | |
kind | enum: payment, refund | default "payment" | |
method | string | yes | 1–60 chars |
note | string | 1–500 chars | |
payer | object | yes | |
payer.contact | string | max 320 chars | |
payer.name | string | max 200 chars | |
payer.ref | string | yes | 1–200 chars |
payer.role | string | yes | 1–60 chars |
paymentId | string | 1–200 chars | |
receivedAt | string (date-time) | ||
refundOf | string | 1–200 chars | |
scenario | string | yes | 1–60 chars |
Schema: apps/journeys/src/oms-ops/contracts.ts (RecordPaymentSchema)
Response 201
/oms-ops/paymentsRecord the booking deposit against the tripcurl -X POST "$BASE/oms-ops/payments" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Request-Id: req-0007" \
-H "Content-Type: application/json" \
-d '{
"kind": "payment",
"anchor": {
"level": "trip",
"ref": "TRP-B2BD5A9771E4"
},
"scenario": "deposit",
"method": "card",
"payer": {
"ref": "CUST-20419",
"name": "Giulia Rossi",
"role": "booker"
},
"amountMinor": 53760,
"currency": "EUR",
"externalRef": "PSP-AUTH-118274",
"idempotencyKey": "dep-Q-2027-58213",
"actor": {
"id": "web-checkout",
"role": "channel",
"channel": "web"
}
}'
HTTP/1.1 201
X-Request-Id: req-0007
{
"paymentId": "pay_6ac1a14d-7a36-4c41-b7bc-db35708558e0",
"tenantId": "meridian",
"kind": "payment",
"anchor": {
"level": "trip",
"ref": "TRP-B2BD5A9771E4"
},
"scenario": "deposit",
"method": "card",
"payer": {
"ref": "CUST-20419",
"name": "Giulia Rossi",
"role": "booker"
},
"amountMinor": 53760,
"currency": "EUR",
"receivedAt": "2026-11-02T09:09:19.000Z",
"externalRef": "PSP-AUTH-118274",
"refundOf": null,
"allocationMethod": "sequential",
"actor": {
"id": "web-checkout",
"role": "channel",
"channel": "web"
},
"recordedAt": "2026-11-02T09:09:19.000Z",
"allocatedMinor": 53760,
"unallocatedMinor": 0,
"refundedMinor": 0,
"legs": [
{
"allocationId": "alc_7ab4ba89-177a-4b91-bf1f-b27285d4aff1",
"paymentId": "pay_6ac1a14d-7a36-4c41-b7bc-db35708558e0",
"lineId": "L-A610167BDD4D",
"tripId": "TRP-B2BD5A9771E4",
"poId": "PO-5BEE8AAD2A57",
"groupId": null,
"amountMinor": 53760,
"currency": "EUR",
"method": "sequential",
"runId": "run_f815e8c5-9bf7-4f60-ac7f-fcb897921a7a",
"reason": "allocate",
"createdAt": "2026-11-02T09:09:19.000Z"
}
],
"idempotent": false
}
/oms-ops/paymentsPay the excursions in full on their own purchase ordercurl -X POST "$BASE/oms-ops/payments" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Request-Id: req-0008" \
-H "Content-Type: application/json" \
-d '{
"kind": "payment",
"anchor": {
"level": "purchase_order",
"ref": "PO-71B4D4926EDD"
},
"scenario": "ancillary_purchase",
"method": "wallet",
"payer": {
"ref": "CUST-20419",
"name": "Giulia Rossi",
"role": "booker"
},
"amountMinor": 24700,
"currency": "EUR",
"externalRef": "PSP-AUTH-120931",
"idempotencyKey": "exc-PO-71B4D4926EDD",
"actor": {
"id": "mobile-app",
"role": "channel",
"channel": "app"
}
}'
HTTP/1.1 201
X-Request-Id: req-0008
{
"paymentId": "pay_f64cf55a-93e1-4f1e-bdbd-2f1ae6d5ee6b",
"tenantId": "meridian",
"kind": "payment",
"anchor": {
"level": "purchase_order",
"ref": "PO-71B4D4926EDD"
},
"scenario": "ancillary_purchase",
"method": "wallet",
"payer": {
"ref": "CUST-20419",
"name": "Giulia Rossi",
"role": "booker"
},
"amountMinor": 24700,
"currency": "EUR",
"receivedAt": "2026-11-02T09:09:56.000Z",
"externalRef": "PSP-AUTH-120931",
"refundOf": null,
"allocationMethod": "proportional",
"actor": {
"id": "mobile-app",
"role": "channel",
"channel": "app"
},
"recordedAt": "2026-11-02T09:09:56.000Z",
"allocatedMinor": 24700,
"unallocatedMinor": 0,
"refundedMinor": 0,
"legs": [
{
"allocationId": "alc_30c286bb-67c5-441c-84cc-b8dcf6e8548e",
"paymentId": "pay_f64cf55a-93e1-4f1e-bdbd-2f1ae6d5ee6b",
"lineId": "L-FDAF4DA2CF1A",
"tripId": "TRP-B2BD5A9771E4",
"poId": "PO-71B4D4926EDD",
"groupId": null,
"amountMinor": 17800,
"currency": "EUR",
"method": "proportional",
"runId": "run_d0b2777e-df22-4866-8747-3a51fb429c9a",
"reason": "allocate",
"createdAt": "2026-11-02T09:09:56.000Z"
},
{
"allocationId": "alc_58bf1f79-5e71-47fc-a961-822f20ac6c2c",
"paymentId": "pay_f64cf55a-93e1-4f1e-bdbd-2f1ae6d5ee6b",
"lineId": "L-93A9D925FCE1",
"tripId": "TRP-B2BD5A9771E4",
"poId": "PO-71B4D4926EDD",
"groupId": null,
"amountMinor": 6900,
"currency": "EUR",
"method": "proportional",
"runId": "run_d0b2777e-df22-4866-8747-3a51fb429c9a",
"reason": "allocate",
"createdAt": "2026-11-02T09:09:56.000Z"
}
],
"idempotent": false
}
/oms-ops/paymentsRefund part of the deposit directlycurl -X POST "$BASE/oms-ops/payments" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Request-Id: req-0014" \
-H "Content-Type: application/json" \
-d '{
"kind": "refund",
"refundOf": "pay_6ac1a14d-7a36-4c41-b7bc-db35708558e0",
"anchor": {
"level": "trip",
"ref": "TRP-B2BD5A9771E4"
},
"scenario": "refund",
"method": "card",
"payer": {
"ref": "CUST-20419",
"name": "Giulia Rossi",
"role": "booker"
},
"amountMinor": 5000,
"currency": "EUR",
"note": "Price match after promotion change",
"idempotencyKey": "rfd-Q-2027-58213-1",
"actor": {
"id": "agent-0412",
"name": "Marco Bianchi",
"role": "care_agent",
"channel": "contact_centre"
}
}'
HTTP/1.1 201
X-Request-Id: req-0014
{
"paymentId": "pay_55710c02-f20c-4099-a7ee-844561a5764f",
"tenantId": "meridian",
"kind": "refund",
"anchor": {
"level": "trip",
"ref": "TRP-B2BD5A9771E4"
},
"scenario": "refund",
"method": "card",
"payer": {
"ref": "CUST-20419",
"name": "Giulia Rossi",
"role": "booker"
},
"amountMinor": 5000,
"currency": "EUR",
"receivedAt": "2026-11-02T09:13:38.000Z",
"externalRef": null,
"refundOf": "pay_6ac1a14d-7a36-4c41-b7bc-db35708558e0",
"allocationMethod": "proportional",
"actor": {
"id": "agent-0412",
"name": "Marco Bianchi",
"role": "care_agent",
"channel": "contact_centre"
},
"recordedAt": "2026-11-02T09:13:38.000Z",
"note": "Price match after promotion change",
"allocatedMinor": -5000,
"unallocatedMinor": 0,
"refundedMinor": 0,
"legs": [
{
"allocationId": "alc_bf81d462-5411-4169-ba86-1147862d70c6",
"paymentId": "pay_55710c02-f20c-4099-a7ee-844561a5764f",
"lineId": "L-A610167BDD4D",
"tripId": "TRP-B2BD5A9771E4",
"poId": "PO-5BEE8AAD2A57",
"groupId": null,
"amountMinor": -5000,
"currency": "EUR",
"method": "proportional",
"runId": "run_593bfe8a-a4a6-4d9f-a900-26a42dcd53b3",
"reason": "refund",
"createdAt": "2026-11-02T09:13:38.000Z"
}
],
"idempotent": false
}
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request failed validation. The message names the first failing field; oms-ops and group surfaces also return every issue in details. |
| 401 | unauthenticated | The bearer token is missing, invalid, expired or minted for another purpose. |
| 403 | scope_forbidden | The token is scoped to an agency or an access scope; this surface requires an unscoped tenant token. |
| 404 | anchor_not_found | The payment anchor has no order lines yet. |
| 404 | refund_origin_not_found | The payment named in refundOf does not exist. |
| 404 | oms_ops_not_enabled | Order operations are not enabled for the tenant. |
| 409 | payments_not_configured | No payment allocation policy is configured. |
| 409 | idempotency_in_progress | A request with this Idempotency-Key is still running. Retry after the Retry-After interval. |
| 422 | unknown_scenario | The payment scenario is not in the allocation policy. |
| 422 | anchor_not_allowed | The scenario does not allow payments at this anchor level. |
| 422 | currency_mismatch | The payment currency differs from the lines' currency. |
| 422 | overpayment | The payment exceeds the open balance and the policy rejects overpayments. |
| 422 | refund_needs_origin | A refund must name the payment it refunds in refundOf. |
| 422 | refund_anchor_mismatch | The refund anchor differs from the original payment's. |
| 422 | refund_exceeds_payment | The refund exceeds what is left of the original payment. |
| 422 | idempotency_key_reused | The Idempotency-Key was used for a different request. |
| 500 | internal | Unexpected failure. Retry with the same Idempotency-Key. |
Read a payment and its allocation
/oms-ops/payments/{paymentId}Parameters
| Name | In | Required | Notes |
|---|---|---|---|
paymentId | path | yes |
Response 200
/oms-ops/payments/pay_8107cc9e-34c3-48ab-bd3b-0a00c4e42db2Read the refund the change createdcurl -X GET "$BASE/oms-ops/payments/pay_8107cc9e-34c3-48ab-bd3b-0a00c4e42db2" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Request-Id: req-0013"
HTTP/1.1 200
X-Request-Id: req-0013
{
"kind": "refund",
"note": "Guest changed shore plans",
"actor": {
"id": "agent-0412",
"name": "Marco Bianchi",
"role": "care_agent",
"channel": "contact_centre"
},
"payer": {
"ref": "CUST-20419",
"name": "Giulia Rossi",
"role": "booker"
},
"anchor": {
"ref": "PO-71B4D4926EDD",
"level": "purchase_order"
},
"method": "wallet",
"currency": "EUR",
"refundOf": "pay_f64cf55a-93e1-4f1e-bdbd-2f1ae6d5ee6b",
"scenario": "refund",
"tenantId": "meridian",
"paymentId": "pay_8107cc9e-34c3-48ab-bd3b-0a00c4e42db2",
"receivedAt": "2026-11-02T09:06:42.000Z",
"recordedAt": "2026-11-02T09:06:42.000Z",
"amountMinor": 24700,
"externalRef": null,
"allocationMethod": "proportional",
"allocatedMinor": 0,
"unallocatedMinor": 0,
"refundedMinor": 0,
"legs": []
}
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request failed validation. The message names the first failing field; oms-ops and group surfaces also return every issue in details. |
| 401 | unauthenticated | The bearer token is missing, invalid, expired or minted for another purpose. |
| 403 | scope_forbidden | The token is scoped to an agency or an access scope; this surface requires an unscoped tenant token. |
| 404 | payment_not_found | The payment does not exist. |
| 404 | oms_ops_not_enabled | Order operations are not enabled for the tenant. |
| 500 | internal | Unexpected failure. Retry with the same Idempotency-Key. |
Read a payment's allocation by passenger
/oms-ops/payments/{paymentId}/passengersParameters
| Name | In | Required | Notes |
|---|---|---|---|
paymentId | path | yes |
Response 200
{ paymentId, legs, versions }; each leg is split to the passengers of its line.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request failed validation. The message names the first failing field; oms-ops and group surfaces also return every issue in details. |
| 401 | unauthenticated | The bearer token is missing, invalid, expired or minted for another purpose. |
| 403 | scope_forbidden | The token is scoped to an agency or an access scope; this surface requires an unscoped tenant token. |
| 404 | payment_not_found | The payment does not exist. |
| 404 | oms_ops_not_enabled | Order operations are not enabled for the tenant. |
| 500 | internal | Unexpected failure. Retry with the same Idempotency-Key. |