Mark booking payment as processing (Public API)
Summary
A new GraphQL mutation, markBookingPaymentProcessing, moves a booking from
pending to processing after the partner's client has successfully confirmed
the Stripe PaymentIntent. This mirrors the existing online-booking REST
endpoint setBookingPaymentIsProcessing.
Payment completion (processing → done) still comes from Stripe webhooks and
is not handled by this mutation.
Mutation
mutation MarkBookingPaymentProcessing($paymentIntentId: String!, $bookingId: ID) {
markBookingPaymentProcessing(
paymentIntentId: $paymentIntentId
bookingId: $bookingId
) {
success
error
deleted
data {
id
onlineBookingPaymentStatus
}
}
}
Arguments
| Argument | Required | Description |
|---|---|---|
paymentIntentId | Yes | Stripe PaymentIntent id returned when the payment intent was created for the booking; this is the stable correlation key for retries and webhook races |
bookingId | No | Optional booking id guard; when provided, it must match the booking row that stores this payment intent |
Response
| Field | Description |
|---|---|
success | true when payment status moved from pending to processing |
data | Updated booking when success is true |
code | Machine-readable failure code when success is false (NOT_FOUND, ALREADY_PROCESSING, ALREADY_PAID, INVALID_STATE) |
error | Human-readable failure reason when success is false |
deleted | true when the matched booking has been soft-deleted (for example by an expiry job). Omitted when the booking is not deleted. |
When to call
Call immediately after successful client-side PaymentIntent confirmation
(confirmPayment, including redirect return flows), before relying on
payment being marked done.
Typical partner flow:
createBooking— create the appointment- Create a payment intent for the booking (via your payment-intent mutation when available)
- Confirm payment in the browser with Stripe.js
markBookingPaymentProcessing— tell Semble checkout is in progress- Wait for Stripe webhooks to mark payment
doneand create the invoice
Failure behaviour
The mutation fails safely without modifying data when:
- No booking in the authenticated practice stores the given payment intent id
- Payment status is not
pending - Optional
bookingIddoes not match the booking for that payment intent
Failure outcomes are explicit:
NOT_FOUND+Pending booking not foundwhen no matching booking is visible in scopeALREADY_PROCESSING+Booking payment is already processingwhen retrying after a successful transitionALREADY_PAID+Booking payment is already paidwhen webhook completion has already moved payment to doneINVALID_STATE+Booking payment is no longer pendingfor other non-pending states
When a booking was found but is not eligible, deleted is true if the booking has already been cleaned up.
If a booking was soft-deleted while payment was still pending (for example slot
expiry during checkout), the mutation can still succeed and returns
{ success: true, deleted: true }. Partners should treat this like the online
booking flow: payment may have gone through but the slot was already released.
Authorization
Access is scoped to the authenticated practice credential (same as other booking mutations). An online-booking token is not used.