Accept Testimony Offer
Confirm payment and accept a testimony offer after successful Stripe checkout. This endpoint completes the acceptance process by validating the Stripe payment session and transitioning the testimony to the "accepted" state.
See Payment Integration for the complete payment integration guide.
Payment Flow
The complete offer acceptance flow involves three steps:
- Initiate Checkout - Call Checkout Offer to get a Stripe checkout URL
- Complete Payment - Redirect user to Stripe where they complete payment
- Confirm Acceptance - Call this endpoint with the session ID returned from Stripe
After successful confirmation, the testimony transitions from offered to accepted state.
Webhook race
The backend also accepts the offer when Stripe's checkout.session.completed webhook arrives, which can happen before the client lands on your success page. In that case this endpoint responds with 409 Conflict — Pre tento posudok už bola prijatá ponuka. Treat that as success on the payment-success page and confirm the state with Show Testimony.
HTTP Request
POST /api/v1/testimonies/offers/accept
Note: This endpoint does NOT include an offer ID in the URL. The offer is identified from the Stripe session.
Parameters
| Parameter | Description |
|---|---|
sessionId string | The Stripe checkout session ID (cs_…) received as the sessionId query parameter on the success page. |
Request Example
{
"sessionId": "cs_test_a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9T0"
}Response
204 No Content
Indicates the offer was successfully accepted and the testimony has transitioned to the "accepted" state.
Authentication
Requires authentication via Bearer token, a verified email and the client role (403 Forbidden otherwise).
401 Unauthorized
{
"message": "Unauthenticated."
}Error Handling
All errors use the standard {"message": "..."} envelope (see Error Responses).
Payment Not Completed
422 Unprocessable Content
{
"message": "Platba ešte nebola dokončená. Stav: unpaid."
}Returned when the Stripe session exists but has not been paid. A validation error with an errors object is returned instead when sessionId is missing or does not start with cs_.
Wrong Client
403 Forbidden
{
"message": "This testimony does not belong to the authenticated client."
}The session was created for another client's testimony.
Conflicts
409 Conflict with one of these messages:
Pre tento posudok už bola prijatá ponuka.— the webhook already accepted this session (see above), the session was confirmed before, or another offer was paid. Verify with Show Testimony.Táto ponuka už nie je dostupná.— the offer was withdrawn in the meantime.Prechod zo stavu [cancelled] do stavu [accepted] nie je možný.— the testimony left theofferedstate.Záznam bol medzitým zmenený. Skúste to znova.— concurrent modification; re-fetch the testimony and retry.
Stripe Unavailable
502 Bad Gateway
{
"message": "Could not retrieve Stripe session."
}The session id is unknown to Stripe or Stripe could not be reached — retry later.
Business Logic
- The offer can only be accepted if the testimony is in
offeredstate - After successful acceptance:
- The testimony transitions to
acceptedstate - The offer is marked as accepted;
expertandacceptedOfferare populated on the testimony - The expert is notified by email
- Invoices are generated and emailed (the expert's invoice to the expert, the platform invoice to the client)
- The platform commission is retained from the expert's payout
- The testimony transitions to