Skip to content

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:

  1. Initiate Checkout - Call Checkout Offer to get a Stripe checkout URL
  2. Complete Payment - Redirect user to Stripe where they complete payment
  3. 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 ​

ParameterDescription
sessionId stringThe Stripe checkout session ID (cs_…) received as the sessionId query parameter on the success page.

Request Example ​

json
{
  "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

json
{
  "message": "Unauthenticated."
}

Error Handling ​

All errors use the standard {"message": "..."} envelope (see Error Responses).

Payment Not Completed ​

422 Unprocessable Content

json
{
  "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

json
{
  "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 the offered state.
  • Záznam bol medzitým zmenený. Skúste to znova. — concurrent modification; re-fetch the testimony and retry.

Stripe Unavailable ​

502 Bad Gateway

json
{
  "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 offered state
  • After successful acceptance:
    • The testimony transitions to accepted state
    • The offer is marked as accepted; expert and acceptedOffer are 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