Insforge Stripe Payments API
Stripe Checkout, Billing Portal, catalog, sync, customer, subscription, and transaction routes
Stripe Checkout, Billing Portal, catalog, sync, customer, subscription, and transaction routes
openapi: 3.0.3
info:
title: Insforge AI Admin Stripe Payments API
version: 1.0.0
description: Model Gateway helper APIs for OpenRouter key provisioning, model discovery, and deprecated compatibility proxy routes
tags:
- name: Stripe Payments
description: Stripe Checkout, Billing Portal, catalog, sync, customer, subscription, and transaction routes
paths:
/api/payments/stripe/{environment}/checkout-sessions:
post:
summary: Create Stripe Checkout Session
description: Create a local checkout attempt with the caller's user context and then create a Stripe Checkout Session. Subscription mode requires a billing subject.
tags:
- Stripe Payments
security:
- bearerAuth: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateCheckoutSessionBody'
example:
mode: subscription
lineItems:
- priceId: price_123
quantity: 1
successUrl: https://app.example.com/billing/success
cancelUrl: https://app.example.com/billing/cancel
subject:
type: team
id: team_123
customerEmail: buyer@example.com
idempotencyKey: checkout-team_123-pro
responses:
'201':
description: Checkout Session created
content:
application/json:
schema:
$ref: '#/components/schemas/CreateCheckoutSessionResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'500':
$ref: '#/components/responses/InternalError'
/api/payments/stripe/{environment}/customer-portal-sessions:
post:
summary: Create Stripe Customer Portal Session
description: Create a Stripe Billing Portal Session for an authenticated user's mapped billing subject.
tags:
- Stripe Payments
security:
- bearerAuth: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateCustomerPortalSessionBody'
example:
subject:
type: team
id: team_123
returnUrl: https://app.example.com/billing
responses:
'201':
description: Customer Portal Session created
content:
application/json:
schema:
$ref: '#/components/schemas/CreateCustomerPortalSessionResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
/api/payments/stripe/status:
get:
summary: Get Stripe Payments Status
description: Return Stripe connection, sync, and managed webhook status for each environment.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
responses:
'200':
description: Stripe payments status
content:
application/json:
schema:
$ref: '#/components/schemas/GetStripeStatusResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
/api/payments/stripe/config:
get:
summary: Get Stripe Key Configuration
description: Return masked Stripe key configuration for test and live environments.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
responses:
'200':
description: Stripe key configuration
content:
application/json:
schema:
$ref: '#/components/schemas/GetStripeConfigResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
/api/payments/stripe/{environment}/config:
put:
summary: Configure Stripe Secret Key
description: Validate and store a Stripe secret key. New Stripe accounts attempt managed webhook setup and then run a unified sync.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpsertStripeConfigBody'
example:
secretKey: sk_test_xxx
responses:
'200':
description: Updated Stripe key configuration
content:
application/json:
schema:
$ref: '#/components/schemas/GetStripeConfigResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
delete:
summary: Remove Stripe Secret Key
description: Remove the configured Stripe secret key for one environment and best-effort remove managed webhook endpoints.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
responses:
'200':
description: Updated Stripe key configuration
content:
application/json:
schema:
$ref: '#/components/schemas/GetStripeConfigResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/api/payments/stripe/sync:
post:
summary: Sync Stripe Payments State
description: Sync products, prices, customers, and subscriptions for every configured Stripe environment. Stripe remains the source of truth.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
responses:
'200':
description: Sync result for configured environments
content:
application/json:
schema:
$ref: '#/components/schemas/SyncStripePaymentsResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
/api/payments/stripe/{environment}/sync:
post:
summary: Sync Stripe Payments State For One Environment
description: Sync products, prices, customers, and subscriptions for one Stripe environment. Stripe remains the source of truth.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
responses:
'200':
description: Sync result for the requested environment
content:
application/json:
schema:
$ref: '#/components/schemas/SyncStripePaymentsResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
/api/payments/stripe/{environment}/webhook:
post:
summary: Configure Managed Stripe Webhook
description: Create or recreate the InsForge-managed Stripe webhook endpoint for one environment.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
responses:
'200':
description: Managed webhook configuration result
content:
application/json:
schema:
$ref: '#/components/schemas/ConfigureStripeWebhookResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
/api/payments/stripe/{environment}/catalog:
get:
summary: List Stripe Catalog
description: Return mirrored Stripe products and prices for one environment.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
responses:
'200':
description: Synced Stripe products and prices
content:
application/json:
schema:
$ref: '#/components/schemas/ListStripeCatalogResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
/api/payments/stripe/{environment}/catalog/products:
get:
summary: List Stripe Products
description: List mirrored Stripe products for one environment.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
responses:
'200':
description: Stripe products
content:
application/json:
schema:
$ref: '#/components/schemas/ListStripeProductsResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
post:
summary: Create Stripe Product
description: Create a Stripe product in the requested environment, then mirror it locally after Stripe succeeds.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateStripeProductBody'
example:
name: Pro Plan
description: Monthly access to Pro features
active: true
metadata:
tier: pro
idempotencyKey: product-pro-plan
responses:
'201':
description: Product created
content:
application/json:
schema:
$ref: '#/components/schemas/MutateStripeProductResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
/api/payments/stripe/{environment}/catalog/products/{productId}:
get:
summary: Get Stripe Product
description: Get one mirrored Stripe product and its associated prices.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
- $ref: '#/components/parameters/ProductIdPath'
responses:
'200':
description: Product and prices
content:
application/json:
schema:
$ref: '#/components/schemas/GetStripeProductResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
patch:
summary: Update Stripe Product
description: Update a Stripe product, then mirror it locally after Stripe succeeds.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
- $ref: '#/components/parameters/ProductIdPath'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateStripeProductBody'
example:
name: Pro Plan
active: true
responses:
'200':
description: Product updated
content:
application/json:
schema:
$ref: '#/components/schemas/MutateStripeProductResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
delete:
summary: Delete Stripe Product
description: Delete a Stripe product from one environment, then remove it from the local mirror.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
- $ref: '#/components/parameters/ProductIdPath'
responses:
'200':
description: Product deleted
content:
application/json:
schema:
$ref: '#/components/schemas/DeleteStripeProductResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/api/payments/stripe/{environment}/catalog/prices:
get:
summary: List Stripe Prices
description: List mirrored Stripe prices for one environment, optionally filtered by product.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
- name: productId
in: query
required: false
schema:
type: string
minLength: 1
description: Filter prices by Stripe product ID.
example: prod_123
responses:
'200':
description: Stripe prices
content:
application/json:
schema:
$ref: '#/components/schemas/ListStripePricesResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
post:
summary: Create Stripe Price
description: Create a Stripe price in the requested environment, then mirror it locally after Stripe succeeds.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateStripePriceBody'
example:
productId: prod_123
currency: usd
unitAmount: 2900
recurring:
interval: month
intervalCount: 1
lookupKey: pro_monthly
idempotencyKey: price-pro-monthly
responses:
'201':
description: Price created
content:
application/json:
schema:
$ref: '#/components/schemas/MutateStripePriceResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
/api/payments/stripe/{environment}/catalog/prices/{priceId}:
get:
summary: Get Stripe Price
description: Get one mirrored Stripe price.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
- $ref: '#/components/parameters/PriceIdPath'
responses:
'200':
description: Price
content:
application/json:
schema:
$ref: '#/components/schemas/GetStripePriceResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
patch:
summary: Update Stripe Price
description: Update mutable Stripe price fields, then mirror the price locally after Stripe succeeds.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
- $ref: '#/components/parameters/PriceIdPath'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateStripePriceBody'
example:
active: true
lookupKey: pro_monthly
responses:
'200':
description: Price updated
content:
application/json:
schema:
$ref: '#/components/schemas/MutateStripePriceResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
delete:
summary: Archive Stripe Price
description: Archive a Stripe price in one environment, then mirror the archived state locally.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
- $ref: '#/components/parameters/PriceIdPath'
responses:
'200':
description: Price archived
content:
application/json:
schema:
$ref: '#/components/schemas/ArchiveStripePriceResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/api/payments/stripe/{environment}/subscriptions:
get:
summary: List Stripe Subscriptions
description: Admin/debug read for mirrored Stripe subscriptions. Use app-owned tables with RLS for end-user payment state.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
- $ref: '#/components/parameters/SubjectTypeQuery'
- $ref: '#/components/parameters/SubjectIdQuery'
- $ref: '#/components/parameters/LimitQuery'
responses:
'200':
description: Stripe subscriptions
content:
application/json:
schema:
$ref: '#/components/schemas/ListStripeSubscriptionsResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
/api/payments/stripe/{environment}/customers:
get:
summary: List Stripe Customers
description: Admin/debug read for mirrored Stripe customers. This is a display mirror only and should not replace app-owned billing tables.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
- $ref: '#/components/parameters/LimitQuery'
responses:
'200':
description: Stripe customers
content:
application/json:
schema:
$ref: '#/components/schemas/ListPaymentCustomersResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
/api/payments/stripe/{environment}/transactions:
get:
summary: List Stripe Transactions
description: Admin/debug read for InsForge's Stripe transaction projection. Use app-owned fulfillment tables with RLS for end-user order, credit, or entitlement state.
tags:
- Stripe Payments
security:
- bearerAuth: []
- apiKey: []
parameters:
- $ref: '#/components/parameters/EnvironmentPath'
- $ref: '#/components/parameters/SubjectTypeQuery'
- $ref: '#/components/parameters/SubjectIdQuery'
- $ref: '#/components/parameters/LimitQuery'
responses:
'200':
description: Stripe transactions
content:
application/json:
schema:
$ref: '#/components/schemas/ListPaymentTransactionsResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
components:
schemas:
CheckoutSessionPaymentStatus:
type: string
enum:
- paid
- unpaid
- no_payment_required
ListPaymentCustomersResponse:
type: object
required:
- customers
properties:
customers:
type: array
items:
$ref: '#/components/schemas/PaymentCustomerListItem'
PaymentProvider:
type: string
enum:
- stripe
- razorpay
MutateStripeProductResponse:
type: object
required:
- product
properties:
product:
$ref: '#/components/schemas/StripeProduct'
PaymentTransaction:
type: object
required:
- environment
- provider
- type
- status
- subjectType
- subjectId
- providerCustomerId
- customerEmailSnapshot
- providerReferenceId
- providerReferenceType
- amount
- amountRefunded
- currency
- description
- paidAt
- failedAt
- refundedAt
- providerCreatedAt
- createdAt
- updatedAt
properties:
environment:
$ref: '#/components/schemas/PaymentEnvironment'
provider:
$ref: '#/components/schemas/PaymentProvider'
type:
$ref: '#/components/schemas/PaymentTransactionType'
status:
$ref: '#/components/schemas/PaymentTransactionStatus'
subjectType:
type: string
nullable: true
subjectId:
type: string
nullable: true
providerCustomerId:
type: string
nullable: true
example: cus_123
customerEmailSnapshot:
type: string
format: email
nullable: true
providerReferenceId:
type: string
nullable: true
example: pi_123
providerReferenceType:
type: string
nullable: true
example: payment_intent
amount:
type: integer
nullable: true
example: 2900
amountRefunded:
type: integer
nullable: true
example: 0
currency:
type: string
nullable: true
example: usd
description:
type: string
nullable: true
paidAt:
type: string
format: date-time
nullable: true
failedAt:
type: string
format: date-time
nullable: true
refundedAt:
type: string
format: date-time
nullable: true
providerCreatedAt:
type: string
format: date-time
nullable: true
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
StripeSubscriptionStatus:
type: string
enum:
- incomplete
- incomplete_expired
- trialing
- active
- past_due
- canceled
- unpaid
- paused
ArchiveStripePriceResponse:
type: object
required:
- price
- archived
properties:
price:
$ref: '#/components/schemas/StripePrice'
archived:
type: boolean
CheckoutSessionStatus:
type: string
enum:
- initialized
- open
- completed
- expired
- failed
StripeProduct:
type: object
required:
- environment
- productId
- name
- description
- active
- defaultPriceId
- metadata
- syncedAt
properties:
environment:
$ref: '#/components/schemas/StripeEnvironment'
productId:
type: string
example: prod_123
name:
type: string
description:
type: string
nullable: true
active:
type: boolean
defaultPriceId:
type: string
nullable: true
example: price_123
metadata:
$ref: '#/components/schemas/Metadata'
syncedAt:
type: string
format: date-time
PaymentTransactionStatus:
type: string
enum:
- succeeded
- failed
- pending
- refunded
- partially_refunded
StripePriceRecurringInterval:
type: string
enum:
- day
- week
- month
- year
GetStripeStatusResponse:
type: object
required:
- connections
properties:
connections:
type: array
items:
$ref: '#/components/schemas/StripeConnection'
ListStripeSubscriptionsResponse:
type: object
required:
- subscriptions
properties:
subscriptions:
type: array
items:
$ref: '#/components/schemas/StripeSubscription'
ConfigureStripeWebhookResponse:
type: object
required:
- connection
properties:
connection:
$ref: '#/components/schemas/StripeConnection'
MutateStripePriceResponse:
type: object
required:
- price
properties:
price:
$ref: '#/components/schemas/StripePrice'
CreateCheckoutSessionLineItem:
type: object
required:
- priceId
additionalProperties: false
properties:
priceId:
type: string
minLength: 1
example: price_123
quantity:
type: integer
minimum: 1
maximum: 999
default: 1
SyncStripePaymentsResponse:
type: object
required:
- results
properties:
results:
type: array
items:
$ref: '#/components/schemas/SyncStripePaymentsEnvironmentResult'
StripeLatestSyncStatus:
type: string
enum:
- succeeded
- failed
StripeKeyConfig:
type: object
required:
- environment
- hasKey
- maskedKey
properties:
environment:
$ref: '#/components/schemas/StripeEnvironment'
hasKey:
type: boolean
maskedKey:
type: string
nullable: true
example: sk_test_...abcd
DeleteStripeProductResponse:
type: object
required:
- productId
- deleted
properties:
productId:
type: string
example: prod_123
deleted:
type: boolean
PaymentEnvironment:
type: string
enum:
- test
- live
UpdateStripeProductBody:
type: object
additionalProperties: false
properties:
name:
type: string
minLength: 1
description:
type: string
nullable: true
maxLength: 5000
active:
type: boolean
metadata:
$ref: '#/components/schemas/Metadata'
minProperties: 1
ListPaymentTransactionsResponse:
type: object
required:
- transactions
properties:
transactions:
type: array
items:
$ref: '#/components/schemas/PaymentTransaction'
CreateStripeProductBody:
type: object
required:
- name
additionalProperties: false
properties:
name:
type: string
minLength: 1
description:
type: string
nullable: true
maxLength: 5000
active:
type: boolean
metadata:
$ref: '#/components/schemas/Metadata'
idempotencyKey:
type: string
minLength: 1
maxLength: 200
CreateCheckoutSessionBody:
type: object
required:
- mode
- lineItems
- successUrl
- cancelUrl
additionalProperties: false
description: Metadata keys starting with insforge_ are reserved and rejected.
properties:
mode:
$ref: '#/components/schemas/CheckoutMode'
lineItems:
type: array
minItems: 1
maxItems: 100
items:
$ref: '#/components/schemas/CreateCheckoutSessionLineItem'
successUrl:
type: string
format: uri
cancelUrl:
type: string
format: uri
subject:
$ref: '#/components/schemas/BillingSubject'
customerEmail:
type: string
format: email
nullable: true
metadata:
$ref: '#/components/schemas/Metadata'
idempotencyKey:
type: string
minLength: 1
maxLength: 200
CreateCheckoutSessionResponse:
type: object
required:
- checkoutSession
properties:
checkoutSession:
$ref: '#/components/schemas/CheckoutSession'
CreateCustomerPortalSessionBody:
type: object
required:
- subject
additionalProperties: false
properties:
subject:
$ref: '#/components/schemas/BillingSubject'
returnUrl:
type: string
format: uri
configuration:
type: string
minLength: 1
maxLength: 255
StripePrice:
type: object
required:
- environment
- priceId
- productId
- active
- currency
- unitAmount
- unitAmountDecimal
- type
- lookupKey
- billingScheme
- taxBehavior
- recurringInterval
- recurringIntervalCount
- metadata
- syncedAt
properties:
environment:
$ref: '#/components/schemas/StripeEnvironment'
priceId:
type: string
example: price_123
productId:
type: string
nullable: true
example: prod_123
active:
type: boolean
currency:
type: string
example: usd
unitAmount:
type: integer
nullable: true
example: 2900
unitAmountDecimal:
type: string
nullable: true
example: '2900'
type:
type: string
example: recurring
lookupKey:
type: string
nullable: true
example: pro_monthly
billingScheme:
type: string
nullable: true
example: per_unit
taxBehavior:
type: string
nullable: true
enum:
- exclusive
- inclusive
- unspecified
example: unspecified
# --- truncated at 32 KB (49 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/insforge/refs/heads/main/openapi/insforge-stripe-payments-api-openapi.yml