{
  "openapi": "3.1.0",
  "info": {
    "title": "Platico API",
    "version": "0.2.0",
    "description": "Platico is a Stripe-shaped, developer-first payment platform for Serbia\nand the Western Balkans. This document describes the public,\nAPI-key-authed merchant surface. Server-side language SDKs\n(Node, Python, Ruby, Go) generated from this spec.\n\nAuthentication: `Authorization: Bearer sk_test_...` (sandbox) or\n`sk_live_...` (production). Keys are merchant-scoped and rotatable\nfrom the dashboard.",
    "contact": {
      "name": "Platico Support",
      "email": "support@platico.rs",
      "url": "https://platico.rs/support"
    },
    "license": {
      "name": "Proprietary — readable, not redistributable",
      "url": "https://platico.rs/license"
    },
    "termsOfService": "https://platico.rs/terms"
  },
  "servers": [
    {
      "url": "https://api.platico.rs",
      "description": "Production — real charges, real money. Use sk_live_* keys."
    },
    {
      "url": "https://api.sandbox.platico.rs",
      "description": "Sandbox — test charges only. Use sk_test_* keys."
    }
  ],
  "tags": [
    {
      "name": "PaymentIntents",
      "description": "Money-movement primitive. Created by a merchant, confirmed with a card token from platico.js, optionally 3-D Secure verified, then settled."
    },
    {
      "name": "Customers",
      "description": "Saved customer records. Useful for attaching reusable payment methods, sending receipts, and looking up a buyer across PaymentIntents."
    },
    {
      "name": "PaymentMethods",
      "description": "Tokenized payment methods (cards today; account-based methods later). Attached to a Customer or used directly on a PaymentIntent."
    },
    {
      "name": "Products",
      "description": "Catalog items the merchant sells. Owns one or more Prices. Deactivated (not hard-deleted) via DELETE; reactivated by updating `active: true`."
    },
    {
      "name": "Prices",
      "description": "Amount + currency attached to a Product. One-time or recurring. Immutable except for `active` and `metadata` — to change amount or currency, create a new Price."
    },
    {
      "name": "Refunds",
      "description": "Reverse a settled PaymentIntent, in full or in part. Cannot refund a PaymentIntent with an open dispute."
    },
    {
      "name": "Disputes",
      "description": "Chargebacks opened by a cardholder via their bank. Read-only on the API surface — disputes are created by the processor, not the merchant."
    },
    {
      "name": "Events",
      "description": "Immutable records of things that happened (a PaymentIntent succeeded, a refund settled). The same events drive outgoing webhooks. Read-only; scoped to the API key's mode."
    },
    {
      "name": "WebhookEndpoints",
      "description": "Destinations Platico delivers signed events to. Create and manage them from the dashboard or the API. The signing secret is returned once on create/roll."
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/v1/payment_intents": {
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "paymentIntents.create",
        "summary": "Create a PaymentIntent",
        "tags": [
          "PaymentIntents"
        ],
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaymentIntentCreateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created PaymentIntent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentIntent"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "paymentIntents.list",
        "summary": "List PaymentIntents",
        "tags": [
          "PaymentIntents"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "description": "Page size. 1–100.",
              "example": 10,
              "default": 10,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "description": "Page size. 1–100."
          },
          {
            "in": "query",
            "name": "starting_after",
            "schema": {
              "description": "Walk forward in time from this PI id (exclusive).",
              "example": "pi_test_example",
              "type": "string"
            },
            "description": "Walk forward in time from this PI id (exclusive)."
          },
          {
            "in": "query",
            "name": "ending_before",
            "schema": {
              "description": "Walk backward in time from this PI id (exclusive).",
              "type": "string"
            },
            "description": "Walk backward in time from this PI id (exclusive)."
          },
          {
            "in": "query",
            "name": "customer",
            "schema": {
              "description": "Filter to a single customer.",
              "type": "string"
            },
            "description": "Filter to a single customer."
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "description": "Filter to a single lifecycle state.",
              "type": "string",
              "enum": [
                "requires_payment_method",
                "requires_confirmation",
                "requires_action",
                "processing",
                "requires_capture",
                "succeeded",
                "canceled"
              ]
            },
            "description": "Filter to a single lifecycle state."
          }
        ],
        "responses": {
          "200": {
            "description": "Cursor-paginated list of PaymentIntents.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Cursor-paginated list. Use `starting_after`/`ending_before` query params with the id of an item from `data` to walk pages.",
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PaymentIntent"
                      }
                    },
                    "has_more": {
                      "description": "True if there are more pages beyond this one. Paginate with `starting_after`.",
                      "example": false,
                      "type": "boolean"
                    },
                    "url": {
                      "description": "Canonical path of this list endpoint.",
                      "example": "/v1/payment_intents",
                      "type": "string"
                    }
                  },
                  "required": [
                    "object",
                    "data",
                    "has_more",
                    "url"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/payment_intents/{id}": {
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "paymentIntents.retrieve",
        "summary": "Retrieve a PaymentIntent",
        "tags": [
          "PaymentIntents"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "PaymentIntent id, prefixed `pi_`.",
              "example": "pi_test_example",
              "type": "string",
              "pattern": "^pi_[a-z0-9]+$"
            },
            "required": true,
            "description": "PaymentIntent id, prefixed `pi_`."
          }
        ],
        "responses": {
          "200": {
            "description": "The PaymentIntent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentIntent"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "paymentIntents.update",
        "summary": "Update a PaymentIntent (description + metadata only)",
        "tags": [
          "PaymentIntents"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "PaymentIntent id, prefixed `pi_`.",
              "example": "pi_test_example",
              "type": "string",
              "pattern": "^pi_[a-z0-9]+$"
            },
            "required": true,
            "description": "PaymentIntent id, prefixed `pi_`."
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaymentIntentUpdateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated PaymentIntent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentIntent"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/payment_intents/{id}/confirm": {
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "paymentIntents.confirm",
        "summary": "Confirm a PaymentIntent",
        "description": "Confirms a PaymentIntent. Pass `payment_method_token` to charge the card directly via AllSecure, or `payment_method_type: \"payment_link\"` to issue a hosted-page URL the customer pays on (returned as `next_action.redirect_to_url`). The two are mutually exclusive; sending both returns 400.",
        "tags": [
          "PaymentIntents"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "PaymentIntent id, prefixed `pi_`.",
              "example": "pi_test_example",
              "type": "string",
              "pattern": "^pi_[a-z0-9]+$"
            },
            "required": true,
            "description": "PaymentIntent id, prefixed `pi_`."
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaymentIntentConfirmBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "PI after confirm attempt (may require 3-D Secure or a hosted-page redirect).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentIntent"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/payment_intents/{id}/capture": {
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "paymentIntents.capture",
        "summary": "Capture a previously preauthorized PaymentIntent",
        "tags": [
          "PaymentIntents"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "PaymentIntent id, prefixed `pi_`.",
              "example": "pi_test_example",
              "type": "string",
              "pattern": "^pi_[a-z0-9]+$"
            },
            "required": true,
            "description": "PaymentIntent id, prefixed `pi_`."
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "description": "Empty body.",
                "type": "object",
                "properties": {}
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The captured PaymentIntent (now `succeeded`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentIntent"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/payment_intents/{id}/cancel": {
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "paymentIntents.cancel",
        "summary": "Cancel a PaymentIntent",
        "tags": [
          "PaymentIntents"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "PaymentIntent id, prefixed `pi_`.",
              "example": "pi_test_example",
              "type": "string",
              "pattern": "^pi_[a-z0-9]+$"
            },
            "required": true,
            "description": "PaymentIntent id, prefixed `pi_`."
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "description": "Empty body.",
                "type": "object",
                "properties": {}
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The canceled PaymentIntent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentIntent"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/customers": {
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "customers.create",
        "summary": "Create a Customer",
        "tags": [
          "Customers"
        ],
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerCreateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created Customer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "customers.list",
        "summary": "List Customers",
        "tags": [
          "Customers"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "description": "Page size. 1–100.",
              "example": 10,
              "default": 10,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "description": "Page size. 1–100."
          },
          {
            "in": "query",
            "name": "starting_after",
            "schema": {
              "description": "Cursor — exclusive.",
              "example": "cus_test_example",
              "type": "string"
            },
            "description": "Cursor — exclusive."
          },
          {
            "in": "query",
            "name": "ending_before",
            "schema": {
              "description": "Cursor — exclusive.",
              "type": "string"
            },
            "description": "Cursor — exclusive."
          },
          {
            "in": "query",
            "name": "email",
            "schema": {
              "description": "Filter to an exact email.",
              "type": "string",
              "format": "email",
              "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
            },
            "description": "Filter to an exact email."
          },
          {
            "in": "query",
            "name": "include_deleted",
            "schema": {
              "description": "If true, soft-deleted customers are included.",
              "example": false,
              "type": "boolean"
            },
            "description": "If true, soft-deleted customers are included."
          }
        ],
        "responses": {
          "200": {
            "description": "Cursor-paginated list of Customers.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Cursor-paginated list. Use `starting_after`/`ending_before` query params with the id of an item from `data` to walk pages.",
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Customer"
                      }
                    },
                    "has_more": {
                      "description": "True if there are more pages beyond this one. Paginate with `starting_after`.",
                      "example": false,
                      "type": "boolean"
                    },
                    "url": {
                      "description": "Canonical path of this list endpoint.",
                      "example": "/v1/customers",
                      "type": "string"
                    }
                  },
                  "required": [
                    "object",
                    "data",
                    "has_more",
                    "url"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/customers/{id}": {
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "customers.retrieve",
        "summary": "Retrieve a Customer",
        "tags": [
          "Customers"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "Customer id, prefixed `cus_`.",
              "example": "cus_test_example",
              "type": "string",
              "pattern": "^cus_[a-z0-9]+$"
            },
            "required": true,
            "description": "Customer id, prefixed `cus_`."
          },
          {
            "in": "query",
            "name": "include_deleted",
            "schema": {
              "description": "If true, return the customer even if soft-deleted.",
              "example": false,
              "type": "boolean"
            },
            "description": "If true, return the customer even if soft-deleted."
          }
        ],
        "responses": {
          "200": {
            "description": "The Customer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "customers.update",
        "summary": "Update a Customer",
        "tags": [
          "Customers"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "Customer id, prefixed `cus_`.",
              "example": "cus_test_example",
              "type": "string",
              "pattern": "^cus_[a-z0-9]+$"
            },
            "required": true,
            "description": "Customer id, prefixed `cus_`."
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerUpdateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated Customer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "customers.delete",
        "summary": "Delete a Customer (soft)",
        "tags": [
          "Customers"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "Customer id, prefixed `cus_`.",
              "example": "cus_test_example",
              "type": "string",
              "pattern": "^cus_[a-z0-9]+$"
            },
            "required": true,
            "description": "Customer id, prefixed `cus_`."
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "responses": {
          "200": {
            "description": "The soft-deleted Customer (now with `deleted` set).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/payment_methods": {
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "paymentMethods.create",
        "summary": "Create (register) a PaymentMethod",
        "tags": [
          "PaymentMethods"
        ],
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaymentMethodCreateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created PaymentMethod.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentMethod"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "paymentMethods.list",
        "summary": "List PaymentMethods",
        "tags": [
          "PaymentMethods"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "description": "Page size. 1–100.",
              "example": 10,
              "default": 10,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "description": "Page size. 1–100."
          },
          {
            "in": "query",
            "name": "starting_after",
            "schema": {
              "example": "pm_test_example",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "ending_before",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "customer",
            "schema": {
              "description": "Filter to a single customer.",
              "type": "string"
            },
            "description": "Filter to a single customer."
          },
          {
            "in": "query",
            "name": "type",
            "schema": {
              "description": "Filter by PaymentMethod kind.",
              "type": "string",
              "enum": [
                "card"
              ]
            },
            "description": "Filter by PaymentMethod kind."
          }
        ],
        "responses": {
          "200": {
            "description": "Cursor-paginated list of PaymentMethods.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Cursor-paginated list. Use `starting_after`/`ending_before` query params with the id of an item from `data` to walk pages.",
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PaymentMethod"
                      }
                    },
                    "has_more": {
                      "description": "True if there are more pages beyond this one. Paginate with `starting_after`.",
                      "example": false,
                      "type": "boolean"
                    },
                    "url": {
                      "description": "Canonical path of this list endpoint.",
                      "example": "/v1/payment_methods",
                      "type": "string"
                    }
                  },
                  "required": [
                    "object",
                    "data",
                    "has_more",
                    "url"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/payment_methods/{id}": {
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "paymentMethods.retrieve",
        "summary": "Retrieve a PaymentMethod",
        "tags": [
          "PaymentMethods"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "PaymentMethod id, prefixed `pm_`.",
              "example": "pm_test_example",
              "type": "string",
              "pattern": "^pm_[a-z0-9]+$"
            },
            "required": true,
            "description": "PaymentMethod id, prefixed `pm_`."
          }
        ],
        "responses": {
          "200": {
            "description": "The PaymentMethod.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentMethod"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "paymentMethods.update",
        "summary": "Update a PaymentMethod (metadata only)",
        "tags": [
          "PaymentMethods"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "PaymentMethod id, prefixed `pm_`.",
              "example": "pm_test_example",
              "type": "string",
              "pattern": "^pm_[a-z0-9]+$"
            },
            "required": true,
            "description": "PaymentMethod id, prefixed `pm_`."
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaymentMethodUpdateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated PaymentMethod.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentMethod"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/payment_methods/{id}/attach": {
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "paymentMethods.attach",
        "summary": "Attach a PaymentMethod to a Customer",
        "tags": [
          "PaymentMethods"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "PaymentMethod id, prefixed `pm_`.",
              "example": "pm_test_example",
              "type": "string",
              "pattern": "^pm_[a-z0-9]+$"
            },
            "required": true,
            "description": "PaymentMethod id, prefixed `pm_`."
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaymentMethodAttachBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The attached PaymentMethod.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentMethod"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/payment_methods/{id}/detach": {
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "paymentMethods.detach",
        "summary": "Detach a PaymentMethod from its Customer",
        "tags": [
          "PaymentMethods"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "PaymentMethod id, prefixed `pm_`.",
              "example": "pm_test_example",
              "type": "string",
              "pattern": "^pm_[a-z0-9]+$"
            },
            "required": true,
            "description": "PaymentMethod id, prefixed `pm_`."
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "description": "Empty body.",
                "type": "object",
                "properties": {}
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The detached PaymentMethod.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentMethod"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/products": {
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "products.create",
        "summary": "Create a Product",
        "tags": [
          "Products"
        ],
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductCreateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created Product.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "products.list",
        "summary": "List Products",
        "tags": [
          "Products"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "active",
            "schema": {
              "description": "Filter to active or inactive products.",
              "example": true,
              "type": "boolean"
            },
            "description": "Filter to active or inactive products."
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "description": "Page size. 1–100.",
              "example": 10,
              "default": 10,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "description": "Page size. 1–100."
          },
          {
            "in": "query",
            "name": "starting_after",
            "schema": {
              "description": "Cursor — exclusive.",
              "example": "prod_test_example",
              "type": "string"
            },
            "description": "Cursor — exclusive."
          },
          {
            "in": "query",
            "name": "ending_before",
            "schema": {
              "description": "Cursor — exclusive.",
              "type": "string"
            },
            "description": "Cursor — exclusive."
          }
        ],
        "responses": {
          "200": {
            "description": "Cursor-paginated list of Products.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Cursor-paginated list. Use `starting_after`/`ending_before` query params with the id of an item from `data` to walk pages.",
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Product"
                      }
                    },
                    "has_more": {
                      "description": "True if there are more pages beyond this one. Paginate with `starting_after`.",
                      "example": false,
                      "type": "boolean"
                    },
                    "url": {
                      "description": "Canonical path of this list endpoint.",
                      "example": "/v1/products",
                      "type": "string"
                    }
                  },
                  "required": [
                    "object",
                    "data",
                    "has_more",
                    "url"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/products/{id}": {
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "products.retrieve",
        "summary": "Retrieve a Product",
        "tags": [
          "Products"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "Product id, prefixed `prod_`.",
              "example": "prod_test_example",
              "type": "string",
              "pattern": "^prod_[a-z0-9]+$"
            },
            "required": true,
            "description": "Product id, prefixed `prod_`."
          }
        ],
        "responses": {
          "200": {
            "description": "The Product.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "products.update",
        "summary": "Update a Product",
        "tags": [
          "Products"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "Product id, prefixed `prod_`.",
              "example": "prod_test_example",
              "type": "string",
              "pattern": "^prod_[a-z0-9]+$"
            },
            "required": true,
            "description": "Product id, prefixed `prod_`."
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductUpdateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated Product.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "products.delete",
        "summary": "Deactivate a Product",
        "tags": [
          "Products"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "Product id, prefixed `prod_`.",
              "example": "prod_test_example",
              "type": "string",
              "pattern": "^prod_[a-z0-9]+$"
            },
            "required": true,
            "description": "Product id, prefixed `prod_`."
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "responses": {
          "200": {
            "description": "The deactivated Product (`active` is now false).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/prices": {
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "prices.create",
        "summary": "Create a Price",
        "tags": [
          "Prices"
        ],
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PriceCreateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created Price.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Price"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "prices.list",
        "summary": "List Prices",
        "tags": [
          "Prices"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "product",
            "schema": {
              "description": "Filter to Prices belonging to this Product id.",
              "example": "prod_test_example",
              "type": "string"
            },
            "description": "Filter to Prices belonging to this Product id."
          },
          {
            "in": "query",
            "name": "active",
            "schema": {
              "description": "Filter by active state.",
              "example": true,
              "type": "boolean"
            },
            "description": "Filter by active state."
          },
          {
            "in": "query",
            "name": "type",
            "schema": {
              "type": "string",
              "enum": [
                "one_time",
                "recurring"
              ]
            }
          },
          {
            "in": "query",
            "name": "currency",
            "schema": {
              "type": "string",
              "enum": [
                "rsd",
                "eur",
                "bam"
              ]
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "description": "Page size. 1–100.",
              "example": 10,
              "default": 10,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "description": "Page size. 1–100."
          },
          {
            "in": "query",
            "name": "starting_after",
            "schema": {
              "description": "Cursor — exclusive.",
              "example": "price_test_example",
              "type": "string"
            },
            "description": "Cursor — exclusive."
          },
          {
            "in": "query",
            "name": "ending_before",
            "schema": {
              "description": "Cursor — exclusive.",
              "type": "string"
            },
            "description": "Cursor — exclusive."
          }
        ],
        "responses": {
          "200": {
            "description": "Cursor-paginated list of Prices.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Cursor-paginated list. Use `starting_after`/`ending_before` query params with the id of an item from `data` to walk pages.",
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Price"
                      }
                    },
                    "has_more": {
                      "description": "True if there are more pages beyond this one. Paginate with `starting_after`.",
                      "example": false,
                      "type": "boolean"
                    },
                    "url": {
                      "description": "Canonical path of this list endpoint.",
                      "example": "/v1/prices",
                      "type": "string"
                    }
                  },
                  "required": [
                    "object",
                    "data",
                    "has_more",
                    "url"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/prices/{id}": {
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "prices.retrieve",
        "summary": "Retrieve a Price",
        "tags": [
          "Prices"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "Price id, prefixed `price_`.",
              "example": "price_test_example",
              "type": "string",
              "pattern": "^price_[a-z0-9]+$"
            },
            "required": true,
            "description": "Price id, prefixed `price_`."
          }
        ],
        "responses": {
          "200": {
            "description": "The Price.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Price"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "prices.update",
        "summary": "Update a Price (active + metadata only)",
        "tags": [
          "Prices"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "Price id, prefixed `price_`.",
              "example": "price_test_example",
              "type": "string",
              "pattern": "^price_[a-z0-9]+$"
            },
            "required": true,
            "description": "Price id, prefixed `price_`."
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PriceUpdateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated Price.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Price"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/refunds": {
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "refunds.create",
        "summary": "Create a Refund",
        "tags": [
          "Refunds"
        ],
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RefundCreateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created Refund.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refund"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "refunds.list",
        "summary": "List Refunds",
        "tags": [
          "Refunds"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "description": "Page size. 1–100.",
              "example": 10,
              "default": 10,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "description": "Page size. 1–100."
          },
          {
            "in": "query",
            "name": "starting_after",
            "schema": {
              "example": "re_test_example",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "ending_before",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "payment_intent",
            "schema": {
              "description": "Filter to refunds against a single PaymentIntent.",
              "example": "pi_test_example",
              "type": "string"
            },
            "description": "Filter to refunds against a single PaymentIntent."
          }
        ],
        "responses": {
          "200": {
            "description": "Cursor-paginated list of Refunds.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Cursor-paginated list. Use `starting_after`/`ending_before` query params with the id of an item from `data` to walk pages.",
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Refund"
                      }
                    },
                    "has_more": {
                      "description": "True if there are more pages beyond this one. Paginate with `starting_after`.",
                      "example": false,
                      "type": "boolean"
                    },
                    "url": {
                      "description": "Canonical path of this list endpoint.",
                      "example": "/v1/refunds",
                      "type": "string"
                    }
                  },
                  "required": [
                    "object",
                    "data",
                    "has_more",
                    "url"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/refunds/{id}": {
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "refunds.retrieve",
        "summary": "Retrieve a Refund",
        "tags": [
          "Refunds"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "Refund id, prefixed `re_`.",
              "example": "re_test_example",
              "type": "string",
              "pattern": "^re_[A-Za-z0-9]+$"
            },
            "required": true,
            "description": "Refund id, prefixed `re_`."
          }
        ],
        "responses": {
          "200": {
            "description": "The Refund.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refund"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/disputes": {
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "disputes.list",
        "summary": "List Disputes",
        "tags": [
          "Disputes"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "description": "Page size. 1–100.",
              "example": 10,
              "default": 10,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "description": "Page size. 1–100."
          },
          {
            "in": "query",
            "name": "starting_after",
            "schema": {
              "example": "dp_test_example",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "ending_before",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "description": "Filter to a single lifecycle state.",
              "type": "string",
              "enum": [
                "needs_response",
                "warning_closed",
                "won",
                "lost"
              ]
            },
            "description": "Filter to a single lifecycle state."
          },
          {
            "in": "query",
            "name": "payment_intent",
            "schema": {
              "description": "Filter to disputes against a single PaymentIntent.",
              "example": "pi_test_example",
              "type": "string"
            },
            "description": "Filter to disputes against a single PaymentIntent."
          }
        ],
        "responses": {
          "200": {
            "description": "Cursor-paginated list of Disputes.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Cursor-paginated list. Use `starting_after`/`ending_before` query params with the id of an item from `data` to walk pages.",
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Dispute"
                      }
                    },
                    "has_more": {
                      "description": "True if there are more pages beyond this one. Paginate with `starting_after`.",
                      "example": false,
                      "type": "boolean"
                    },
                    "url": {
                      "description": "Canonical path of this list endpoint.",
                      "example": "/v1/disputes",
                      "type": "string"
                    }
                  },
                  "required": [
                    "object",
                    "data",
                    "has_more",
                    "url"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/disputes/{id}": {
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "disputes.retrieve",
        "summary": "Retrieve a Dispute",
        "tags": [
          "Disputes"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "Dispute id, prefixed `dp_`.",
              "example": "dp_test_example",
              "type": "string",
              "pattern": "^dp_[A-Za-z0-9]+$"
            },
            "required": true,
            "description": "Dispute id, prefixed `dp_`."
          }
        ],
        "responses": {
          "200": {
            "description": "The Dispute.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Dispute"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/events": {
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "events.list",
        "summary": "List Events",
        "tags": [
          "Events"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "description": "Page size. 1–100.",
              "example": 10,
              "default": 10,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "description": "Page size. 1–100."
          },
          {
            "in": "query",
            "name": "starting_after",
            "schema": {
              "description": "Cursor — exclusive.",
              "example": "evt_test_example",
              "type": "string"
            },
            "description": "Cursor — exclusive."
          },
          {
            "in": "query",
            "name": "ending_before",
            "schema": {
              "description": "Cursor — exclusive.",
              "type": "string"
            },
            "description": "Cursor — exclusive."
          },
          {
            "in": "query",
            "name": "type",
            "schema": {
              "description": "Filter to a single event type, e.g. `payment_intent.succeeded`.",
              "example": "payment_intent.succeeded",
              "type": "string"
            },
            "description": "Filter to a single event type, e.g. `payment_intent.succeeded`."
          }
        ],
        "responses": {
          "200": {
            "description": "Cursor-paginated list of Events.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Cursor-paginated list. Use `starting_after`/`ending_before` query params with the id of an item from `data` to walk pages.",
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Event"
                      }
                    },
                    "has_more": {
                      "description": "True if there are more pages beyond this one. Paginate with `starting_after`.",
                      "example": false,
                      "type": "boolean"
                    },
                    "url": {
                      "description": "Canonical path of this list endpoint.",
                      "example": "/v1/events",
                      "type": "string"
                    }
                  },
                  "required": [
                    "object",
                    "data",
                    "has_more",
                    "url"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}": {
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "events.retrieve",
        "summary": "Retrieve an Event",
        "tags": [
          "Events"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "Event id, prefixed `evt_`.",
              "example": "evt_test_example",
              "type": "string",
              "pattern": "^evt_[A-Za-z0-9]+$"
            },
            "required": true,
            "description": "Event id, prefixed `evt_`."
          }
        ],
        "responses": {
          "200": {
            "description": "The Event.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Event"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhook_endpoints": {
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "webhookEndpoints.create",
        "summary": "Create a Webhook Endpoint",
        "tags": [
          "WebhookEndpoints"
        ],
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEndpointCreateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created endpoint. The `secret` is included here ONCE — store it now.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "webhookEndpoints.list",
        "summary": "List Webhook Endpoints",
        "tags": [
          "WebhookEndpoints"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "description": "Page size. 1–100.",
              "example": 10,
              "default": 10,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "description": "Page size. 1–100."
          },
          {
            "in": "query",
            "name": "starting_after",
            "schema": {
              "description": "Cursor — exclusive.",
              "example": "we_test_example",
              "type": "string"
            },
            "description": "Cursor — exclusive."
          },
          {
            "in": "query",
            "name": "ending_before",
            "schema": {
              "description": "Cursor — exclusive.",
              "type": "string"
            },
            "description": "Cursor — exclusive."
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "description": "Filter by status.",
              "type": "string",
              "enum": [
                "enabled",
                "disabled"
              ]
            },
            "description": "Filter by status."
          }
        ],
        "responses": {
          "200": {
            "description": "Cursor-paginated list of endpoints (no secrets).",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Cursor-paginated list. Use `starting_after`/`ending_before` query params with the id of an item from `data` to walk pages.",
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookEndpoint"
                      }
                    },
                    "has_more": {
                      "description": "True if there are more pages beyond this one. Paginate with `starting_after`.",
                      "example": false,
                      "type": "boolean"
                    },
                    "url": {
                      "description": "Canonical path of this list endpoint.",
                      "example": "/v1/webhook_endpoints",
                      "type": "string"
                    }
                  },
                  "required": [
                    "object",
                    "data",
                    "has_more",
                    "url"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhook_endpoints/{id}": {
      "get": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "webhookEndpoints.retrieve",
        "summary": "Retrieve a Webhook Endpoint",
        "tags": [
          "WebhookEndpoints"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "Webhook endpoint id, prefixed `we_`.",
              "example": "we_test_example",
              "type": "string",
              "pattern": "^we_[A-Za-z0-9]+$"
            },
            "required": true,
            "description": "Webhook endpoint id, prefixed `we_`."
          }
        ],
        "responses": {
          "200": {
            "description": "The endpoint (no secret).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "webhookEndpoints.update",
        "summary": "Update a Webhook Endpoint",
        "tags": [
          "WebhookEndpoints"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "Webhook endpoint id, prefixed `we_`.",
              "example": "we_test_example",
              "type": "string",
              "pattern": "^we_[A-Za-z0-9]+$"
            },
            "required": true,
            "description": "Webhook endpoint id, prefixed `we_`."
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEndpointUpdateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "webhookEndpoints.delete",
        "summary": "Delete a Webhook Endpoint (soft)",
        "tags": [
          "WebhookEndpoints"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "Webhook endpoint id, prefixed `we_`.",
              "example": "we_test_example",
              "type": "string",
              "pattern": "^we_[A-Za-z0-9]+$"
            },
            "required": true,
            "description": "Webhook endpoint id, prefixed `we_`."
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "responses": {
          "200": {
            "description": "The soft-deleted endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhook_endpoints/{id}/roll": {
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "webhookEndpoints.roll",
        "summary": "Roll the signing secret",
        "tags": [
          "WebhookEndpoints"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "description": "Webhook endpoint id, prefixed `we_`.",
              "example": "we_test_example",
              "type": "string",
              "pattern": "^we_[A-Za-z0-9]+$"
            },
            "required": true,
            "description": "Webhook endpoint id, prefixed `we_`."
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h.",
              "example": "idempotency-1746619200-a1b2c3d4",
              "type": "string",
              "maxLength": 255
            },
            "description": "Replay-safe key. Send the SAME value on retries to ensure the operation runs at most once. SDKs auto-generate when omitted. Cached for 24h."
          }
        ],
        "responses": {
          "200": {
            "description": "The endpoint with a freshly rotated `secret` (shown once).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — validation failed, unknown field, or invalid request state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Authentication missing or invalid. The `Authorization` header must carry a valid `sk_test_*` / `sk_live_*` key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found, or not owned by your merchant account. Same response for both — leaking existence is a side-channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key was used previously with a different request body. Either use a fresh key or retry with the original body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limited. The `RateLimit-Reset` response header tells you when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Generic — the message is not parseable. Retry idempotent operations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream payment processor unreachable. Safe to retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "PaymentIntentCreateBody": {
        "type": "object",
        "properties": {
          "amount": {
            "description": "Charge amount in minor units (e.g. 1000 = 10.00 RSD). Max 100,000,000.",
            "example": 999,
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 100000000
          },
          "currency": {
            "description": "Lowercase ISO currency code. 2-decimal currencies only at this time.",
            "example": "rsd",
            "type": "string",
            "enum": [
              "rsd",
              "eur",
              "bam"
            ]
          },
          "capture_method": {
            "description": "Defaults to `automatic`. Use `manual` for preauthorize + later capture.",
            "example": "automatic",
            "type": "string",
            "enum": [
              "automatic",
              "manual"
            ]
          },
          "customer": {
            "description": "Attach to a saved customer (`cus_*`). Required if `payment_method` is attached to a customer.",
            "type": "string"
          },
          "payment_method": {
            "description": "Attach a saved payment method (`pm_*`). Mutually exclusive with `payment_method_token` (provide one).",
            "type": "string"
          },
          "description": {
            "description": "Free-form description. Surfaced on receipts.",
            "example": "Order #4581",
            "type": "string",
            "maxLength": 1000
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          },
          "confirm": {
            "description": "If true, charge immediately. Requires `payment_method_token` or `payment_method`.",
            "example": false,
            "type": "boolean"
          },
          "payment_method_token": {
            "description": "One-shot card token from platico.js. Mutually exclusive with `payment_method`.",
            "type": "string"
          },
          "return_url": {
            "description": "HTTPS URL the cardholder returns to after 3-D Secure. Required if 3DS may occur.",
            "example": "https://merchant.example.com/checkout/return",
            "type": "string"
          }
        },
        "required": [
          "amount",
          "currency"
        ]
      },
      "Metadata": {
        "description": "Free-form key-value pairs the merchant attaches to a resource for their own bookkeeping. Max 50 keys, max 40 chars per key, max 500 chars per value. Returned verbatim. NOT searchable.",
        "example": {
          "order_id": "4581",
          "shipping_zone": "rs-bg"
        },
        "type": "object",
        "propertyNames": {
          "type": "string",
          "maxLength": 40
        },
        "additionalProperties": {
          "type": "string",
          "maxLength": 500
        }
      },
      "PaymentIntentUpdateBody": {
        "description": "Only description and metadata are mutable.",
        "type": "object",
        "properties": {
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ]
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          }
        }
      },
      "PaymentIntentConfirmBody": {
        "type": "object",
        "properties": {
          "payment_method_token": {
            "description": "One-shot card token from platico.js (`ix::…`). Charges the card synchronously via AllSecure. Mutually exclusive with `payment_method_type`.",
            "type": "string"
          },
          "payment_method_type": {
            "description": "Set to `\"payment_link\"` to issue a hosted-page URL instead of charging directly. The response will contain `next_action.redirect_to_url` — show that URL to the customer (e.g. as a QR code in a POS). The customer opens it in their browser and pays on a Platico-hosted page; you poll `GET /v1/payment_intents/:id` for the result. Mutually exclusive with `payment_method_token`.",
            "type": "string",
            "const": "payment_link"
          },
          "return_url": {
            "type": "string"
          }
        }
      },
      "CustomerCreateBody": {
        "type": "object",
        "properties": {
          "email": {
            "description": "Customer email. Lowercased + trimmed on the server.",
            "example": "jane@example.com",
            "anyOf": [
              {
                "type": "string",
                "format": "email",
                "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
              },
              {
                "type": "null"
              }
            ]
          },
          "name": {
            "example": "Jane Doe",
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ]
          },
          "phone": {
            "example": null,
            "anyOf": [
              {
                "type": "string",
                "maxLength": 50
              },
              {
                "type": "null"
              }
            ]
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          }
        }
      },
      "CustomerUpdateBody": {
        "type": "object",
        "properties": {
          "email": {
            "anyOf": [
              {
                "type": "string",
                "format": "email",
                "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
              },
              {
                "type": "null"
              }
            ]
          },
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ]
          },
          "phone": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 50
              },
              {
                "type": "null"
              }
            ]
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          }
        }
      },
      "PaymentMethodCreateBody": {
        "type": "object",
        "properties": {
          "type": {
            "description": "PaymentMethod kind. Currently only `card` is supported.",
            "example": "card",
            "type": "string",
            "enum": [
              "card"
            ]
          },
          "card": {
            "description": "Required when `type` is `card`.",
            "type": "object",
            "properties": {
              "token": {
                "description": "One-shot card token from platico.js.",
                "example": "ix::example",
                "type": "string"
              }
            },
            "required": [
              "token"
            ]
          },
          "customer": {
            "description": "Attach to a saved customer (`cus_*`).",
            "example": null,
            "type": "string"
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          }
        },
        "required": [
          "type",
          "card"
        ]
      },
      "PaymentMethodUpdateBody": {
        "description": "Only metadata is mutable.",
        "type": "object",
        "properties": {
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          }
        }
      },
      "PaymentMethodAttachBody": {
        "type": "object",
        "properties": {
          "customer": {
            "description": "Target customer id.",
            "example": "cus_test_example",
            "type": "string"
          }
        },
        "required": [
          "customer"
        ]
      },
      "ProductCreateBody": {
        "type": "object",
        "properties": {
          "name": {
            "example": "Premium subscription",
            "type": "string",
            "maxLength": 200
          },
          "description": {
            "example": "Monthly access.",
            "type": "string",
            "maxLength": 1000
          },
          "active": {
            "description": "Defaults to true.",
            "example": true,
            "type": "boolean"
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          }
        },
        "required": [
          "name"
        ]
      },
      "ProductUpdateBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ]
          },
          "active": {
            "type": "boolean"
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          }
        }
      },
      "PriceCreateBody": {
        "type": "object",
        "properties": {
          "product": {
            "description": "Owning Product id (`prod_…`).",
            "example": "prod_test_example",
            "type": "string"
          },
          "currency": {
            "description": "Lowercase ISO-4217. Case-insensitive on input.",
            "example": "rsd",
            "type": "string",
            "enum": [
              "rsd",
              "eur",
              "bam"
            ]
          },
          "unit_amount": {
            "description": "Price in the smallest currency unit (999 = 9.99 RSD).",
            "example": 999,
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991
          },
          "type": {
            "example": "one_time",
            "type": "string",
            "enum": [
              "one_time",
              "recurring"
            ]
          },
          "recurring": {
            "$ref": "#/components/schemas/PriceRecurringBody"
          },
          "active": {
            "description": "Defaults to true.",
            "example": true,
            "type": "boolean"
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          }
        },
        "required": [
          "product",
          "currency",
          "unit_amount",
          "type"
        ]
      },
      "PriceRecurringBody": {
        "type": "object",
        "properties": {
          "interval": {
            "example": "month",
            "type": "string",
            "enum": [
              "day",
              "week",
              "month",
              "year"
            ]
          },
          "interval_count": {
            "description": "Defaults to 1.",
            "example": 1,
            "type": "integer",
            "minimum": 1,
            "maximum": 365
          }
        },
        "required": [
          "interval"
        ]
      },
      "PriceUpdateBody": {
        "description": "Only `active` and `metadata` are mutable. To change amount, currency, or recurrence: create a new Price and deactivate the old one.",
        "type": "object",
        "properties": {
          "active": {
            "type": "boolean"
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          }
        }
      },
      "RefundCreateBody": {
        "type": "object",
        "properties": {
          "payment_intent": {
            "description": "PaymentIntent (`pi_*`) to refund.",
            "example": "pi_test_example",
            "type": "string"
          },
          "amount": {
            "description": "Refund amount in minor units. Omit to refund the full remaining balance.",
            "example": 500,
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 100000000
          },
          "reason": {
            "example": "requested_by_customer",
            "type": "string",
            "enum": [
              "duplicate",
              "fraudulent",
              "requested_by_customer"
            ]
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          }
        },
        "required": [
          "payment_intent"
        ]
      },
      "WebhookEndpointCreateBody": {
        "type": "object",
        "properties": {
          "url": {
            "description": "HTTPS URL events are POSTed to.",
            "example": "https://example.com/webhooks/platico",
            "type": "string",
            "format": "uri"
          },
          "enabled_events": {
            "description": "Event types to deliver. Use `[\"*\"]` for all.",
            "example": [
              "payment_intent.succeeded",
              "charge.refunded"
            ],
            "minItems": 1,
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "description": {
            "example": "Primary endpoint",
            "type": "string",
            "maxLength": 500
          }
        },
        "required": [
          "url",
          "enabled_events"
        ]
      },
      "WebhookEndpointUpdateBody": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "enabled_events": {
            "minItems": 1,
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "enabled",
              "disabled"
            ]
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "PaymentIntent": {
        "description": "The primary money-movement object. Created → optionally confirmed (with a card token) → optionally 3-D Secure verified → settled. Mirrors Stripe's PaymentIntent semantics.",
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier. Prefixed with `pi_`.",
            "example": "pi_test_example",
            "type": "string"
          },
          "object": {
            "description": "Type discriminator. Always `payment_intent`.",
            "type": "string",
            "const": "payment_intent"
          },
          "amount": {
            "description": "Amount in the smallest currency unit (integer minor units). 1000 = 10.00 RSD.",
            "example": 999,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "currency": {
            "description": "Three-letter ISO currency code, lowercase. Today: `rsd`, `eur`, `bam`.",
            "example": "rsd",
            "type": "string"
          },
          "status": {
            "description": "Lifecycle state. Terminal states: `succeeded`, `canceled`, `requires_payment_method` (failed, retryable). Non-terminal: `requires_confirmation`, `requires_action` (e.g. 3-D Secure), `processing`, `requires_capture` (manual-capture preauth).",
            "example": "succeeded",
            "type": "string",
            "enum": [
              "requires_payment_method",
              "requires_confirmation",
              "requires_action",
              "processing",
              "requires_capture",
              "succeeded",
              "canceled"
            ]
          },
          "capture_method": {
            "description": "`automatic` charges immediately. `manual` reserves funds; you call `capture` separately within 7 days.",
            "example": "automatic",
            "type": "string",
            "enum": [
              "automatic",
              "manual"
            ]
          },
          "customer": {
            "description": "Attached `cus_*` id, or null.",
            "example": null,
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "payment_method": {
            "description": "Attached `pm_*` id, or null.",
            "example": null,
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "description": {
            "description": "Arbitrary merchant-provided text. Surfaced on receipts.",
            "example": null,
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "metadata": {
            "description": "Free-form key-value pairs the merchant attaches for their own bookkeeping. Returned verbatim.",
            "example": {
              "order_id": "4581",
              "shipping_zone": "rs-bg"
            },
            "$ref": "#/components/schemas/Metadata"
          },
          "next_action": {
            "description": "When `status` is `requires_action`, describes the next step (today: 3-D Secure redirect). Null otherwise.",
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "type": {
                    "description": "Action variant. Currently both values mean \"redirect the cardholder\".",
                    "type": "string",
                    "enum": [
                      "redirect_to_url",
                      "three_d_secure_redirect"
                    ]
                  },
                  "redirect_to_url": {
                    "description": "Redirect target.",
                    "type": "object",
                    "properties": {
                      "url": {
                        "description": "URL the cardholder must visit to complete the action (typically a bank-hosted 3-D Secure page). One-shot; expires within minutes.",
                        "example": "https://asxgw.paymentsandbox.cloud/redirect/example",
                        "type": "string"
                      }
                    },
                    "required": [
                      "url"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "type",
                  "redirect_to_url"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          },
          "last_payment_error": {
            "description": "Details of the last failed confirm/capture attempt on this PI. Null if no attempts have failed.",
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "type": {
                    "description": "Category of failure.",
                    "example": "card_error",
                    "type": "string"
                  },
                  "code": {
                    "description": "Machine-readable code.",
                    "example": "card_declined",
                    "type": "string"
                  },
                  "decline_code": {
                    "description": "Network decline reason. Only on card_error.",
                    "example": "insufficient_funds",
                    "type": "string"
                  },
                  "message": {
                    "description": "Human-readable. Safe to surface to end users.",
                    "example": "Your card was declined.",
                    "type": "string"
                  }
                },
                "required": [
                  "type",
                  "code",
                  "message"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          },
          "livemode": {
            "description": "`true` for live-mode PIs, `false` for sandbox.",
            "example": false,
            "type": "boolean"
          },
          "disputed": {
            "description": "`true` if any chargeback (dispute) has been opened against this PI. Stripe-shape companion to the dispute list endpoints.",
            "example": false,
            "type": "boolean"
          },
          "created": {
            "description": "Creation time as a Unix-second timestamp (integer).",
            "example": 1778709600,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "id",
          "object",
          "amount",
          "currency",
          "status",
          "capture_method",
          "customer",
          "payment_method",
          "description",
          "metadata",
          "next_action",
          "last_payment_error",
          "livemode",
          "disputed",
          "created"
        ],
        "additionalProperties": false
      },
      "Error": {
        "description": "Standard error envelope returned by every 4xx / 5xx response.",
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "type": {
                "description": "High-level category. SDK consumers match on this for retry/alert routing.",
                "type": "string",
                "enum": [
                  "invalid_request_error",
                  "api_error",
                  "rate_limit_error",
                  "idempotency_error",
                  "authentication_error",
                  "api_connection_error"
                ]
              },
              "code": {
                "description": "Machine-readable failure code. Common examples: 'resource_not_found', 'parameter_invalid', 'amount_too_large', 'payment_intent_under_dispute'. The full list is documented in the errors guide; this spec doesn't enumerate it (intentional — see security guardrails).",
                "example": "resource_not_found",
                "type": "string"
              },
              "message": {
                "description": "Human-readable explanation. Safe to surface to end users.",
                "example": "No such payment_intent.",
                "type": "string"
              },
              "param": {
                "description": "Request field name at fault, when applicable.",
                "example": "payment_intent",
                "type": "string"
              }
            },
            "required": [
              "type",
              "code",
              "message"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      },
      "Customer": {
        "description": "Saved customer record. Owns attached PaymentMethods. Soft-deleted via `DELETE`; retained for transaction history.",
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier. Prefixed with `cus_`.",
            "example": "cus_test_example",
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "customer"
          },
          "email": {
            "description": "Customer email. Lowercased + trimmed before storage.",
            "example": "jane@example.com",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "name": {
            "description": "Free-form name. Surfaced on receipts.",
            "example": "Jane Doe",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "phone": {
            "description": "E.164 phone (no normalization performed).",
            "example": null,
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          },
          "livemode": {
            "example": false,
            "type": "boolean"
          },
          "created": {
            "description": "Unix-second creation timestamp.",
            "example": 1778709600,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "deleted": {
            "description": "Unix-second soft-delete timestamp; null if active. Customers are never hard-deleted (referential integrity with their PaymentIntents).",
            "example": null,
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "object",
          "email",
          "name",
          "phone",
          "metadata",
          "livemode",
          "created",
          "deleted"
        ],
        "additionalProperties": false
      },
      "PaymentMethod": {
        "description": "Tokenized payment method (cards today). Created via `POST /v1/payment_methods` with a token from platico.js; attached to a Customer for reuse.",
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier. Prefixed with `pm_`.",
            "example": "pm_test_example",
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "payment_method"
          },
          "type": {
            "description": "Payment method kind. Currently only `card`.",
            "example": "card",
            "type": "string",
            "enum": [
              "card"
            ]
          },
          "customer": {
            "description": "Attached `cus_*` id, or null if unattached.",
            "example": null,
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "livemode": {
            "example": false,
            "type": "boolean"
          },
          "card": {
            "description": "Card details. Null when `type` is not `card`.",
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "brand": {
                    "description": "Card network. `visa`, `mastercard`, `maestro`, etc. Null if unknown.",
                    "example": "visa",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "last4": {
                    "description": "Last four digits of the card number.",
                    "example": "1111",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "exp_month": {
                    "description": "Expiry month (1–12).",
                    "example": 12,
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "exp_year": {
                    "description": "Expiry year (4 digits).",
                    "example": 2030,
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "holder": {
                    "description": "Cardholder name as tokenized. Free-form; not validated.",
                    "example": "Jane Doe",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "fingerprint": {
                    "description": "One-way SHA-256 of metadata (last4 + brand + exp + holder). Safe for client-side card dedup; reveals nothing reversible.",
                    "example": null,
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "brand",
                  "last4",
                  "exp_month",
                  "exp_year",
                  "holder",
                  "fingerprint"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          },
          "created": {
            "description": "Unix-second creation timestamp.",
            "example": 1778709600,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "detached_at": {
            "description": "Unix-second detachment timestamp; null if still attached.",
            "example": null,
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "object",
          "type",
          "customer",
          "livemode",
          "card",
          "metadata",
          "created",
          "detached_at"
        ],
        "additionalProperties": false
      },
      "Product": {
        "description": "A product in the merchant catalog. Owns one or more Prices. Deactivation is blocked while any active Price references the product.",
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier. Prefixed with `prod_`.",
            "example": "prod_test_example",
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "product"
          },
          "name": {
            "description": "Product name. Free-form, ≤200 chars.",
            "example": "Premium subscription",
            "type": "string"
          },
          "description": {
            "description": "Optional description. ≤1000 chars.",
            "example": "Monthly plan for the premium tier.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "active": {
            "description": "Whether this product can be associated with new active prices. Soft-deactivated via `DELETE`; can be reactivated via `POST`.",
            "example": true,
            "type": "boolean"
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          },
          "livemode": {
            "example": false,
            "type": "boolean"
          },
          "created": {
            "description": "Unix-second creation timestamp.",
            "example": 1778709600,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "updated": {
            "description": "Unix-second last-update timestamp.",
            "example": 1778709600,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "id",
          "object",
          "name",
          "description",
          "active",
          "metadata",
          "livemode",
          "created",
          "updated"
        ],
        "additionalProperties": false
      },
      "Price": {
        "description": "A price attached to a Product. Immutable except for `active` and `metadata` — to change amount or currency, create a new Price and deactivate the old one.",
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier. Prefixed with `price_`.",
            "example": "price_test_example",
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "price"
          },
          "product": {
            "description": "Owning Product id (`prod_…`).",
            "example": "prod_test_example",
            "type": "string"
          },
          "currency": {
            "description": "Lowercase ISO-4217. One of: `rsd`, `eur`, `bam`.",
            "example": "rsd",
            "type": "string"
          },
          "unit_amount": {
            "description": "Price in the smallest currency unit (e.g. 999 = 9.99 RSD).",
            "example": 999,
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "type": {
            "example": "one_time",
            "type": "string",
            "enum": [
              "one_time",
              "recurring"
            ]
          },
          "recurring": {
            "description": "Recurrence config when `type` is `recurring`; null otherwise.",
            "anyOf": [
              {
                "$ref": "#/components/schemas/PriceRecurring"
              },
              {
                "type": "null"
              }
            ]
          },
          "active": {
            "description": "Whether this price can be charged.",
            "example": true,
            "type": "boolean"
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          },
          "livemode": {
            "example": false,
            "type": "boolean"
          },
          "created": {
            "description": "Unix-second creation timestamp.",
            "example": 1778709600,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "id",
          "object",
          "product",
          "currency",
          "unit_amount",
          "type",
          "recurring",
          "active",
          "metadata",
          "livemode",
          "created"
        ],
        "additionalProperties": false
      },
      "PriceRecurring": {
        "type": "object",
        "properties": {
          "interval": {
            "example": "month",
            "type": "string",
            "enum": [
              "day",
              "week",
              "month",
              "year"
            ]
          },
          "interval_count": {
            "example": 1,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "interval",
          "interval_count"
        ],
        "additionalProperties": false
      },
      "Refund": {
        "description": "Reverses a settled PaymentIntent, in full or in part. A PI can have multiple refunds whose sum is ≤ the PI amount. Cannot refund a PI with an open dispute.",
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier. Prefixed with `re_`.",
            "example": "re_test_example",
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "refund"
          },
          "amount": {
            "description": "Refunded amount in minor units.",
            "example": 500,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "currency": {
            "example": "rsd",
            "type": "string"
          },
          "status": {
            "description": "Lifecycle state. Terminal: `succeeded`, `failed`, `canceled`.",
            "example": "succeeded",
            "type": "string",
            "enum": [
              "pending",
              "succeeded",
              "failed",
              "canceled"
            ]
          },
          "reason": {
            "description": "Merchant-supplied reason category.",
            "example": "requested_by_customer",
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "duplicate",
                  "fraudulent",
                  "requested_by_customer"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "failure_reason": {
            "description": "Processor failure message when status is `failed`. Null otherwise.",
            "example": null,
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "payment_intent": {
            "description": "Parent `pi_*` id this refund is against.",
            "example": "pi_test_example",
            "type": "string"
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          },
          "created": {
            "description": "Unix-second creation timestamp.",
            "example": 1778709600,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "id",
          "object",
          "amount",
          "currency",
          "status",
          "reason",
          "failure_reason",
          "payment_intent",
          "metadata",
          "created"
        ],
        "additionalProperties": false
      },
      "Dispute": {
        "description": "A chargeback opened by the cardholder via their bank. Created by AllSecure webhooks — never directly by the merchant. Read-only on the API surface.",
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier. Prefixed with `dp_`.",
            "example": "dp_test_example",
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "dispute"
          },
          "amount": {
            "description": "Disputed amount in minor units.",
            "example": 999,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "currency": {
            "example": "rsd",
            "type": "string"
          },
          "status": {
            "description": "`needs_response`: open, response window ticking. `warning_closed`: rescinded by the bank before a decision. `won` / `lost`: terminal outcomes.",
            "example": "needs_response",
            "type": "string",
            "enum": [
              "needs_response",
              "warning_closed",
              "won",
              "lost"
            ]
          },
          "reason": {
            "description": "Reason text from the processor (truncated to 50 chars on ingest).",
            "example": "fraudulent",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "payment_intent": {
            "description": "Parent `pi_*` id the dispute was opened against.",
            "example": "pi_test_example",
            "type": "string"
          },
          "evidence": {
            "description": "Opaque evidence blob. Read-only at this stage; merchant evidence-submission is a planned future capability.",
            "example": null,
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ]
          },
          "livemode": {
            "example": false,
            "type": "boolean"
          },
          "created": {
            "description": "Unix-second creation timestamp (when the dispute landed in our system).",
            "example": 1778709600,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "id",
          "object",
          "amount",
          "currency",
          "status",
          "reason",
          "payment_intent",
          "evidence",
          "livemode",
          "created"
        ],
        "additionalProperties": false
      },
      "Event": {
        "description": "An immutable record of something that happened (a PaymentIntent succeeded, a refund settled, a chargeback opened). The same events drive outgoing webhooks. Read-only.",
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier. Prefixed with `evt_`.",
            "example": "evt_test_example",
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "event"
          },
          "type": {
            "description": "Event type, e.g. `payment_intent.succeeded`, `charge.refunded`, `endpoint.test`.",
            "example": "payment_intent.succeeded",
            "type": "string"
          },
          "data": {
            "description": "Event payload. `data.object` is the immutable snapshot.",
            "type": "object",
            "properties": {
              "object": {
                "description": "Snapshot of the API object the event describes, as it was at event time."
              }
            },
            "required": [
              "object"
            ],
            "additionalProperties": false
          },
          "livemode": {
            "example": false,
            "type": "boolean"
          },
          "created": {
            "description": "Unix-second creation timestamp.",
            "example": 1778709600,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "id",
          "object",
          "type",
          "data",
          "livemode",
          "created"
        ],
        "additionalProperties": false
      },
      "WebhookEndpoint": {
        "description": "A destination Platico POSTs signed events to. Manage from the dashboard or via the API. The signing secret is shown once (on create/roll); verify deliveries with it.",
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier. Prefixed with `we_`.",
            "example": "we_test_example",
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "webhook_endpoint"
          },
          "url": {
            "description": "HTTPS URL events are POSTed to.",
            "example": "https://example.com/webhooks/platico",
            "type": "string"
          },
          "livemode": {
            "example": false,
            "type": "boolean"
          },
          "status": {
            "example": "enabled",
            "type": "string",
            "enum": [
              "enabled",
              "disabled"
            ]
          },
          "enabled_events": {
            "description": "Event types delivered to this endpoint (`[\"*\"]` for all).",
            "example": [
              "payment_intent.succeeded",
              "charge.refunded"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "description": {
            "example": null,
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "masked": {
            "description": "Masked signing secret for display. The full secret is only returned on create/roll.",
            "example": "whsec_•••••••••",
            "type": "string"
          },
          "last4": {
            "description": "Last 4 of the signing secret (•••• unless just created/rolled).",
            "example": "••••",
            "type": "string"
          },
          "created": {
            "description": "Unix-second creation timestamp.",
            "example": 1778709600,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "updated": {
            "description": "Unix-second last-update timestamp.",
            "example": 1778709600,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "deleted_at": {
            "description": "Unix-second soft-delete timestamp, or null.",
            "example": null,
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "secret": {
            "description": "Plaintext signing secret (HMAC-SHA256). Returned ONLY on create and roll — store it now, it is never shown again.",
            "example": "whsec_example_shown_once",
            "type": "string"
          },
          "rotated_from": {
            "description": "On a roll response, the id of the endpoint whose secret was rotated.",
            "example": "we_test_example",
            "type": "string"
          }
        },
        "required": [
          "id",
          "object",
          "url",
          "livemode",
          "status",
          "enabled_events",
          "description",
          "masked",
          "last4",
          "created",
          "updated",
          "deleted_at"
        ],
        "additionalProperties": false
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API key",
        "description": "API key as `Authorization: Bearer sk_test_...` or `sk_live_...`. Keys are issued from the dashboard and scoped to a single merchant + mode."
      }
    }
  }
}
