add_passenger_fee
Adds a seat, baggage or other fee to one passenger on one leg and charges it. With
user_request_id and user_request_fee_id, it is also how an admin applies a fee of a RESOLVED
user request — the last step of the user request flow. Each
fee of a request is applied with its own call.
It is a GraphQL mutation returning Passenger, and needs the ADMIN role.
Input
input: AddPassengerFeeInput!
| Field | Type | Required | Description |
|---|---|---|---|
booking_history_id | String | Yes | The booking to add the fee to. |
fee_type | FeeType | Yes | BAGGAGE, SEAT or OTHER. With a user request fee, it must be that fee's type. |
departure_eticket_id | String | One of the two | The passenger's e-ticket on the departure leg. |
arrival_eticket_id | String | One of the two | The passenger's e-ticket on the return leg. |
baggage | AddBaggageInput | When BAGGAGE, without a user request | The baggage to add. |
seat | SeatInput | When SEAT, without a user request | The seat to add. |
other_fee | OtherFeeInput | When OTHER, without a user request | The fee to add. |
user_request_id | String | No | A RESOLVED user request whose fee this applies. Needs user_request_fee_id. |
user_request_fee_id new | String | With user_request_id | The fee of that request to apply. Each fee can be applied once. |
The e-ticket picks both the passenger and the leg. If both are sent, the departure one is used.
Applying a user request fee
The fee is accepted only when all of these hold:
- The request is
RESOLVED. - It belongs to the same booking as
booking_history_id, and is for the same passenger as the e-ticket. - The fee is one of the request's
fees, isn'tpaidyet, and is for the e-ticket's leg. fee_typeis the fee's type.
With it, the call behaves differently:
| Without a user request | With a user request fee | |
|---|---|---|
| Seat / baggage / other fee data | Required; decides what is added | Taken from the fee; the input's baggage, seat and other_fee are ignored |
| Charged to the company | The fee price | The fee's corporate_amount, converted to VND (0 means no charge) |
| Booking price goes up by | The fee price | The fee's full price |
| Afterwards | Nothing new | The fee is paid, and the payment is added to its extra_purchase_ids |
The requester's part (price - corporate_amount) was already paid with
begin_personal_payment, before approval.
mutation {
add_passenger_fee(input: {
booking_history_id: "..."
fee_type: SEAT
departure_eticket_id: "..."
user_request_id: "3JMY..."
user_request_fee_id: "3Jwm...seat"
}) { id }
}
When the payment fails
If the payment is refused, the fee stays unpaid and the admin can retry. The store service's own
error comes back, such as not_enough when the corporate balance is too low.
If the payment service can't be reached, the call returns payment_unreachable and the fee stays
marked as paid, because the charge may have gone through. Check with the backend team before
retrying.
Errors
Errors for a user request fee:
| Error | Meaning |
|---|---|
user_request_not_found | Unknown user_request_id. |
<status>_user_request | The request isn't RESOLVED — for example confirmed_user_request. |
user_request_fee_id_required | user_request_id was sent without user_request_fee_id. |
user_request_fee_not_found | The fee isn't one of the request's fees. |
paid_user_request_fee | The fee was already applied. |
user_request_fee_type_mismatch | fee_type isn't the fee's type. |
user_request_booking_mismatch | The request is for a different booking. |
user_request_passenger_mismatch | The request is for a different passenger. |
user_request_leg_mismatch | The fee is for the other leg. |
payment_unreachable | Payment service didn't answer; the charge may have gone through. |
Errors from the fee itself:
| Error | Meaning |
|---|---|
MISSING_DEPARTURE_ARRIVAL_ETICKET_ID | Neither e-ticket id was sent. |
not_found | Unknown booking_history_id. |
INVALID_ETICKET_ID | No passenger on the booking has that e-ticket. |
missing_fee_data | The input matching fee_type — baggage, seat or other_fee — is missing. |
invalid_transaction_time | transaction_time is in the future. |
invalid_data | The baggage is no bigger than what the passenger already has on that leg. |
already_has_seat | The passenger already has a seat on that leg. |
It can also return Middleware Errors.