{"openapi":"3.1.0","info":{"title":"Utopia Payments API","version":"1.0.0","description":"Accept one-time payments and renewing subscriptions from your own website.\n\n**Authentication.** Send your secret key as a bearer token:\n`Authorization: Bearer sk_live_…`. Create keys in Dashboard → Developers.\nTest keys (`sk_test_…`) only ever see test data.\n\n**Amounts** are integers in the currency's minor unit: `34900` is AED 349.00.\nKWD, BHD and OMR use three minor-unit digits. Because checkout settles to two\ndecimal places. Utopia currently accepts AED only. Read the enabled currencies\nfrom `GET /account`.\n**Timestamps** are ISO 8601. **Ids** carry a type prefix such as `pay_` or `sub_`.\n\n**Errors** use HTTP status codes with a JSON body `{ \"code\", \"message\" }`.\n\n**Idempotency.** Send `Idempotency-Key` on POST requests. Retrying with the\nsame key returns the first response for 24 hours instead of creating a duplicate.\n\n**Pagination.** List endpoints return `{ items, has_more, next_cursor }`;\npass `next_cursor` back as `cursor` for the next page.\n\n**Rate limits.** 240 requests per minute per key; over the limit returns 429.\n\n**Webhooks** follow the Standard Webhooks specification: verify\n`webhook-signature` with your endpoint's `whsec_…` secret.\n\nThere is currently no public endpoint that initiates a refund. Operational\nrefunds appear in payment state and emit `refund.succeeded`.","contact":{"name":"Utopia Payments","email":"support@utopia-payments.com"}},"servers":[{"url":"https://utopia-payments.com/api/v1"}],"security":[{"secretKey":[]}],"tags":[{"name":"Checkout sessions","description":"Hosted checkout for one-time payments and new subscriptions."},{"name":"Payments","description":"Every charge, including subscription renewals."},{"name":"Subscriptions","description":"Renewing plans started by a recurring checkout."},{"name":"Products","description":"What you sell: one-time or recurring."},{"name":"Customers","description":"People who pay you."},{"name":"Webhooks","description":"Endpoints that receive signed events."},{"name":"Events","description":"The record of everything sent to webhooks."},{"name":"Account","description":"The merchant a key belongs to."},{"name":"Webhook events","description":"What Utopia sends to your webhook endpoints."}],"paths":{"/account":{"get":{"tags":["Account"],"operationId":"getAccount","summary":"Retrieve your account","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/checkout_sessions":{"post":{"tags":["Checkout sessions"],"operationId":"createCheckoutSession","summary":"Create a checkout session","description":"Returns a `checkout_url` to redirect the customer to. A cart with one recurring product starts a subscription; otherwise it takes a one-time payment. Sessions expire after 24 hours.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutSessionCreate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutSession"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/checkout_sessions/{id}":{"get":{"tags":["Checkout sessions"],"operationId":"getCheckoutSession","summary":"Retrieve a checkout session","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^cks_[0-9a-f]{32}$","examples":["cks_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutSession"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/payments":{"get":{"tags":["Payments"],"operationId":"listPayments","summary":"List payments","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/PaymentStatus"}},{"name":"customer_id","in":"query","required":false,"schema":{"type":"string","pattern":"^cus_[0-9a-f]{32}$","examples":["cus_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]}},{"name":"checkout_session_id","in":"query","required":false,"schema":{"type":"string","pattern":"^cks_[0-9a-f]{32}$","examples":["cks_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["items","has_more","next_cursor"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Payment"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/payments/{id}":{"get":{"tags":["Payments"],"operationId":"getPayment","summary":"Retrieve a payment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^pay_[0-9a-f]{32}$","examples":["pay_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Payment"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/subscriptions":{"get":{"tags":["Subscriptions"],"operationId":"listSubscriptions","summary":"List subscriptions","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/SubscriptionStatus"}},{"name":"customer_id","in":"query","required":false,"schema":{"type":"string","pattern":"^cus_[0-9a-f]{32}$","examples":["cus_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["items","has_more","next_cursor"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Subscription"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/subscriptions/{id}":{"get":{"tags":["Subscriptions"],"operationId":"getSubscription","summary":"Retrieve a subscription","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^sub_[0-9a-f]{32}$","examples":["sub_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subscription"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"patch":{"tags":["Subscriptions"],"operationId":"updateSubscription","summary":"Update or cancel a subscription","description":"Send `{ \"status\": \"cancelled\" }` to cancel now, or `{ \"cancel_at_period_end\": true }` to let the paid period run out without renewing.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^sub_[0-9a-f]{32}$","examples":["sub_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionUpdate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subscription"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/products":{"get":{"tags":["Products"],"operationId":"listProducts","summary":"List products","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"name":"status","in":"query","required":false,"schema":{"enum":["active","draft","archived"]}},{"name":"billing","in":"query","required":false,"schema":{"enum":["one_time","recurring"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["items","has_more","next_cursor"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Product"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Products"],"operationId":"createProduct","summary":"Create a product","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductCreate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/products/{id}":{"get":{"tags":["Products"],"operationId":"getProduct","summary":"Retrieve a product","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^pdt_[0-9a-f]{32}$","examples":["pdt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"patch":{"tags":["Products"],"operationId":"updateProduct","summary":"Update a product","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^pdt_[0-9a-f]{32}$","examples":["pdt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductUpdate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/customers":{"get":{"tags":["Customers"],"operationId":"listCustomers","summary":"List customers","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"name":"email","in":"query","required":false,"schema":{"type":"string","format":"email"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["items","has_more","next_cursor"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Customer"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Customers"],"operationId":"createCustomer","summary":"Create a customer","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerCreate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Customer"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/customers/{id}":{"get":{"tags":["Customers"],"operationId":"getCustomer","summary":"Retrieve a customer","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^cus_[0-9a-f]{32}$","examples":["cus_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Customer"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"patch":{"tags":["Customers"],"operationId":"updateCustomer","summary":"Update a customer","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^cus_[0-9a-f]{32}$","examples":["cus_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerUpdate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Customer"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/webhooks":{"get":{"tags":["Webhooks"],"operationId":"listWebhooks","summary":"List webhook endpoints","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["items","has_more","next_cursor"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Webhooks"],"operationId":"createWebhook","summary":"Create a webhook endpoint","description":"The response includes the endpoint's signing `secret`.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/WebhookEndpoint"},{"type":"object","required":["secret"],"properties":{"secret":{"type":"string","pattern":"^whsec_"}}}]}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/webhooks/{id}":{"get":{"tags":["Webhooks"],"operationId":"getWebhook","summary":"Retrieve a webhook endpoint","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^wh_[0-9a-f]{32}$","examples":["wh_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"patch":{"tags":["Webhooks"],"operationId":"updateWebhook","summary":"Update a webhook endpoint","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^wh_[0-9a-f]{32}$","examples":["wh_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointUpdate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"delete":{"tags":["Webhooks"],"operationId":"deleteWebhook","summary":"Delete a webhook endpoint","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^wh_[0-9a-f]{32}$","examples":["wh_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["object","webhook_id","deleted"],"properties":{"object":{"const":"webhook"},"webhook_id":{"type":"string","pattern":"^wh_[0-9a-f]{32}$","examples":["wh_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"deleted":{"const":true}}}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/webhooks/{id}/secret":{"get":{"tags":["Webhooks"],"operationId":"getWebhookSecret","summary":"Retrieve an endpoint's signing secret","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^wh_[0-9a-f]{32}$","examples":["wh_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["secret"],"properties":{"secret":{"type":"string","pattern":"^whsec_"}}}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/events":{"get":{"tags":["Events"],"operationId":"listEvents","summary":"List events","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"name":"type","in":"query","required":false,"schema":{"$ref":"#/components/schemas/EventType"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["items","has_more","next_cursor"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/events/{id}":{"get":{"tags":["Events"],"operationId":"getEvent","summary":"Retrieve an event","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^evt_[0-9a-f]{32}$","examples":["evt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}}},"webhooks":{"payment.succeeded":{"post":{"tags":["Webhook events"],"summary":"payment.succeeded","description":"Sent to your endpoint as a signed POST. Answer with any 2xx within 10 seconds; failures are retried with backoff for about a day. Verify the signature before trusting the body.","parameters":[{"name":"webhook-id","in":"header","required":true,"schema":{"type":"string","pattern":"^evt_[0-9a-f]{32}$","examples":["evt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"description":"Unique per event; use it to ignore duplicates."},{"name":"webhook-timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds. Reject deliveries older than a few minutes."},{"name":"webhook-signature","in":"header","required":true,"schema":{"type":"string"},"description":"`v1,` + base64 HMAC-SHA256 of `{webhook-id}.{webhook-timestamp}.{raw body}`, keyed with the base64-decoded part of your `whsec_` secret."}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["id","type","livemode","created_at","data"],"properties":{"id":{"type":"string","pattern":"^evt_[0-9a-f]{32}$","examples":["evt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"type":{"const":"payment.succeeded"},"livemode":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"data":{"$ref":"#/components/schemas/Payment"}}}}}},"responses":{"2XX":{"description":"Acknowledged."}}}},"payment.failed":{"post":{"tags":["Webhook events"],"summary":"payment.failed","description":"Sent to your endpoint as a signed POST. Answer with any 2xx within 10 seconds; failures are retried with backoff for about a day. Verify the signature before trusting the body.","parameters":[{"name":"webhook-id","in":"header","required":true,"schema":{"type":"string","pattern":"^evt_[0-9a-f]{32}$","examples":["evt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"description":"Unique per event; use it to ignore duplicates."},{"name":"webhook-timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds. Reject deliveries older than a few minutes."},{"name":"webhook-signature","in":"header","required":true,"schema":{"type":"string"},"description":"`v1,` + base64 HMAC-SHA256 of `{webhook-id}.{webhook-timestamp}.{raw body}`, keyed with the base64-decoded part of your `whsec_` secret."}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["id","type","livemode","created_at","data"],"properties":{"id":{"type":"string","pattern":"^evt_[0-9a-f]{32}$","examples":["evt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"type":{"const":"payment.failed"},"livemode":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"data":{"$ref":"#/components/schemas/Payment"}}}}}},"responses":{"2XX":{"description":"Acknowledged."}}}},"refund.succeeded":{"post":{"tags":["Webhook events"],"summary":"refund.succeeded","description":"Sent to your endpoint as a signed POST. Answer with any 2xx within 10 seconds; failures are retried with backoff for about a day. Verify the signature before trusting the body.","parameters":[{"name":"webhook-id","in":"header","required":true,"schema":{"type":"string","pattern":"^evt_[0-9a-f]{32}$","examples":["evt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"description":"Unique per event; use it to ignore duplicates."},{"name":"webhook-timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds. Reject deliveries older than a few minutes."},{"name":"webhook-signature","in":"header","required":true,"schema":{"type":"string"},"description":"`v1,` + base64 HMAC-SHA256 of `{webhook-id}.{webhook-timestamp}.{raw body}`, keyed with the base64-decoded part of your `whsec_` secret."}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["id","type","livemode","created_at","data"],"properties":{"id":{"type":"string","pattern":"^evt_[0-9a-f]{32}$","examples":["evt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"type":{"const":"refund.succeeded"},"livemode":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"data":{"allOf":[{"$ref":"#/components/schemas/Payment"},{"type":"object","properties":{"refund_amount":{"type":"integer","minimum":0,"description":"The amount this refund returned."}}}]}}}}}},"responses":{"2XX":{"description":"Acknowledged."}}}},"subscription.active":{"post":{"tags":["Webhook events"],"summary":"subscription.active","description":"Sent to your endpoint as a signed POST. Answer with any 2xx within 10 seconds; failures are retried with backoff for about a day. Verify the signature before trusting the body.","parameters":[{"name":"webhook-id","in":"header","required":true,"schema":{"type":"string","pattern":"^evt_[0-9a-f]{32}$","examples":["evt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"description":"Unique per event; use it to ignore duplicates."},{"name":"webhook-timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds. Reject deliveries older than a few minutes."},{"name":"webhook-signature","in":"header","required":true,"schema":{"type":"string"},"description":"`v1,` + base64 HMAC-SHA256 of `{webhook-id}.{webhook-timestamp}.{raw body}`, keyed with the base64-decoded part of your `whsec_` secret."}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["id","type","livemode","created_at","data"],"properties":{"id":{"type":"string","pattern":"^evt_[0-9a-f]{32}$","examples":["evt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"type":{"const":"subscription.active"},"livemode":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"data":{"$ref":"#/components/schemas/Subscription"}}}}}},"responses":{"2XX":{"description":"Acknowledged."}}}},"subscription.renewed":{"post":{"tags":["Webhook events"],"summary":"subscription.renewed","description":"Sent to your endpoint as a signed POST. Answer with any 2xx within 10 seconds; failures are retried with backoff for about a day. Verify the signature before trusting the body.","parameters":[{"name":"webhook-id","in":"header","required":true,"schema":{"type":"string","pattern":"^evt_[0-9a-f]{32}$","examples":["evt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"description":"Unique per event; use it to ignore duplicates."},{"name":"webhook-timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds. Reject deliveries older than a few minutes."},{"name":"webhook-signature","in":"header","required":true,"schema":{"type":"string"},"description":"`v1,` + base64 HMAC-SHA256 of `{webhook-id}.{webhook-timestamp}.{raw body}`, keyed with the base64-decoded part of your `whsec_` secret."}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["id","type","livemode","created_at","data"],"properties":{"id":{"type":"string","pattern":"^evt_[0-9a-f]{32}$","examples":["evt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"type":{"const":"subscription.renewed"},"livemode":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"data":{"$ref":"#/components/schemas/Subscription"}}}}}},"responses":{"2XX":{"description":"Acknowledged."}}}},"subscription.on_hold":{"post":{"tags":["Webhook events"],"summary":"subscription.on_hold","description":"Sent to your endpoint as a signed POST. Answer with any 2xx within 10 seconds; failures are retried with backoff for about a day. Verify the signature before trusting the body.","parameters":[{"name":"webhook-id","in":"header","required":true,"schema":{"type":"string","pattern":"^evt_[0-9a-f]{32}$","examples":["evt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"description":"Unique per event; use it to ignore duplicates."},{"name":"webhook-timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds. Reject deliveries older than a few minutes."},{"name":"webhook-signature","in":"header","required":true,"schema":{"type":"string"},"description":"`v1,` + base64 HMAC-SHA256 of `{webhook-id}.{webhook-timestamp}.{raw body}`, keyed with the base64-decoded part of your `whsec_` secret."}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["id","type","livemode","created_at","data"],"properties":{"id":{"type":"string","pattern":"^evt_[0-9a-f]{32}$","examples":["evt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"type":{"const":"subscription.on_hold"},"livemode":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"data":{"$ref":"#/components/schemas/Subscription"}}}}}},"responses":{"2XX":{"description":"Acknowledged."}}}},"subscription.cancelled":{"post":{"tags":["Webhook events"],"summary":"subscription.cancelled","description":"Sent to your endpoint as a signed POST. Answer with any 2xx within 10 seconds; failures are retried with backoff for about a day. Verify the signature before trusting the body.","parameters":[{"name":"webhook-id","in":"header","required":true,"schema":{"type":"string","pattern":"^evt_[0-9a-f]{32}$","examples":["evt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"description":"Unique per event; use it to ignore duplicates."},{"name":"webhook-timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds. Reject deliveries older than a few minutes."},{"name":"webhook-signature","in":"header","required":true,"schema":{"type":"string"},"description":"`v1,` + base64 HMAC-SHA256 of `{webhook-id}.{webhook-timestamp}.{raw body}`, keyed with the base64-decoded part of your `whsec_` secret."}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["id","type","livemode","created_at","data"],"properties":{"id":{"type":"string","pattern":"^evt_[0-9a-f]{32}$","examples":["evt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"type":{"const":"subscription.cancelled"},"livemode":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"data":{"$ref":"#/components/schemas/Subscription"}}}}}},"responses":{"2XX":{"description":"Acknowledged."}}}}},"components":{"securitySchemes":{"secretKey":{"type":"http","scheme":"bearer","description":"Your secret key: `sk_live_…` or `sk_test_…`."}},"parameters":{"Limit":{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},"Cursor":{"name":"cursor","in":"query","schema":{"type":"string"},"description":"The `next_cursor` of the previous page."},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"Retrying with the same key returns the first response instead of creating a duplicate."}},"responses":{"Error":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","examples":["NOT_FOUND","INVALID_REQUEST","CURRENCY_NOT_SUPPORTED"]},"message":{"type":"string"}}},"Currency":{"enum":["AED"]},"Metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"maxProperties":50,"description":"Your own key-value pairs, returned on the object and its events."},"PaymentStatus":{"enum":["processing","succeeded","failed","refunded","partially_refunded"]},"SubscriptionStatus":{"enum":["active","on_hold","cancelled"]},"EventType":{"enum":["payment.succeeded","payment.failed","refund.succeeded","subscription.active","subscription.renewed","subscription.on_hold","subscription.cancelled"]},"Account":{"type":"object","required":["object","business_name","support_email","livemode","payments_enabled","currencies"],"properties":{"object":{"const":"account"},"business_name":{"type":["string","null"]},"support_email":{"type":["string","null"]},"livemode":{"type":"boolean"},"payments_enabled":{"type":"boolean"},"currencies":{"type":"array","items":{"$ref":"#/components/schemas/Currency"}}}},"Product":{"type":"object","required":["object","product_id","name","description","price","currency","billing","billing_interval","interval_count","status","metadata","created_at","updated_at"],"properties":{"object":{"const":"product"},"product_id":{"type":"string","pattern":"^pdt_[0-9a-f]{32}$","examples":["pdt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"name":{"type":"string"},"description":{"type":"string"},"price":{"type":"integer","minimum":0,"description":"Integer amount in AED fils. For example, 34900 means AED 349.00."},"currency":{"$ref":"#/components/schemas/Currency"},"billing":{"enum":["one_time","recurring"]},"billing_interval":{"enum":["day","week","month","year",null]},"interval_count":{"type":["integer","null"],"minimum":1,"maximum":365},"status":{"enum":["active","draft","archived"]},"metadata":{"$ref":"#/components/schemas/Metadata"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}}},"ProductCreate":{"type":"object","required":["name","price","currency"],"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":5000},"price":{"type":"integer","minimum":0,"description":"Integer amount in AED fils. For example, 34900 means AED 349.00."},"currency":{"$ref":"#/components/schemas/Currency"},"billing":{"enum":["one_time","recurring"],"default":"one_time"},"billing_interval":{"enum":["day","week","month","year"],"description":"Required for recurring products."},"interval_count":{"type":"integer","minimum":1,"maximum":365,"default":1,"description":"Bill every N intervals."},"status":{"enum":["active","draft","archived"],"default":"active"},"metadata":{"$ref":"#/components/schemas/Metadata"}}},"ProductUpdate":{"type":"object","description":"Any product field. Include `price` when changing `currency`.","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":5000},"price":{"type":"integer","minimum":0,"description":"Integer amount in AED fils. For example, 34900 means AED 349.00."},"currency":{"$ref":"#/components/schemas/Currency"},"billing":{"enum":["one_time","recurring"]},"billing_interval":{"enum":["day","week","month","year",null]},"interval_count":{"type":["integer","null"],"minimum":1,"maximum":365},"status":{"enum":["active","draft","archived"]},"metadata":{"$ref":"#/components/schemas/Metadata"}}},"Customer":{"type":"object","required":["object","customer_id","name","email","phone_number","metadata","created_at"],"properties":{"object":{"const":"customer"},"customer_id":{"type":"string","pattern":"^cus_[0-9a-f]{32}$","examples":["cus_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"name":{"type":"string"},"email":{"type":"string","format":"email"},"phone_number":{"type":["string","null"]},"metadata":{"$ref":"#/components/schemas/Metadata"},"created_at":{"type":"string","format":"date-time"}}},"CustomerCreate":{"type":"object","required":["email","name"],"properties":{"email":{"type":"string","format":"email"},"name":{"type":"string","minLength":1,"maxLength":200},"phone_number":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$","description":"E.164, like +971501234567."},"metadata":{"$ref":"#/components/schemas/Metadata"}}},"CustomerUpdate":{"type":"object","properties":{"email":{"type":"string","format":"email"},"name":{"type":"string","minLength":1,"maxLength":200},"phone_number":{"type":["string","null"],"pattern":"^\\+[1-9]\\d{6,14}$"},"metadata":{"$ref":"#/components/schemas/Metadata"}}},"ProductCartItem":{"oneOf":[{"title":"Saved product","type":"object","required":["product_id"],"properties":{"product_id":{"type":"string","pattern":"^pdt_[0-9a-f]{32}$","examples":["pdt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"quantity":{"type":"integer","minimum":1,"maximum":100,"default":1}}},{"title":"Inline one-time item","type":"object","required":["name","unit_amount","currency"],"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"unit_amount":{"type":"integer","minimum":0,"description":"Integer amount in AED fils. For example, 34900 means AED 349.00."},"currency":{"$ref":"#/components/schemas/Currency"},"quantity":{"type":"integer","minimum":1,"maximum":100,"default":1}}}]},"CheckoutSessionCreate":{"type":"object","required":["product_cart"],"properties":{"product_cart":{"type":"array","minItems":1,"maxItems":50,"items":{"$ref":"#/components/schemas/ProductCartItem"},"description":"One-time items in one currency, or exactly one recurring product."},"customer":{"type":"object","description":"Prefills the checkout form.","properties":{"email":{"type":"string","format":"email"},"name":{"type":"string","maxLength":200},"phone_number":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"}}},"return_url":{"type":"string","format":"uri","description":"Where the customer lands afterwards; `payment_id`, `status` and `session_id` are appended."},"metadata":{"$ref":"#/components/schemas/Metadata"}}},"CheckoutSession":{"type":"object","required":["object","session_id","kind","status","checkout_url","total_amount","currency","product_cart","customer","return_url","payment_id","subscription_id","metadata","livemode","created_at","expires_at","completed_at"],"properties":{"object":{"const":"checkout_session"},"session_id":{"type":"string","pattern":"^cks_[0-9a-f]{32}$","examples":["cks_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"kind":{"enum":["payment","subscription"]},"status":{"enum":["open","complete","expired"]},"checkout_url":{"type":["string","null"],"format":"uri","description":"Redirect the customer here while the session is open."},"total_amount":{"type":"integer","minimum":0,"description":"Integer amount in AED fils. For example, 34900 means AED 349.00."},"currency":{"$ref":"#/components/schemas/Currency"},"product_cart":{"type":"array","items":{"type":"object","required":["product_id","name","quantity","unit_amount"],"properties":{"product_id":{"oneOf":[{"type":"string","pattern":"^pdt_[0-9a-f]{32}$","examples":["pdt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},{"type":"null"}]},"name":{"type":"string"},"quantity":{"type":"integer"},"unit_amount":{"type":"integer","minimum":0,"description":"Integer amount in AED fils. For example, 34900 means AED 349.00."}}}},"customer":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone_number":{"type":["string","null"]}}},"return_url":{"type":["string","null"]},"payment_id":{"oneOf":[{"type":"string","pattern":"^pay_[0-9a-f]{32}$","examples":["pay_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},{"type":"null"}]},"subscription_id":{"oneOf":[{"type":"string","pattern":"^sub_[0-9a-f]{32}$","examples":["sub_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},{"type":"null"}]},"metadata":{"$ref":"#/components/schemas/Metadata"},"livemode":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"}}},"Payment":{"type":"object","required":["object","payment_id","status","total_amount","refunded_amount","fee_amount","net_amount","currency","description","customer","checkout_session_id","subscription_id","billing_reason","metadata","livemode","created_at","paid_at"],"properties":{"object":{"const":"payment"},"payment_id":{"type":"string","pattern":"^pay_[0-9a-f]{32}$","examples":["pay_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"status":{"$ref":"#/components/schemas/PaymentStatus"},"total_amount":{"type":"integer","minimum":0,"description":"Integer amount in AED fils. For example, 34900 means AED 349.00."},"refunded_amount":{"type":"integer","minimum":0,"description":"Integer amount in AED fils. For example, 34900 means AED 349.00."},"fee_amount":{"type":["integer","null"],"minimum":0,"description":"Utopia's processing fee on this payment, in the currency's minor unit. Fixed when the payment succeeds and kept after a refund. Null while the payment is processing or if it failed."},"net_amount":{"type":["integer","null"],"description":"What you keep: `total_amount` − `refunded_amount` − `fee_amount`, in the currency's minor unit. Negative when a refund returned more than was left after the fee. Null while the payment is processing or if it failed."},"currency":{"$ref":"#/components/schemas/Currency"},"description":{"type":"string"},"customer":{"type":"object","properties":{"customer_id":{"oneOf":[{"type":"string","pattern":"^cus_[0-9a-f]{32}$","examples":["cus_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},{"type":"null"}]},"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone_number":{"type":["string","null"]}}},"checkout_session_id":{"oneOf":[{"type":"string","pattern":"^cks_[0-9a-f]{32}$","examples":["cks_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},{"type":"null"}]},"subscription_id":{"oneOf":[{"type":"string","pattern":"^sub_[0-9a-f]{32}$","examples":["sub_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},{"type":"null"}]},"billing_reason":{"enum":["payment","subscription_create","subscription_cycle"],"description":"Why the payment exists: a checkout, a subscription's first payment, or a renewal."},"metadata":{"$ref":"#/components/schemas/Metadata"},"livemode":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"paid_at":{"type":["string","null"],"format":"date-time"}}},"Subscription":{"type":"object","required":["object","subscription_id","status","product_id","name","quantity","recurring_amount","currency","billing_interval","interval_count","customer","payment_method","current_period_start","next_billing_date","cancel_at_period_end","cancelled_at","cancellation_reason","failed_payment_attempts","next_retry_at","checkout_session_id","metadata","livemode","created_at"],"properties":{"object":{"const":"subscription"},"subscription_id":{"type":"string","pattern":"^sub_[0-9a-f]{32}$","examples":["sub_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"status":{"$ref":"#/components/schemas/SubscriptionStatus"},"product_id":{"type":"string","pattern":"^pdt_[0-9a-f]{32}$","examples":["pdt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"name":{"type":"string"},"quantity":{"type":"integer"},"recurring_amount":{"type":"integer","minimum":0,"description":"Integer amount in AED fils. For example, 34900 means AED 349.00."},"currency":{"$ref":"#/components/schemas/Currency"},"billing_interval":{"enum":["day","week","month","year"]},"interval_count":{"type":"integer"},"customer":{"type":"object","properties":{"customer_id":{"oneOf":[{"type":"string","pattern":"^cus_[0-9a-f]{32}$","examples":["cus_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},{"type":"null"}]},"name":{"type":["string","null"]},"email":{"type":"string"}}},"payment_method":{"oneOf":[{"type":"object","properties":{"brand":{"type":["string","null"]},"last4":{"type":"string"},"exp_month":{"type":["integer","null"]},"exp_year":{"type":["integer","null"]}}},{"type":"null"}]},"current_period_start":{"type":"string","format":"date-time"},"next_billing_date":{"type":"string","format":"date-time"},"cancel_at_period_end":{"type":"boolean"},"cancelled_at":{"type":["string","null"],"format":"date-time"},"cancellation_reason":{"enum":["requested","payment_failed","gateway_canceled","merchant_rejected",null]},"failed_payment_attempts":{"type":"integer"},"next_retry_at":{"type":["string","null"],"format":"date-time"},"checkout_session_id":{"oneOf":[{"type":"string","pattern":"^cks_[0-9a-f]{32}$","examples":["cks_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},{"type":"null"}]},"metadata":{"$ref":"#/components/schemas/Metadata"},"livemode":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}}},"SubscriptionUpdate":{"type":"object","properties":{"cancel_at_period_end":{"type":"boolean"},"status":{"const":"cancelled","description":"Cancel immediately."},"metadata":{"$ref":"#/components/schemas/Metadata"}}},"WebhookEndpoint":{"type":"object","required":["object","webhook_id","url","description","event_types","disabled","livemode","created_at"],"properties":{"object":{"const":"webhook"},"webhook_id":{"type":"string","pattern":"^wh_[0-9a-f]{32}$","examples":["wh_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"url":{"type":"string","format":"uri"},"description":{"type":"string"},"event_types":{"type":"array","items":{"$ref":"#/components/schemas/EventType"},"description":"Empty means every event."},"disabled":{"type":"boolean"},"livemode":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}}},"WebhookEndpointCreate":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"HTTPS URL on a public address."},"description":{"type":"string","maxLength":500},"event_types":{"type":"array","items":{"$ref":"#/components/schemas/EventType"}},"disabled":{"type":"boolean","default":false}}},"WebhookEndpointUpdate":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"description":{"type":"string","maxLength":500},"event_types":{"type":"array","items":{"$ref":"#/components/schemas/EventType"}},"disabled":{"type":"boolean"}}},"Event":{"type":"object","required":["object","event_id","type","livemode","created_at","data"],"properties":{"object":{"const":"event"},"event_id":{"type":"string","pattern":"^evt_[0-9a-f]{32}$","examples":["evt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c"]},"type":{"type":"string"},"livemode":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object"}}}}}}