{"openapi":"3.1.0","info":{"title":"marve-py-payment-service","version":"0.1.0"},"paths":{"/payments/health":{"get":{"tags":["Payments"],"summary":"Health check","operationId":"health_payments_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"message":{"type":"string"}},"additionalProperties":true,"type":"object","required":["message"],"title":"Health"},"example":{"message":"marve-py-payment-service is okay and running, fast!"}}}},"500":{"description":"Unexpected failure, including a provider error. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}}}}},"/payments/history":{"get":{"tags":["Payments"],"summary":"The signed-in user's payments","description":"Always the caller's own payments, from the token. Any other query key filters on that stored field the same way (`true`/`false` become booleans).","operationId":"get_payment_history_payments_history_get","parameters":[{"description":"Page number, or `all` for no paging. Pages hold 10.","required":false,"schema":{"type":"string","title":"Page","description":"Page number, or `all` for no paging. Pages hold 10.","examples":["1"]},"name":"page","in":"query"},{"description":"`field` ascending, `-field` descending. Default `-created_at_timestamp`.","required":false,"schema":{"type":"string","title":"Ordering","description":"`field` ascending, `-field` descending. Default `-created_at_timestamp`.","examples":["-created_at_timestamp"]},"name":"ordering","in":"query"},{"description":"Search text matched across the payment's fields and its payment method.","required":false,"schema":{"type":"string","title":"All","description":"Search text matched across the payment's fields and its payment method."},"name":"all","in":"query"},{"description":"Partial, case-insensitive, e.g. `paid`.","required":false,"schema":{"type":"string","title":"Status","description":"Partial, case-insensitive, e.g. `paid`."},"name":"status","in":"query"},{"description":"Partial, case-insensitive.","required":false,"schema":{"type":"string","title":"Email","description":"Partial, case-insensitive."},"name":"email","in":"query"},{"description":"Partial, case-insensitive.","required":false,"schema":{"type":"string","title":"Reference","description":"Partial, case-insensitive."},"name":"reference","in":"query"},{"description":"Partial, case-insensitive.","required":false,"schema":{"type":"string","title":"Payment Session Reference","description":"Partial, case-insensitive."},"name":"payment_session_reference","in":"query"},{"description":"Whole number, exact match.","required":false,"schema":{"type":"string","title":"Amount","description":"Whole number, exact match."},"name":"amount","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"title":"PaymentHistory","type":"object","properties":{"items":{"description":"A list of payment records, or `{\"payments\": []}` when nothing matches.","anyOf":[{"type":"array","items":{"title":"PaymentRecord","type":"object","properties":{"reference":{"type":"string"},"user_reference":{"type":["string","null"]},"email":{"type":["string","null"]},"status":{"type":["string","null"]},"payment_method":{"type":["object","null"]},"payment_session_reference":{"type":["string","null"]},"metadata":{"type":"object"},"amount":{"type":["number","null"]},"expires_at_timestamp":{"type":["string","null"]},"created_at_timestamp":{"type":["string","null"]},"updated_at_timestamp":{"type":["string","null"]}},"required":["reference"],"additionalProperties":true}},{"type":"object","properties":{"payments":{"type":"array"}}}]},"pagination":{"title":"Pagination","type":"object","properties":{"current_page":{"type":"integer"},"page_size":{"type":"integer"},"total_records":{"type":"integer"},"total_pages":{"type":"integer"},"has_next":{"type":"boolean"},"has_previous":{"type":"boolean"}},"required":["current_page","page_size","total_records","total_pages","has_next","has_previous"],"additionalProperties":true}},"required":["items","pagination"],"additionalProperties":true},"example":{"items":{"payments":[]},"pagination":{"current_page":1,"page_size":10,"total_records":0,"total_pages":0,"has_next":false,"has_previous":false}}}}},"401":{"description":"No token, an expired token, or not signed in","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure, including a provider error. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/payments/{reference}/initiate":{"patch":{"tags":["Payments"],"summary":"Start a checkout session","description":"Opens a Stripe checkout session for the payment and returns where to send the customer. No request body. `reference` is the payment's 36-character reference.","operationId":"initiate_payment_session_payments__reference__initiate_patch","parameters":[{"required":true,"schema":{"type":"string","title":"Reference"},"name":"reference","in":"path"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"reference":{"type":"string"},"session":{"properties":{"session_id":{"type":"string"},"session_url":{"type":"string"},"status":{"type":"string"}},"additionalProperties":true,"type":"object","required":["session_id","session_url","status"],"title":"CheckoutSession"}},"additionalProperties":true,"type":"object","required":["reference","session"],"title":"PaymentSession"},"example":{"reference":"11111111-1111-1111-1111-111111111111","session":{"session_id":"cs_test_1","session_url":"https://stripe.example/pay","status":"initiated"}}}}},"400":{"description":"The payment has no payment method or provider set, or the provider's answer was incomplete","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"401":{"description":"No token, an expired token, or not signed in","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No live payment with this reference","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure, including a provider error. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/payments/{reference}/confirm":{"patch":{"tags":["Payments"],"summary":"Confirm a paid checkout","description":"Asks the provider whether the checkout session was paid and, if so, marks the payment `paid`. No request body. `reference` is the payment's 36-character reference.","operationId":"confirm_payment_payments__reference__confirm_patch","parameters":[{"required":true,"schema":{"type":"string","title":"Reference"},"name":"reference","in":"path"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"reference":{"type":"string"},"message":{"type":"string"}},"additionalProperties":true,"type":"object","required":["reference","message"],"title":"PaymentMessage"},"example":{"reference":"11111111-1111-1111-1111-111111111111","message":"Payment with reference 11111111-1111-1111-1111-111111111111 confirmed and payment initiated"}}}},"400":{"description":"The payment has no payment method or provider set, or the provider's answer was incomplete","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"401":{"description":"No token, an expired token, or not signed in","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No live payment with this reference","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"451":{"description":"The provider says the payment has not succeeded, so it cannot be confirmed","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure, including a provider error. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/payments/{reference}/status":{"get":{"tags":["Payments"],"summary":"Payment status","description":"A short view of the live payment. `reference` is the payment's 36-character reference.","operationId":"get_payment_status_payments__reference__status_get","parameters":[{"required":true,"schema":{"type":"string","title":"Reference"},"name":"reference","in":"path"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"title":"PaymentStatus","type":"object","properties":{"reference":{"type":"string"},"status":{"type":["string","null"]},"amount":{"type":["number","null"]},"payment_method":{"type":["object","null"]},"session":{"type":["string","null"]},"metadata":{"type":"object"},"created_at":{"type":["string","null"]},"expires_at":{"type":["string","null"]}},"required":["reference"],"additionalProperties":true},"example":{"reference":"11111111-1111-1111-1111-111111111111","status":"awaiting_payment","amount":100.0,"payment_method":{"method":"card","provider":"stripe","currency":"GBP"},"session":"cs_test_1","metadata":{},"created_at":"2026-09-30T11:17:13.888882","expires_at":"2026-09-30T11:22:13.888882"}}}},"401":{"description":"No token, an expired token, or not signed in","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No live payment with this reference","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure, including a provider error. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/payments/{reference}/cancel":{"delete":{"tags":["Payments"],"summary":"Cancel a payment","description":"Cancels the provider's payment intent and marks the payment `cancelled`. Every failure here, a missing payment included, answers 500. `reference` is the payment's 36-character reference.","operationId":"cancel_payment_payments__reference__cancel_delete","parameters":[{"required":true,"schema":{"type":"string","title":"Reference"},"name":"reference","in":"path"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"reference":{"type":"string"},"message":{"type":"string"}},"additionalProperties":true,"type":"object","required":["reference","message"],"title":"PaymentMessage"},"example":{"reference":"11111111-1111-1111-1111-111111111111","message":"Payment with reference 11111111-1111-1111-1111-111111111111 has been cancelled"}}}},"401":{"description":"No token, an expired token, or not signed in","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure, including a provider error. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/payments/{reference}/intent":{"patch":{"tags":["Payments"],"summary":"Create a payment intent","description":"Creates a Stripe payment intent for the payment and returns the client secret the browser needs. No request body. `reference` is the payment's 36-character reference.","operationId":"create_payment_intent_payments__reference__intent_patch","parameters":[{"required":true,"schema":{"type":"string","title":"Reference"},"name":"reference","in":"path"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"reference":{"type":"string"},"payment_intent_id":{"type":"string"},"client_secret":{"type":"string"},"status":{"type":"string"}},"additionalProperties":true,"type":"object","required":["reference","payment_intent_id","client_secret","status"],"title":"PaymentIntent"},"example":{"reference":"11111111-1111-1111-1111-111111111111","payment_intent_id":"pi_test_1","client_secret":"pi_test_1_secret_example","status":"succeeded"}}}},"400":{"description":"The payment has no payment method or provider set, or the provider's answer was incomplete","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"401":{"description":"No token, an expired token, or not signed in","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No live payment with this reference","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure, including a provider error. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/payments/{reference}":{"get":{"tags":["Payments"],"summary":"The payment record","description":"The live payment as stored. `reference` is the payment's 36-character reference.","operationId":"get_payment_payments__reference__get","parameters":[{"required":true,"schema":{"type":"string","title":"Reference"},"name":"reference","in":"path"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"title":"PaymentRecord","type":"object","properties":{"reference":{"type":"string"},"user_reference":{"type":["string","null"]},"email":{"type":["string","null"]},"status":{"type":["string","null"]},"payment_method":{"type":["object","null"]},"payment_session_reference":{"type":["string","null"]},"metadata":{"type":"object"},"amount":{"type":["number","null"]},"expires_at_timestamp":{"type":["string","null"]},"created_at_timestamp":{"type":["string","null"]},"updated_at_timestamp":{"type":["string","null"]}},"required":["reference"],"additionalProperties":true},"example":{"reference":"11111111-1111-1111-1111-111111111111","user_reference":"22222222-2222-2222-2222-222222222222","email":"jane@example.com","status":"awaiting_payment","payment_method":{"method":"card","provider":"stripe","currency":"GBP"},"payment_session_reference":"cs_test_1","metadata":{},"amount":100.0,"expires_at_timestamp":"2026-09-30T11:22:13.888882","created_at_timestamp":"2026-09-30T11:17:13.888882","updated_at_timestamp":"2026-09-30T11:17:13.888882"}}}},"401":{"description":"No token, an expired token, or not signed in","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No live payment with this reference","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure, including a provider error. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string"},"error_type":{"type":"string"},"errors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"title":"ErrorEnvelope"},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["Payment with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/webhooks/stripe":{"post":{"tags":["Webhooks"],"summary":"Stripe webhook","description":"Called by Stripe, not by users. Authenticated by the `stripe-signature` header, not a token. Handles `payment_intent.succeeded` and `payment_intent.payment_failed`; any other event type is acknowledged and ignored.","operationId":"handle_stripe_webhook_api_webhooks_stripe_post","parameters":[{"description":"Stripe's signature over the raw body. Checked against the webhook secret.","required":true,"schema":{"type":"string"},"name":"stripe-signature","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"type":{"type":"string","description":"`payment_intent.succeeded` or `payment_intent.payment_failed` are acted on."},"data":{"type":"object","description":"`data.object` is the payment intent; its `metadata.payment_reference` names the payment."}},"additionalProperties":true,"type":"object","required":["type","data"],"title":"StripeEvent"},"example":{"type":"payment_intent.succeeded","data":{"object":{"id":"pi_test_1","status":"succeeded","amount_received":10000,"metadata":{"payment_reference":"11111111-1111-1111-1111-111111111111"}}}}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"message":{"type":"string"}},"additionalProperties":true,"type":"object","required":["message"],"title":"WebhookResult"},"example":{"message":"Payment confirmed from webhook"}}}},"400":{"description":"Bad signature, or the event could not be handled","content":{"application/json":{"schema":{"properties":{"error":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error"],"title":"WebhookError"},"example":{"error":"Invalid signature"}}}}}}}},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"HTTPBearer":{"type":"http","description":"The access token from sign-in.","scheme":"bearer"}}}}