begin_personal_payment
The requester starts paying their part of a request — personal_amount, what's left after the
company's share. It returns an extra purchase that the store service charges to the requester's
wallet. Once the store reports the payment, the request moves from AWAITING_PERSONAL_PAYMENT to
CONFIRMED in the status flow.
It is a GraphQL mutation returning ExtraPurchase. Only the user who created the request
can call it, and only while the request is AWAITING_PERSONAL_PAYMENT.
Input
input: BeginPersonalPaymentInput!
| Field | Type | Required | Description |
|---|---|---|---|
user_request_id | String | Yes | The user request to pay. |
Response
| Field | Type | Description |
|---|---|---|
id | String | The extra purchase to pay. Send it to the store's book_extra_purchase. |
amount | Decimal | What the requester pays: personal_amount, converted to VND. |
currency | String | Always VND. |
status | ExtraPurchaseStatus | PAYING until the store reports the payment. |
Calling it again while a payment is still PAYING returns the same extra purchase — so if the
requester leaves the checkout without paying, book that same purchase again. After a payment fails,
the next call starts a new one. Each attempt is its own extra purchase, with the request's
user_request_id and personal: true; there's at most one PAYING at a time.
mutation {
begin_personal_payment(input: { user_request_id: "3JMY..." }) {
id amount currency status
}
}
Paying it in the store
FE calls begin_personal_payment, then the store's book_extra_purchase, then finishes with the
store's Payment Flow — see
How the requester pays.
begin_personal_payment(flight) — returns the extra purchase.book_extra_purchase(store), withinput: { flight: { id: "<extra purchase id>" } }— puts it in the requester's cart. Only the requester can book their own personal payment. Steps 1–2 are step 3 of the Payment Flow, "create shopping_item": clear the cart and cancel any open checkout session first.- The rest of the Payment Flow (store) —
begin_payment_checkout_session, corporate payment left off (this is the requester's own money, not the company's), thenpay_with_wallet. - The store tells the flight service when the payment succeeds or fails; there's nothing more to
call. On success the request moves to
CONFIRMED, then on to approval, or straight toRESOLVEDwhen the company pays nothing. On failure it staysAWAITING_PERSONAL_PAYMENT, so the requester can start again from step 1.
Refetch the request after paying before you render its status.
Errors
| Error | Meaning |
|---|---|
<status>_user_request | The request isn't AWAITING_PERSONAL_PAYMENT — for example resolved_user_request once it's paid. |
no_personal_amount | Nothing is left for the requester to pay. |
personal_payment_in_progress | Another call started a payment at the same moment, and it ended before this call could return it. Call again. |
unauthorized | The caller didn't create the request. |
not_found | Unknown user_request_id. |
The store's book_extra_purchase adds two of its own:
| Error | Meaning |
|---|---|
unauthorized | Someone other than the requester tried to book the personal payment. |
<STATUS>_extra_purchase | The extra purchase isn't PAYING any more — for example CANCELLED_extra_purchase. Call begin_personal_payment again for a new one. |
It can also return Middleware Errors. All user request errors are listed together in User Request Errors.