{"openapi":"3.0.3","info":{"title":"Paysio API","version":"1.0.0","description":"Public Paysio V1 API. Every response is wrapped in a top-level `data` key — unwrap it exactly once: single resources are `{ \"data\": { ... } }`, lists are `{ \"data\": [ ... ], \"has_more\": boolean }`. Authenticate with HTTP Bearer using a secret (sk_) or publishable (pk_) key; write operations require a secret key. Monetary amounts are integers in cents. Balance, payouts, and account-checks require Paysio Debit & Payouts, which is enabled per mode (a test key can work while a live key does not).","contact":{"name":"Paysio","url":"https://paysio.com/docs"}},"servers":[{"url":"https://paysio.com/api/v1","description":"Production"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Products"},{"name":"Customers"},{"name":"Payment Methods"},{"name":"Charges"},{"name":"Wallets"},{"name":"Transactions"},{"name":"Disputes"},{"name":"Payouts"},{"name":"Payout Links"},{"name":"Payout Requests"},{"name":"Balance"},{"name":"Account Checks"},{"name":"Subscriptions"},{"name":"Invoices"},{"name":"Checkout Sessions"},{"name":"Tokens"},{"name":"3D Secure"},{"name":"Payment Links"},{"name":"Fulfillments"},{"name":"Account"},{"name":"Members"},{"name":"Storefronts"},{"name":"Pixels"},{"name":"Apps","description":"Endpoints for installed Paysio apps. Blocks, files, emails and app data require an app access token (pat_) from POST /oauth/token — a merchant API key is refused with 403 app_required."}],"paths":{"/products":{"get":{"tags":["Products"],"operationId":"listProducts","summary":"List products","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/startingAfter"}],"responses":{"200":{"description":"A paginated list of products.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Product"}},"has_more":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Products"],"operationId":"createProduct","summary":"Create a product","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductCreate"}}}},"responses":{"201":{"description":"The created product.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Product"}}}}}},"400":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}}}},"/inventory/adjust":{"post":{"tags":["Products"],"operationId":"adjustInventory","summary":"Adjust stock atomically","description":"Move stock in a single statement. Use this instead of PATCH /products/{id} whenever concurrency is possible: PATCH is read-modify-write, so two simultaneous orders both read the same value and both write it back, overselling a unit. Send exactly one of delta (relative, for a sale) or quantity (absolute, for an import). Requires the inventory:write scope.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["product_id"],"properties":{"product_id":{"type":"string","description":"The product whose stock is moving"},"delta":{"type":"integer","description":"Relative change, e.g. -1 for one unit sold. 409 if it would go below zero."},"quantity":{"type":"integer","minimum":0,"description":"Absolute value to set. For imports, not sales."},"variant_id":{"type":"string","description":"Adjust a variant instead of the product itself"}}}}}},"responses":{"200":{"description":"The new stock level.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"inventory"},"product_id":{"type":"string"},"variant_id":{"type":"string","nullable":true},"stock_quantity":{"type":"integer"},"track_inventory":{"type":"boolean"}}}}}},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"}}}},"/products/{id}":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"get":{"tags":["Products"],"operationId":"getProduct","summary":"Retrieve a product","responses":{"200":{"description":"A product.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Product"}}}}}},"404":{"$ref":"#/components/responses/Error"}}},"patch":{"tags":["Products"],"operationId":"updateProduct","summary":"Update a product","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductUpdate"}}}},"responses":{"200":{"description":"The updated product.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Product"}}}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/invoices":{"get":{"tags":["Invoices"],"operationId":"listInvoices","summary":"List invoices","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/startingAfter"},{"name":"status","in":"query","schema":{"type":"string","enum":["draft","sent","viewed","processing","paid","void"]}},{"name":"customer_id","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"A paginated list of invoices.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Invoice"}},"has_more":{"type":"boolean"}}}}}}}},"post":{"tags":["Invoices"],"operationId":"createInvoice","summary":"Create an invoice","security":[{"bearerAuth":[]}],"description":"Creates a draft invoice from your products. Nothing is emailed until you send it (POST /invoices/{id}/send) or pass send: true. Sending creates a one-time payment link and emails a branded invoice with a PDF.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceCreate"}}}},"responses":{"201":{"description":"The created invoice.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Invoice"}}}}}},"400":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}}}},"/invoices/{id}":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"get":{"tags":["Invoices"],"operationId":"getInvoice","summary":"Retrieve an invoice","responses":{"200":{"description":"An invoice.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Invoice"}}}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/invoices/{id}/send":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"post":{"tags":["Invoices"],"operationId":"sendInvoice","summary":"Send an invoice","security":[{"bearerAuth":[]}],"description":"Creates the payment link on first send, emails the invoice with a PDF attached, and marks it sent. Re-sending emails again and reuses the link.","responses":{"200":{"description":"The sent invoice, with hosted_invoice_url, pay_url and emailed.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Invoice"}}}}}},"400":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/invoices/{id}/void":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"post":{"tags":["Invoices"],"operationId":"voidInvoice","summary":"Void an invoice","security":[{"bearerAuth":[]}],"description":"Voids an unpaid invoice and deactivates its payment link.","responses":{"200":{"description":"The voided invoice.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Invoice"}}}}}},"400":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/customers":{"get":{"tags":["Customers"],"operationId":"listCustomers","summary":"List customers","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/startingAfter"},{"name":"processor","in":"query","schema":{"type":"string","enum":["nmi","stripe","aptpay"]},"description":"Filter by the gateway the customer is vaulted on. Use processor=aptpay to find payout-eligible customers."}],"responses":{"200":{"description":"A paginated list of customers.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Customer"}},"has_more":{"type":"boolean"}}}}}}}},"post":{"tags":["Customers"],"operationId":"createCustomer","summary":"Create (or upsert) a customer","security":[{"bearerAuth":[]}],"description":"Creates a customer, or updates the existing one with the same email. Optionally vaults a card in the same call. On a Paysio Debit & Payouts workspace the customer is created on the AptPay rail so saved cards are payout-eligible.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerCreate"}}}},"responses":{"201":{"description":"The created customer.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Customer"},"payment_method":{"nullable":true,"type":"object"},"existing":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/customers/{id}":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"get":{"tags":["Customers"],"operationId":"getCustomer","summary":"Retrieve a customer","responses":{"200":{"description":"A customer.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Customer"}}}}}},"404":{"$ref":"#/components/responses/Error"}}},"patch":{"tags":["Customers"],"operationId":"updateCustomer","summary":"Update a customer","security":[{"bearerAuth":[]}],"description":"Update contact, billing, and shipping details. Billing address is used for card AVS on charges and payouts.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerUpdate"}}}},"responses":{"200":{"description":"The updated customer.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Customer"}}}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/customers/{id}/payment-methods":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"get":{"tags":["Payment Methods"],"operationId":"listPaymentMethods","summary":"List a customer’s saved payment methods","responses":{"200":{"description":"Saved payment methods.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PaymentMethod"}}}}}}}}},"post":{"tags":["Payment Methods"],"operationId":"addPaymentMethod","summary":"Save a payment method to a customer","security":[{"bearerAuth":[]}],"description":"Provide ONE of: a Paysio.js token (payment_token), raw card fields (cc_number + cc_exp_month + cc_exp_year), or a bank account (type=bank_account). The returned `id` (= billing_id) is what you pass to POST /payouts as payment_method_id.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentMethodCreate"}}}},"responses":{"201":{"description":"The saved payment method.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PaymentMethod"}}}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/customers/{id}/payment-methods/{billingId}":{"delete":{"tags":["Payment Methods"],"operationId":"deletePaymentMethod","summary":"Remove a saved payment method","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/pathId"},{"name":"billingId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"deleted":{"type":"boolean"},"billing_id":{"type":"string"}}}}}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/charges":{"post":{"tags":["Charges"],"operationId":"createCharge","summary":"Charge a saved card or a one-time token","security":[{"bearerAuth":[]}],"description":"Charge a customer’s vaulted instrument (customer_id) or a one-time token (payment_token / stripe_payment_method_id). Provide amount, OR product_id, OR line_items.\n\nSmart Routing: when enabled for the workspace, a FRESH payment_token charge is classified server-side and routed automatically — debit/prepaid cards to Paysio Debit & Payouts, credit cards to the NMI-family gateway — with no extra request fields. It requires billing_country \"US\", no gateway override, and no saved method; saved/vaulted methods charge on the workspace default gateway instead. The response processorType shows which gateway was used.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChargeCreate"}}}},"responses":{"201":{"description":"The created transaction.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Transaction"}}}}}},"400":{"$ref":"#/components/responses/Error"},"402":{"description":"Declined — the transaction object is included under data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","description":"Stable Paysio code, e.g. insufficient_funds. Branch on this."},"decline_code":{"type":"string","nullable":true,"description":"The gateway's own code, verbatim (NMI '202', AptPay 'D013')."},"category":{"type":"string","enum":["declined","insufficient_funds","invalid_card","cvc","unsupported_card","duplicate","configuration","gateway_unavailable","unknown"]},"reference_id":{"type":"string","nullable":true},"data":{"$ref":"#/components/schemas/Transaction"}}}}}},"503":{"description":"The gateway did not return a clean result. The outcome is UNKNOWN — do NOT treat this as a failed charge. Retry with the SAME reference_id (a duplicate is refused with 409 while the first attempt is unresolved).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"decline_code":{"type":"string","nullable":true},"category":{"type":"string"},"reference_id":{"type":"string","nullable":true}}}}}}}}},"/wallets/prepare":{"post":{"tags":["Wallets"],"operationId":"prepareWallet","summary":"Prepare a Google Pay payment for 3D Secure","security":[{"bearerAuth":[]}],"description":"Decrypts the Google Pay token once and reports whether the credential needs a 3DS step-up. Paysio.js calls this automatically after the Google sheet closes — call it yourself only if you drive the wallet flow by hand. Desktop/iOS Google Pay (PAN_ONLY) is the buyer's real card and can be stepped up; Android device tokens are already authenticated and always report three_ds_required false. Apple Pay is refused for the same reason.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["paysio_wallet"],"properties":{"paysio_wallet":{"type":"object","description":"{ type: \"google_pay\", google_token, info? } from the wallet sheet."}}}}}},"responses":{"200":{"description":"The prepared credential and whether a step-up applies.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"object":{"type":"string","example":"wallet_prepare"},"prepared":{"type":"string","description":"Sealed credential — send as paysio_wallet.prepared on POST /charges. Single-use, workspace-bound, expires in 15 minutes."},"three_ds_required":{"type":"boolean","description":"True when a 3DS challenge should run before charging. False unless 3D Secure is enabled for the workspace AND the vault is on."},"three_ds_reason":{"type":"string","nullable":true,"enum":["already_authenticated","three_ds_disabled","vault_disabled","card_unavailable"],"description":"Why three_ds_required is false; null when a step-up is required. \"already_authenticated\" = device token or wallet-verified credential (nothing to step up); \"three_ds_disabled\" = enable 3D Secure in Settings > Checkout; \"vault_disabled\" = the Paysio vault is off; \"card_unavailable\" = the step-up card could not be created (charge without 3DS)."},"card_id":{"type":"string","nullable":true,"description":"Authenticate this with POST /three-ds/authenticate (or threeDS.authenticate({ cardId })), then charge with the 3DS result."},"card":{"type":"object","properties":{"brand":{"type":"string","nullable":true},"last4":{"type":"string","nullable":true},"exp_month":{"type":"integer"},"exp_year":{"type":"integer"},"token_type":{"type":"string","enum":["pan","dpan"],"description":"\"pan\" = the buyer's real card (step-up meaningful); \"dpan\" = device token, already authenticated."}}}}}}}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/wallets/apple-pay-session":{"post":{"tags":["Wallets"],"operationId":"createApplePaySession","summary":"Mint an Apple Pay merchant session","security":[{"bearerAuth":[]}],"description":"Called automatically by paysio.js during onvalidatemerchant — you normally never call it yourself. Live mode requires the serving domain to be registered (see the domains endpoints); test mode accepts any domain.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domain"],"properties":{"validation_url":{"type":"string","description":"The validationURL Apple handed the browser."},"domain":{"type":"string","description":"The exact FQDN serving the page (window.location.hostname)."}}}}}},"responses":{"200":{"description":"The opaque Apple merchant session (5-minute TTL, single-use).","content":{"application/json":{"schema":{"type":"object","properties":{"session":{"type":"object"}}}}}},"400":{"description":"Apple Pay not enabled, or the domain is not registered (code \"domain_not_registered\").","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"}}}}}}}}},"/wallets/apple-pay/domains":{"get":{"tags":["Wallets"],"operationId":"listApplePayDomains","summary":"List Apple Pay domains","security":[{"bearerAuth":[]}],"description":"Domains registered for Apple Pay on this workspace, per environment (a test key reads the sandbox registration, a live key reads production).","responses":{"200":{"description":"The registration state.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ApplePayDomains"}}}}}}}},"post":{"tags":["Wallets"],"operationId":"addApplePayDomain","summary":"Register an Apple Pay domain","security":[{"bearerAuth":[]}],"description":"Register a merchant-hosted domain for the Apple Pay button. In live mode the domain must already serve the Paysio domain-association file at /.well-known/apple-developer-merchantid-domain-association (download it from https://paysio.com at the same path); Paysio verifies the file, then registers the domain with Apple.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string","description":"Fully qualified domain, e.g. \"shop.example.com\"."}}}}}},"responses":{"201":{"description":"The updated registration state.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ApplePayDomains"}}}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/wallets/apple-pay/domains/{domain}":{"delete":{"tags":["Wallets"],"operationId":"removeApplePayDomain","summary":"Remove an Apple Pay domain","security":[{"bearerAuth":[]}],"description":"Remove a registered domain. Paysio-managed domains (paysio.com and the workspace custom domain) cannot be removed.","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated registration state.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ApplePayDomains"}}}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/transactions":{"get":{"tags":["Transactions"],"operationId":"listTransactions","summary":"List transactions","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/startingAfter"},{"name":"customer_id","in":"query","schema":{"type":"string"}},{"name":"subscription_id","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"A paginated list of transactions.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Transaction"}},"has_more":{"type":"boolean"}}}}}}}}},"/transactions/{id}":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"get":{"tags":["Transactions"],"operationId":"getTransaction","summary":"Retrieve a transaction","responses":{"200":{"description":"A transaction.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Transaction"}}}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/transactions/{id}/void":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"post":{"tags":["Transactions"],"operationId":"voidTransaction","summary":"Void a transaction","security":[{"bearerAuth":[]}],"description":"Cancel a charge before it settles. Only valid while the transaction is still pending settlement — once settled, refund it instead.","responses":{"200":{"description":"The voided transaction.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Transaction"}}}}}},"400":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/transactions/{id}/refund":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"post":{"tags":["Transactions"],"operationId":"refundTransaction","summary":"Refund a transaction","security":[{"bearerAuth":[]}],"description":"Refund a settled charge, fully or partially. Omit amount to refund everything still outstanding. Partial refunds may be repeated up to the original amount.","requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefundCreate"}}}},"responses":{"200":{"description":"The refunded transaction.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Transaction"}}}}}},"400":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/disputes":{"get":{"tags":["Disputes"],"operationId":"listDisputes","summary":"List disputes","description":"Pre-chargeback alerts (Ethoca, CDRN, Visa RDR), chargebacks, TC40 fraud reports, ACH returns, and reversals. Read-only — refunding an alert, fighting, or accepting happens in the dashboard.","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/startingAfter"},{"name":"status","in":"query","schema":{"type":"string"},"description":"Filter by status. Comma-separate for multiple values, e.g. \"new,matched\"."},{"name":"kind","in":"query","schema":{"type":"string"},"description":"Filter by kind. Comma-separate for multiple values, e.g. \"chargeback,ach_return\"."},{"name":"transaction_id","in":"query","schema":{"type":"string"},"description":"Disputes raised against one transaction."}],"responses":{"200":{"description":"A paginated list of disputes.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Dispute"}},"has_more":{"type":"boolean"}}}}}}}}},"/disputes/{id}":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"get":{"tags":["Disputes"],"operationId":"getDispute","summary":"Retrieve a dispute","description":"Returns the dispute object at the top level (no data wrapper) with an extra events array — the case timeline, newest first.","responses":{"200":{"description":"A dispute with its event timeline.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Dispute"},{"type":"object","properties":{"events":{"type":"array","description":"Case timeline, newest first. Types include \"created\", \"matched\", \"refunded\", \"outcome_sent\", \"accepted\", \"fight_started\", \"evidence_submitted\", \"represented\", \"won\", and \"lost\".","items":{"type":"object","properties":{"type":{"type":"string"},"created_at":{"type":"string","format":"date-time"}}}}}}]}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/subscriptions":{"get":{"tags":["Subscriptions"],"operationId":"listSubscriptions","summary":"List subscriptions","description":"Supports metadata filtering via ?metadata[key]=value.","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/startingAfter"}],"responses":{"200":{"description":"A paginated list of subscriptions.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Subscription"}},"has_more":{"type":"boolean"}}}}}}}},"post":{"tags":["Subscriptions"],"operationId":"createSubscription","summary":"Create a subscription","security":[{"bearerAuth":[]}],"description":"Charge a stored customer on a recurring product. The first payment is taken immediately unless start_date is in the future. The customer must already have a saved payment method — on Paysio Debit & Payouts it must be a Paysio-vaulted one (they completed a checkout, or you saved a card via POST /customers or POST /customers/{id}/payment-methods).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionCreate"}}}},"responses":{"201":{"description":"The created subscription.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Subscription"}}}}}},"400":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/subscriptions/{id}":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"get":{"tags":["Subscriptions"],"operationId":"getSubscription","summary":"Retrieve a subscription","responses":{"200":{"description":"A subscription.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Subscription"}}}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/subscriptions/{id}/cancel":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"post":{"tags":["Subscriptions"],"operationId":"cancelSubscription","summary":"Cancel a subscription","security":[{"bearerAuth":[]}],"description":"Defaults to cancelling at the end of the current period (the customer keeps access to what they paid for). Pass immediate: true to end it now.","requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionCancel"}}}},"responses":{"200":{"description":"The cancelled (or scheduled-to-cancel) subscription.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Subscription"}}}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/subscriptions/{id}/pause":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"post":{"tags":["Subscriptions"],"operationId":"pauseSubscription","summary":"Pause a subscription","security":[{"bearerAuth":[]}],"description":"Stop billing without cancelling. Resume later with POST /subscriptions/{id}/resume.","responses":{"200":{"description":"The paused subscription.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Subscription"}}}}}},"400":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/subscriptions/{id}/resume":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"post":{"tags":["Subscriptions"],"operationId":"resumeSubscription","summary":"Resume a subscription","security":[{"bearerAuth":[]}],"description":"Restart a paused subscription, or clear a pending end-of-period cancellation.","responses":{"200":{"description":"The resumed subscription.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Subscription"}}}}}},"400":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/checkout-sessions":{"post":{"tags":["Checkout Sessions"],"operationId":"createCheckoutSession","summary":"Create a hosted or embedded checkout session","security":[{"bearerAuth":[]}],"description":"Create a hosted payment page or an Embedded Checkout client secret. Paysio collects contact and payment data, supports Quick Checkout, runs 3DS, and vaults the method. Embedded Checkout automatically shows eligible Apple Pay and Google Pay buttons according to the workspace Gateway settings; no separate wallet argument is required.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutSessionCreate"}}}},"responses":{"201":{"description":"Redirect to `url` in hosted mode or pass `client_secret` to paysio.mountCheckout() in embedded mode.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CheckoutSession"}}}}}},"400":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/checkout-sessions/{id}":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"get":{"tags":["Checkout Sessions"],"operationId":"getCheckoutSession","summary":"Retrieve a checkout session","description":"Poll for status, or read it after the buyer returns to your success_url.","responses":{"200":{"description":"A checkout session.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CheckoutSession"}}}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/payouts":{"get":{"tags":["Payouts"],"operationId":"listPayouts","summary":"List payouts","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/startingAfter"},{"name":"customer_id","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","paid","failed","canceled"]}}],"responses":{"200":{"description":"A paginated list of payouts.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Payout"}},"has_more":{"type":"boolean"}}}}}}}},"post":{"tags":["Payouts"],"operationId":"createPayout","summary":"Send a payout","security":[{"bearerAuth":[]}],"description":"Requires Paysio Debit & Payouts. Provide amount, customer_id, and exactly ONE destination: payment_method_id (the id from GET payment-methods, must be payout_eligible), payment_token (a ptok_), or bank_account.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayoutCreate"}}}},"responses":{"200":{"description":"The created payout (status pending; settles via webhook).","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Payout"}}}}}},"400":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"}}}},"/payouts/{id}":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"get":{"tags":["Payouts"],"operationId":"getPayout","summary":"Retrieve a payout","responses":{"200":{"description":"A payout.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Payout"}}}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/payout-links":{"get":{"tags":["Payout Links"],"operationId":"listPayoutLinks","summary":"List payout links","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/startingAfter"},{"name":"type","in":"query","schema":{"type":"string","enum":["directed","request"]}},{"name":"status","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"A paginated list of payout links.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PayoutLink"}},"has_more":{"type":"boolean"}}}}}}}},"post":{"tags":["Payout Links"],"operationId":"createPayoutLink","summary":"Create a payout link","security":[{"bearerAuth":[]}],"description":"Requires Paysio Debit & Payouts. type \"directed\" (default) holds amount + fee against your balance and emails the recipient a claim link; type \"request\" creates a reusable form (see Payout Requests).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayoutLinkCreate"}}}},"responses":{"201":{"description":"The created payout link.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PayoutLink"}}}}}},"400":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"}}}},"/payout-links/{id}":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"get":{"tags":["Payout Links"],"operationId":"getPayoutLink","summary":"Retrieve a payout link","responses":{"200":{"description":"A payout link.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PayoutLink"}}}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/payout-links/{id}/cancel":{"post":{"tags":["Payout Links"],"operationId":"cancelPayoutLink","summary":"Cancel a payout link","security":[{"bearerAuth":[]}],"description":"Cancel a pending directed link (or an active request link) and release the held balance.","parameters":[{"$ref":"#/components/parameters/pathId"}],"responses":{"200":{"description":"The cancelled payout link.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PayoutLink"}}}}}},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"}}}},"/payout-requests":{"get":{"tags":["Payout Requests"],"operationId":"listPayoutRequests","summary":"List payout requests","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/startingAfter"},{"name":"payout_link_id","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","approved","rejected","failed"]}}],"responses":{"200":{"description":"A paginated list of payout requests.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PayoutRequest"}},"has_more":{"type":"boolean"}}}}}}}}},"/payout-requests/{id}":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"get":{"tags":["Payout Requests"],"operationId":"getPayoutRequest","summary":"Retrieve a payout request","responses":{"200":{"description":"A payout request.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PayoutRequest"}}}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/payout-requests/{id}/approve":{"post":{"tags":["Payout Requests"],"operationId":"approvePayoutRequest","summary":"Approve and pay a request","security":[{"bearerAuth":[]}],"description":"Runs the money-out to the card captured at submit time. Send an optional `amount` (cents) to pay a different figure than was asked for — the original ask is kept as `requested_amount`. 400 if balance is insufficient (the request reverts to pending); 409 if no longer pending.","parameters":[{"$ref":"#/components/parameters/pathId"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"amount":{"type":"integer","minimum":1,"description":"Cents to send instead of the requested amount. Omit to pay what was asked for."}}}}}},"responses":{"200":{"description":"The approved payout request.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PayoutRequest"}}}}}},"400":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"}}}},"/payout-requests/{id}/reject":{"post":{"tags":["Payout Requests"],"operationId":"rejectPayoutRequest","summary":"Reject a request","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/pathId"}],"responses":{"200":{"description":"The rejected payout request.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PayoutRequest"}}}}}},"409":{"$ref":"#/components/responses/Error"}}}},"/balance":{"get":{"tags":["Balance"],"operationId":"getBalance","summary":"Retrieve the Debit & Payouts balance","parameters":[{"name":"currency","in":"query","schema":{"type":"string","default":"USD"}}],"responses":{"200":{"description":"The merchant balance.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Balance"}}}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/account-checks":{"post":{"tags":["Account Checks"],"operationId":"createAccountCheck","summary":"Pre-flight a payout destination","security":[{"bearerAuth":[]}],"description":"Requires Paysio Debit & Payouts. Verify whether a card can receive push-to-card funds (and on which network/speed), or which RTP rails a bank supports, before sending a payout. Card responses also carry additive `bin` and `card_type_consensus` objects sourced from an independent BIN directory; both may be null and neither changes any pre-existing field.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"payment_token":{"type":"string"},"customer_id":{"type":"string"},"payment_method_id":{"type":"string"},"card":{"type":"object","properties":{"number":{"type":"string"},"exp_month":{"type":"string"},"exp_year":{"type":"string"}}},"bank_account":{"type":"object","properties":{"routing_number":{"type":"string"}}}}}}}},"responses":{"200":{"description":"Eligibility result.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AccountCheck"}}}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/tokens":{"post":{"tags":["Tokens"],"operationId":"createToken","summary":"Tokenize a card server-side","description":"Returns a single-use ptok_ token (15-minute TTL) you can pass to /charges or /payouts. Sensitive — prefer the Paysio.js iframe (which calls this for you) for browser collection to stay out of PCI scope.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["number","exp_month","exp_year"],"properties":{"number":{"type":"string"},"exp_month":{"type":"string"},"exp_year":{"type":"string"},"cvv":{"type":"string"}}}}}},"responses":{"200":{"description":"A payment token.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"token":{"type":"string","example":"ptok_abc123"},"card":{"type":"object","properties":{"last4":{"type":"string"},"brand":{"type":"string"},"exp_month":{"type":"string"},"exp_year":{"type":"string"}}}}}}}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/three-ds/initialize":{"post":{"tags":["3D Secure"],"operationId":"initializeThreeDs","summary":"Initialize 3DS device fingerprinting","description":"Starts the issuer device-fingerprint step and returns transaction_info plus optional hidden-iframe HTML. Render device_fingerprint_html, wait about 3 seconds, then pass transaction_info to /three-ds/authenticate. Paysio.js performs this sequencing automatically.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"},"card_id":{"type":"string"},"payment_method_id":{"type":"string"}}}}}},"responses":{"200":{"description":"3DS transaction identifiers and optional fingerprint HTML.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"transaction_info":{"type":"object"},"device_fingerprint_html":{"type":"string","nullable":true}}}}}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/three-ds/authenticate":{"post":{"tags":["3D Secure"],"operationId":"authenticateThreeDs","summary":"Start a 3D Secure authentication","description":"Runs 3DS for a vaulted card before you charge it. Identify the card with a ptok_ token (a NEW card — resolved server-side and NOT consumed, so you can still charge it), a payment_method_id (a SAVED card on file — same id you pass to POST /charges), or a card_id. Saved-card 3DS requires that the customer has already used that method at your business. For direct integrations, initialize device fingerprinting first and echo transaction_info here. Returns a terminal status for frictionless flows, or a challenge when required, then poll /three-ds/finish until terminal. If the card's brand has no acquirer profile configured for your account, returns { skipped: true, status: \"SKIPPED\", reason: \"no_acquirer_profile\" } instead of an error — proceed with the charge and omit three_ds (SKIPPED is unrelated to the workspace 3D Secure toggle; the endpoint authenticates whenever called). The Paysio.js threeDS helper handles initialization, fingerprinting, challenge rendering, and polling for you. Requires the Paysio vault to be enabled for the workspace; the Settings > Checkout 3D Secure toggle gates only the automatic Paysio.js/hosted flows, not direct calls to this endpoint.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreeDsAuthenticate"}}}},"responses":{"200":{"description":"The 3DS authentication result. When challenge_required is true (status non-terminal), render the challenge and poll /three-ds/finish until status is terminal.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ThreeDsResult"}}}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/three-ds/finish":{"post":{"tags":["3D Secure"],"operationId":"finishThreeDs","summary":"Complete the 3DS challenge","description":"Fetch the terminal 3DS result after a challenge. Once the challenge returned by /three-ds/authenticate has been rendered, poll this endpoint (~every 3s) until the status is terminal (Y / A / N / U / R), then pass eci/cavv/xid to POST /charges. Frictionless authentications are already terminal from /three-ds/authenticate and do not need this call. A response containing an `error` field means authentication failed — stop polling.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreeDsFinish"}}}},"responses":{"200":{"description":"The 3DS result. Keep polling while the status is non-terminal.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ThreeDsResult"}}}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/payment-links":{"get":{"tags":["Payment Links"],"operationId":"listPaymentLinks","summary":"List payment links","description":"Read-only. Payment links are mode-aware: a test key sees test links, a live key sees live links. `url` is the exact public checkout URL (custom domain when active). Requires the payment_links:read scope on scoped keys.","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/startingAfter"},{"name":"status","in":"query","schema":{"type":"string"},"description":"Filter by status, e.g. \"active\"."}],"responses":{"200":{"description":"A paginated list of payment links.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PaymentLink"}},"has_more":{"type":"boolean"}}}}}}}}},"/payment-links/{id}":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"get":{"tags":["Payment Links"],"operationId":"getPaymentLink","summary":"Retrieve a payment link","description":"Returns the payment link object at the top level (no data wrapper).","responses":{"200":{"description":"A payment link.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentLink"}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/fulfillments":{"get":{"tags":["Fulfillments"],"operationId":"listFulfillments","summary":"List fulfillments for a transaction","description":"Requires the fulfillments:read scope on scoped keys. `fulfillment_status` is the order’s own roll-up (\"unfulfilled\" or \"fulfilled\").","parameters":[{"name":"transaction_id","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The fulfillments on the transaction plus the order roll-up.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Fulfillment"}},"fulfillment_status":{"type":"string","enum":["unfulfilled","fulfilled"]},"has_more":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Fulfillments"],"operationId":"createFulfillment","summary":"Mark an order fulfilled","security":[{"bearerAuth":[]}],"description":"All-or-nothing: creates a fulfillment covering every line item on the transaction and sets the order fulfillment status (no partial line-item selection, no customer notification). 400 with code \"already_fulfilled\" when the order is already fully fulfilled. Requires the fulfillments:write scope on scoped keys.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FulfillmentCreate"}}}},"responses":{"200":{"description":"The created fulfillment, returned at the top level (no data wrapper).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Fulfillment"}}}},"400":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/account":{"get":{"tags":["Account"],"operationId":"getAccount","summary":"Retrieve the account","description":"The workspace this credential belongs to — identity and branding only. Returned at the top level (no data wrapper). Requires the account:read scope on scoped keys.","responses":{"200":{"description":"The account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"404":{"$ref":"#/components/responses/Error"}}},"patch":{"tags":["Account"],"operationId":"updateAccount","summary":"Update the account","security":[{"bearerAuth":[]}],"description":"Update branding: name, logo_url, timezone. slug, currency, subdomain and custom_domain are read-only here — each one silently breaks live URLs, prices, or a domain binding, so they stay dashboard actions. Requires the account:write scope on scoped keys.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountUpdate"}}}},"responses":{"200":{"description":"The updated account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/members":{"get":{"tags":["Members"],"operationId":"listMembers","summary":"List team members","description":"Name, email and role only — read-only by design (there is no members:write scope). Requires the members:read scope on scoped keys.","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/startingAfter"}],"responses":{"200":{"description":"A paginated list of members.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Member"}},"has_more":{"type":"boolean"}}}}}}}}},"/storefronts":{"get":{"tags":["Storefronts"],"operationId":"listStorefronts","summary":"List storefronts","description":"Status and live URL only; the generated HTML is not exposed. Requires the storefronts:read scope on scoped keys.","responses":{"200":{"description":"The workspace storefronts.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Storefront"}},"has_more":{"type":"boolean"}}}}}}}}},"/pixels":{"get":{"tags":["Pixels"],"operationId":"getPixels","summary":"Retrieve pixel configuration","description":"The marketing pixel IDs wired into checkout. Returned at the top level (no data wrapper). Requires the pixels:read scope on scoped keys.","responses":{"200":{"description":"The pixels object.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Pixels"}}}},"404":{"$ref":"#/components/responses/Error"}}},"patch":{"tags":["Pixels"],"operationId":"updatePixels","summary":"Update pixel configuration","security":[{"bearerAuth":[]}],"description":"Send only the fields to change: empty string or null clears a pixel, an omitted field is left alone. Requires the pixels:write scope on scoped keys.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PixelsUpdate"}}}},"responses":{"200":{"description":"The updated pixels object.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Pixels"}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/blocks":{"post":{"tags":["Apps"],"operationId":"createAppBlock","summary":"Attach or replace a customer-facing block","security":[{"bearerAuth":[]}],"description":"App access token (pat_) only — a merchant API key gets 403 app_required. Blocks are rendered by Paysio on the confirmation page, the customer portal, and the receipt email. Upserts on (app install, object, block type), so a retrying webhook handler corrects its block instead of duplicating it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppBlockCreate"}}}},"responses":{"200":{"description":"The block, returned at the top level (no data wrapper).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppBlock"}}}},"400":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}},"get":{"tags":["Apps"],"operationId":"listAppBlocks","summary":"List this app’s blocks on an object","security":[{"bearerAuth":[]}],"description":"App access token (pat_) only.","parameters":[{"name":"object_type","in":"query","required":true,"schema":{"type":"string","enum":["transaction","customer","subscription"]}},{"name":"object_id","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The app’s blocks on the object.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AppBlock"}},"has_more":{"type":"boolean"}}}}}},"403":{"$ref":"#/components/responses/Error"}}}},"/blocks/{id}":{"parameters":[{"$ref":"#/components/parameters/pathId"}],"delete":{"tags":["Apps"],"operationId":"deleteAppBlock","summary":"Remove a block","security":[{"bearerAuth":[]}],"description":"App access token (pat_) only. Scoped to the install — an app can only ever delete its own blocks.","responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","example":"app_block"},"deleted":{"type":"boolean"}}}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/files":{"post":{"tags":["Apps"],"operationId":"uploadFile","summary":"Upload a file","security":[{"bearerAuth":[]}],"description":"App access token (pat_) only; requires the files:write scope. Multipart upload, field name \"file\", max 10 MB. Allowed types: application/pdf, image/png, image/jpeg, image/gif, image/webp, text/plain, text/csv, application/json, application/zip (no HTML or SVG). The returned id is the storage key; the url is public and immutable. There is no list endpoint — keep the returned ids.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"The file to upload."}}}}}},"responses":{"200":{"description":"The stored file, returned at the top level (no data wrapper).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppFile"}}}},"400":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}}}},"/files/{id}":{"delete":{"tags":["Apps"],"operationId":"deleteFile","summary":"Delete a file","security":[{"bearerAuth":[]}],"description":"App access token (pat_) only; requires the files:write scope. {id} is the storage key returned at upload (path-shaped — append it verbatim after /files/). 404 for any key outside this app’s own prefix.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The storage key returned by POST /files."}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","example":"file"},"deleted":{"type":"boolean"}}}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/emails":{"post":{"tags":["Apps"],"operationId":"sendEmail","summary":"Send an email to a workspace customer","security":[{"bearerAuth":[]}],"description":"App access token (pat_) only; requires the emails:send scope. Sends as the merchant: the sender address is resolved from the workspace and its white-label brand, never from the request, and the recipient must already be a customer of the workspace. Rate limited to 500 sends per app install per hour (429 beyond that). Test-mode sends succeed but are NOT delivered (delivered: false).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailSend"}}}},"responses":{"200":{"description":"The send result, returned at the top level (no data wrapper).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Email"}}}},"400":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/app-data":{"get":{"tags":["Apps"],"operationId":"listAppData","summary":"List stored keys","security":[{"bearerAuth":[]}],"description":"App access token (pat_) only; no scope required (the store is bounded by the app's own install). Per-install key-value storage for zero-backend apps. Values are omitted from the list - fetch a single key for its value. Storage is per install and per mode (a test token cannot read or write live rows), and rows are deleted 30 days after the app is uninstalled.","responses":{"200":{"description":"The app's stored keys, values omitted.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"app_data"},"key":{"type":"string"},"updated":{"type":"integer","description":"Unix seconds."}}}}}}}}},"403":{"$ref":"#/components/responses/Error"}}}},"/app-data/{key}":{"parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"},"description":"1-128 characters of letters, digits and ._:- only."}],"get":{"tags":["Apps"],"operationId":"getAppData","summary":"Retrieve a stored value","security":[{"bearerAuth":[]}],"description":"App access token (pat_) only. 404 when nothing is stored under the key.","responses":{"200":{"description":"The stored entry, returned at the top level (no data wrapper).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppData"}}}},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}},"put":{"tags":["Apps"],"operationId":"putAppData","summary":"Create or replace a stored value","security":[{"bearerAuth":[]}],"description":"App access token (pat_) only. Values are any JSON up to 64KB; an install can hold at most 500 keys per mode (400 with code \"limit_exceeded\" beyond that). A settings/state store for zero-backend apps, not a database.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppDataPut"}}}},"responses":{"200":{"description":"The stored entry, returned at the top level (no data wrapper).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppData"}}}},"400":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}}},"delete":{"tags":["Apps"],"operationId":"deleteAppData","summary":"Delete a stored key","security":[{"bearerAuth":[]}],"description":"App access token (pat_) only. Idempotent - deleting a missing key succeeds with deleted: false.","responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"app_data"},"key":{"type":"string"},"deleted":{"type":"boolean"}}}}}},"403":{"$ref":"#/components/responses/Error"}}}},"/oauth/token":{"post":{"tags":["Apps"],"operationId":"exchangeToken","summary":"Exchange an ID token for an app access token","servers":[{"url":"https://api.paysio.com","description":"Token exchange lives OUTSIDE /v1 — call it at https://api.paysio.com/oauth/token."}],"security":[],"description":"RFC 8693 token exchange: trade the 60-second ID token an app’s frontend received for a pat_ access token its backend can use against /v1. Accepts JSON or form encoding. No Authorization header — the client credentials go in the body. Errors use the OAuth shape { error, error_description }.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthTokenRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/OAuthTokenRequest"}}}},"responses":{"200":{"description":"The access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthTokenResponse"}}}},"400":{"description":"OAuth error, e.g. unsupported_grant_type.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"401":{"description":"invalid_client or invalid_grant.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"403":{"description":"App suspended, not installed on the workspace, or no scopes granted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"A secret (sk_live_ / sk_test_) or publishable (pk_live_ / pk_test_) API key. Write operations require a secret key. The key’s mode (live vs test) selects the live or sandbox environment."}},"parameters":{"limit":{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"description":"Page size (1-100)."},"startingAfter":{"name":"starting_after","in":"query","schema":{"type":"string"},"description":"Cursor — the id of the last item from the previous page."},"pathId":{"name":"id","in":"path","required":true,"schema":{"type":"string"}}},"responses":{"Error":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable message (wording may change — do not branch on it)."},"type":{"type":"string","description":"Stable, machine-branchable error category.","enum":["invalid_request_error","authentication_error","card_error","permission_error","not_found_error","idempotency_error","rate_limit_error","api_error"]},"code":{"type":"string","description":"More specific machine-readable code where one applies (e.g. resource_missing)."}},"required":["error","type"]},"Product":{"type":"object","properties":{"object":{"type":"string","example":"product"},"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"images":{"type":"array","items":{"type":"string"}},"pricingType":{"type":"string","enum":["one_time","recurring","open_ended"]},"price":{"type":"integer","nullable":true,"description":"Price in cents."},"currency":{"type":"string"},"billingPeriod":{"type":"string","nullable":true},"active":{"type":"boolean","description":"Inverse of archived; true means purchasable."},"archived":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}},"ProductCreate":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"description":{"type":"string"},"images":{"type":"array","items":{"type":"string"}},"pricingType":{"type":"string","enum":["one_time","recurring","open_ended"]},"price":{"type":"integer"},"currency":{"type":"string"},"billingPeriod":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"category":{"type":"string"},"active":{"type":"boolean","description":"Default true. Set false to create archived/hidden."}}},"ProductUpdate":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"price":{"type":"integer"},"currency":{"type":"string"},"active":{"type":"boolean","description":"Set false to archive, true to unarchive (preferred over archived)."},"archived":{"type":"boolean","description":"Legacy alias for the inverse of active."}}},"Invoice":{"type":"object","properties":{"object":{"type":"string","example":"invoice"},"id":{"type":"string"},"invoiceNumber":{"type":"integer","nullable":true},"invoiceLabel":{"type":"string","example":"INV-00019"},"status":{"type":"string","enum":["draft","sent","viewed","processing","paid","void"],"description":"processing = a Debit & Payouts payment was accepted and is settling; it becomes paid, or returns to sent with the link reactivated if the payment fails."},"customerId":{"type":"string","nullable":true},"customerEmail":{"type":"string"},"customerName":{"type":"string","nullable":true},"items":{"type":"array","items":{"type":"object","properties":{"productId":{"type":"string"},"productName":{"type":"string"},"quantity":{"type":"integer"},"unitPrice":{"type":"integer","description":"cents"},"currency":{"type":"string"}}}},"subtotal":{"type":"integer"},"taxAmount":{"type":"integer"},"discountCode":{"type":"string","nullable":true},"discountAmount":{"type":"integer"},"amount":{"type":"integer","description":"Total in cents"},"currency":{"type":"string"},"dueDate":{"type":"string","format":"date-time","nullable":true},"memo":{"type":"string","nullable":true},"hosted_invoice_url":{"type":"string"},"pay_url":{"type":"string","nullable":true,"description":"Checkout URL; null until the invoice has been sent."},"emailed":{"type":"boolean","description":"Only on send responses: whether an email actually went out."},"sentAt":{"type":"string","format":"date-time","nullable":true},"paidAt":{"type":"string","format":"date-time","nullable":true},"transactionId":{"type":"string","nullable":true},"sandbox":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}},"InvoiceCreate":{"type":"object","required":["items"],"properties":{"customer_email":{"type":"string","description":"Required unless customer_id is given."},"customer_id":{"type":"string"},"customer_name":{"type":"string"},"items":{"type":"array","items":{"type":"object","required":["product_id","quantity"],"properties":{"product_id":{"type":"string"},"quantity":{"type":"integer"},"unit_price":{"type":"integer","description":"Cents. Required for open_ended products; optional rate override for one_time products. Checkout charges exactly this."}}}},"discount_code":{"type":"string"},"memo":{"type":"string"},"descriptor":{"type":"string"},"due_date":{"type":"string","format":"date"},"send":{"type":"boolean","description":"Create and send in one call."}}},"Customer":{"type":"object","properties":{"object":{"type":"string","example":"customer"},"id":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string","nullable":true},"lastName":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"billingAddress1":{"type":"string","nullable":true},"billingCity":{"type":"string","nullable":true},"billingState":{"type":"string","nullable":true},"billingPostalCode":{"type":"string","nullable":true},"billingCountry":{"type":"string","nullable":true},"processorType":{"type":"string","enum":["nmi","stripe","aptpay"],"description":"Gateway the customer’s saved methods live on. Only aptpay customers can receive payouts."},"createdAt":{"type":"string","format":"date-time"}}},"CustomerCreate":{"type":"object","required":["email"],"properties":{"email":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"phone":{"type":"string"},"billing_address_1":{"type":"string"},"billing_city":{"type":"string"},"billing_state":{"type":"string"},"billing_postal_code":{"type":"string"},"billing_country":{"type":"string"},"payment_token":{"type":"string","description":"Optional — vault a card in the same call."},"cc_number":{"type":"string"},"cc_exp_month":{"type":"string"},"cc_exp_year":{"type":"string"}}},"CustomerUpdate":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"phone":{"type":"string"},"billing_address_1":{"type":"string"},"billing_city":{"type":"string"},"billing_state":{"type":"string"},"billing_postal_code":{"type":"string"},"billing_country":{"type":"string"}}},"AccountCheck":{"type":"object","description":"Card or bank eligibility result. Card fields below; bank checks return routing_number, bank_name, rtp and ach_eligible instead.","additionalProperties":true,"properties":{"object":{"type":"string","example":"account_check"},"type":{"type":"string","enum":["card","bank"]},"eligible":{"type":"boolean","description":"Card: whether it can RECEIVE a push payout (receiving === true)."},"receiving":{"type":"boolean","nullable":true,"description":"Money-OUT: can this card receive pushed funds. From the payout network."},"sending":{"type":"boolean","nullable":true,"description":"Money-IN: can funds be pulled from this card. From the payout network. Advisory — the issuer makes the final decision."},"network":{"type":"string","nullable":true,"description":"Card network as reported by the payout network. Compare with bin.scheme, which is sourced independently."},"funds_availability":{"type":"string","nullable":true,"description":"How fast a payout to this card lands, e.g. \"immediate\"."},"card_type":{"type":"string","nullable":true,"description":"Card type as reported by the payout network. Unchanged; see card_type_consensus for the reconciled view."},"country":{"type":"string","nullable":true},"currency":{"type":"string","nullable":true},"bin":{"type":"object","nullable":true,"additionalProperties":true,"description":"Independent BIN-range data. Null when unavailable or the BIN could not be derived from the request.","properties":{"bin":{"type":"string"},"scheme":{"type":"string","nullable":true,"enum":["visa","mastercard","amex","discover","jcb","unionpay","diners","unknown"]},"funding":{"type":"string","nullable":true,"enum":["debit","credit","prepaid"],"description":"Null when the record failed the trust check."},"brand":{"type":"string","nullable":true},"category":{"type":"string","nullable":true,"description":"Issuer product tier, e.g. \"SIGNATURE\", \"INFINITE\", \"BUSINESS\"."},"country":{"type":"string","nullable":true,"description":"ISO 3166-1 alpha-2."},"country_name":{"type":"string","nullable":true},"issuer":{"type":"string","nullable":true},"currency":{"type":"string","nullable":true},"prepaid":{"type":"boolean","nullable":true},"commercial":{"type":"boolean","nullable":true},"trusted":{"type":"boolean","description":"False means the record failed our sanity check and contributed nothing to card_type_consensus."}}},"card_type_consensus":{"type":"object","nullable":true,"additionalProperties":true,"description":"Reconciliation of the payout network card type with the BIN directory.","properties":{"card_type":{"type":"string","enum":["debit","credit","prepaid","unknown"]},"source":{"type":"string","enum":["agreed","aptpay","aptpay-kept","directory","veto"],"description":"How card_type was settled. \"veto\" = the BIN directory overruled a debit/prepaid to credit; \"directory\" = it filled in a type the network did not give."},"agrees":{"type":"boolean","description":"False when the two sources reported different card types."},"reason":{"type":"string"}}}}},"PaymentMethod":{"type":"object","properties":{"id":{"type":"string","description":"Payment method id — OPAQUE, do not parse or construct it. Pass as payment_method_id on POST /charges, /payouts, /account-checks and /three-ds/authenticate. Paysio-vaulted methods look like \"vault_<uuid>\"; legacy ones are the gateway instrument id. Both are accepted everywhere."},"billing_id":{"type":"string","description":"Alias of id (backwards compatibility)."},"type":{"type":"string","enum":["card","bank_account"]},"processor":{"type":"string","enum":["paysio_vault","nmi","stripe","aptpay"],"description":"\"paysio_vault\" = stored in the Paysio vault (default for cards on NMI / Debit & Payouts accounts); otherwise the gateway holding a legacy instrument."},"payout_eligible":{"type":"boolean","description":"Whether this method can be a POST /payouts destination. Requires Debit & Payouts, then reflects the method itself: banks and debit/prepaid cards are eligible; a known CREDIT card (or one flagged unable to receive funds) is false — push-to-card only settles on debit rails. Unclassified cards default to true and are re-verified at send time. Gateway-agnostic: a card saved while charging on NMI can still receive a payout. Stripe pm_ / legacy NMI ids are never eligible."},"card_last_four":{"type":"string","nullable":true},"bank_last_four":{"type":"string","nullable":true},"card_type":{"type":"string","nullable":true},"cc_exp":{"type":"string","nullable":true},"card_bin":{"type":"string","nullable":true,"description":"Issuer BIN for cards; null for bank accounts."},"is_default":{"type":"boolean","description":"The customer's default method — charged when customer_id is sent with no payment_method_id."}}},"PaymentMethodCreate":{"type":"object","description":"Provide ONE option: payment_token; OR cc_number + cc_exp_month + cc_exp_year; OR type=bank_account with routing_number + account_number.","properties":{"type":{"type":"string","enum":["card","bank_account"],"default":"card"},"payment_token":{"type":"string"},"cc_number":{"type":"string"},"cc_exp_month":{"type":"string"},"cc_exp_year":{"type":"string"},"routing_number":{"type":"string"},"account_number":{"type":"string"},"account_type":{"type":"string","enum":["checking","saving"]},"description":{"type":"string"}}},"Transaction":{"type":"object","properties":{"object":{"type":"string","example":"transaction"},"id":{"type":"string"},"orderNumber":{"type":"integer","nullable":true},"customerId":{"type":"string","nullable":true},"processorType":{"type":"string","description":"Gateway that actually processed the charge. With Smart Routing on this may differ from the workspace default — a debit card is routed to \"aptpay\" and a credit card to the NMI-family gateway."},"amount":{"type":"integer","description":"Amount in cents."},"currency":{"type":"string"},"status":{"type":"string","enum":["pending_settlement","declined","error","blocked","disputed"]},"cardLastFour":{"type":"string","nullable":true},"cardType":{"type":"string","nullable":true},"riskScore":{"type":"integer","nullable":true,"description":"Fraud risk score out of 100, from velocity, the buyer history with this merchant, and whether the card, address and connection agree. Scoring is on by default; null means the merchant switched it off, which is not the same as a score of zero. Configure it under Settings > Risk scoring."},"riskDecision":{"type":"string","nullable":true,"enum":["allow","review","block"],"description":"What the score did. \"allow\" charged normally; \"review\" charged normally and flagged the payment for the merchant. \"block\" refused it before the gateway saw it (403, code \"blocked\") and only ever occurs when the merchant has separately opted in to refusing payments, which is off by default — so on the defaults the highest possible verdict is \"review\"."},"bank_auth_status":{"type":"string","enum":["awaiting","authorized","expired"],"description":"Instant ACH only. \"awaiting\" until the payer completes the hosted bank authorization; \"authorized\" once the payment settles; \"expired\" if they never finish within 3 hours (the charge then fails). Absent on all other charges."},"bank_auth_url":{"type":"string","nullable":true,"description":"Instant ACH only. Hosted page where a FIRST-TIME payer authorizes their bank — send them here. Returning payers get no URL and nothing to do."},"metadata":{"type":"object"},"sandbox":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}},"RefundCreate":{"type":"object","properties":{"amount":{"type":"integer","description":"Amount to refund in cents. Omit to refund everything still outstanding on the transaction."},"send_email":{"type":"boolean","default":true,"description":"Send the Paysio refund email to the customer. Debit & Payouts only — the other gateways send no refund email."}}},"Dispute":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","example":"dispute"},"kind":{"type":"string","enum":["alert_ethoca","alert_cdrn","alert_rdr","chargeback","tc40","ach_return","reversal"]},"status":{"type":"string","enum":["new","matched","unmatched","refunded","accepted","fighting","response_submitted","won","lost","expired"]},"transaction_id":{"type":"string","nullable":true,"description":"The matched Paysio transaction, or null while unmatched."},"network":{"type":"string","nullable":true,"description":"Card network (e.g. \"visa\"), when known."},"reason":{"type":"string","nullable":true,"description":"Human-readable dispute reason."},"reason_code":{"type":"string","nullable":true,"description":"Network reason code (e.g. \"10.4\")."},"amount":{"type":"integer","description":"Disputed amount in cents."},"currency":{"type":"string"},"card_bin":{"type":"string","nullable":true,"description":"First six digits of the disputed card."},"card_last4":{"type":"string","nullable":true,"description":"Last four digits of the disputed card."},"due_at":{"type":"string","format":"date-time","nullable":true,"description":"Response deadline, when the network set one."},"alerted_at":{"type":"string","format":"date-time","nullable":true,"description":"When the alert or chargeback was raised."},"response_submitted":{"type":"boolean","description":"Whether a chargeback response has been submitted."},"sandbox":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"Subscription":{"type":"object","properties":{"id":{"type":"string"},"customerId":{"type":"string","nullable":true},"productId":{"type":"string","nullable":true},"status":{"type":"string","enum":["active","scheduled","paused","cancelled","past_due"]},"amount":{"type":"integer","description":"Recurring amount in cents (excluding tax/shipping)."},"taxAmount":{"type":"integer","nullable":true},"shippingAmount":{"type":"integer","nullable":true},"discountAmount":{"type":"integer","nullable":true},"currency":{"type":"string"},"billingPeriod":{"type":"string","description":"Billing interval, e.g. \"monthly\" or \"yearly\"."},"currentPeriodStart":{"type":"string","format":"date-time","nullable":true},"currentPeriodEnd":{"type":"string","format":"date-time","nullable":true},"nextBillingDate":{"type":"string","format":"date-time","nullable":true},"cancelAtPeriodEnd":{"type":"boolean","description":"Still active, but will not renew at the end of the current period."},"pausedAt":{"type":"string","format":"date-time","nullable":true},"cancelledAt":{"type":"string","format":"date-time","nullable":true},"customerEmail":{"type":"string","nullable":true},"productName":{"type":"string","nullable":true},"metadata":{"type":"object"},"sandbox":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}},"SubscriptionCreate":{"type":"object","required":["customer_id","product_id"],"properties":{"customer_id":{"type":"string","description":"Customer with a saved payment method."},"product_id":{"type":"string","description":"A recurring product."},"payment_method_id":{"type":"string","description":"Charge a SPECIFIC saved method instead of the customer's default. Use an id from GET /customers/{id}/payment-methods (the \"vault_…\" form or the bare UUID). Must belong to this customer and have been used at your business, else 400 — a subscription is never silently created against a different card."},"start_date":{"type":"string","format":"date-time","description":"ISO 8601. If in the future the subscription is created with status \"scheduled\" and nothing is charged until then."},"metadata":{"type":"object"}}},"SubscriptionCancel":{"type":"object","properties":{"at_period_end":{"type":"boolean","description":"Cancel when the current period ends (the default when the subscription is active with time remaining)."},"immediate":{"type":"boolean","description":"Cancel right now instead of at period end."},"reason":{"type":"string","description":"Optional free-text reason stored on the subscription."}}},"CheckoutSession":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"ui_mode":{"type":"string","enum":["hosted","embedded"]},"payment_methods":{"type":"array","nullable":true,"items":{"type":"string","enum":["card","bank","apple_pay","google_pay"]},"description":"The session's payment method restriction, or null when it uses the workspace's configured methods."},"show_order_summary":{"type":"boolean","description":"Whether Embedded Checkout renders the order summary, totals, and promo-code controls. Hosted checkout always shows it."},"email_field_mode":{"type":"string","enum":["editable","read_only","hidden"],"description":"Embedded email-field behavior."},"phone_field_mode":{"type":"string","enum":["editable","read_only","hidden"],"description":"Embedded phone-field behavior."},"quick_checkout_behavior":{"type":"string","enum":["on_input","on_load","disabled"],"description":"When Embedded Checkout checks the supplied email for Quick Checkout."},"client_secret":{"type":"string","description":"Returned only for embedded mode. Pass it to paysio.mountCheckout and keep it out of logs and analytics."},"embed_url":{"type":"string","description":"Direct embedded document URL. Prefer paysio.mountCheckout for origin validation and automatic resizing."},"url":{"type":"string","description":"Hosted payment page — redirect the buyer here."},"success_url":{"type":"string","nullable":true},"status":{"type":"string","enum":["open","completed","expired"]},"expires_at":{"type":"string","format":"date-time","nullable":true},"completed_at":{"type":"string","format":"date-time","nullable":true},"transaction_id":{"type":"string","nullable":true},"order_number":{"type":"integer","nullable":true,"description":"Sequential order number. Present after completion."},"order_label":{"type":"string","nullable":true,"description":"Display-ready order number, such as #00019. Present after completion."},"metadata":{"type":"object","nullable":true},"sandbox":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}}},"CheckoutSessionCreate":{"type":"object","required":["line_items"],"properties":{"line_items":{"type":"array","minItems":1,"description":"Each item is either { product_id, quantity, unit_price? } for an existing product, or { name, amount, quantity } to define one inline (amount in cents). unit_price (cents) pins the line to that rate: required for open_ended products, optional for one_time ones, not allowed on recurring ones.","items":{"type":"object","properties":{"product_id":{"type":"string"},"quantity":{"type":"integer"},"unit_price":{"type":"integer","description":"Cents. Pins this line to a unit price (required for open_ended products)."},"name":{"type":"string"},"amount":{"type":"integer","description":"Ad-hoc price in cents; must be positive."}}}},"success_url":{"type":"string","description":"Where to send the buyer after payment."},"ui_mode":{"type":"string","enum":["hosted","embedded"],"default":"hosted","description":"Use embedded to mount the complete checkout form inside your page."},"show_order_summary":{"type":"boolean","default":false,"description":"Embedded mode only. Show Paysio's order summary with line items, totals, tax, shipping, recurring charges, and promo-code controls."},"email_field_mode":{"type":"string","enum":["editable","read_only","hidden"],"default":"editable","description":"Embedded mode only. read_only and hidden require customer_email."},"phone_field_mode":{"type":"string","enum":["editable","read_only","hidden"],"default":"editable","description":"Embedded mode only. read_only requires customer_phone. Hidden also requires it when the workspace requires phone collection."},"quick_checkout_behavior":{"type":"string","enum":["on_input","on_load","disabled"],"default":"on_input","description":"Embedded mode only. on_input preserves normal typed-email detection; on_load checks customer_email immediately; disabled suppresses Quick Checkout. A remembered session resumes only when its identity matches customer_email."},"allowed_parent_origins":{"type":"array","items":{"type":"string"},"description":"Required in embedded mode. Exact HTTPS origins allowed to frame the checkout. HTTP is accepted only for localhost development."},"customer_email":{"type":"string","format":"email","description":"Optional authoritative email prefill. A remembered Quick Checkout session cannot replace it and resumes only when the emails match."},"customer_phone":{"type":"string","description":"Optional phone prefill. Quick Checkout SMS codes go only to a phone already verified on the customer record."},"expires_at":{"type":"string","format":"date-time","description":"Optional expiry. Embedded sessions default to 24 hours and cannot exceed 7 days."},"appearance":{"type":"object","description":"Embedded Checkout theme defaults. Runtime appearance passed to mountCheckout overrides these values.","properties":{"variables":{"type":"object","properties":{"colorPrimary":{"type":"string"},"colorBackground":{"type":"string"},"colorText":{"type":"string"},"colorTextMuted":{"type":"string"},"colorBorder":{"type":"string"},"borderRadius":{"type":"string"},"buttonBorderRadius":{"type":"string"},"fontFamily":{"type":"string"},"fontSize":{"type":"string"}}},"fonts":{"type":"array","items":{"type":"object","properties":{"cssSrc":{"type":"string","format":"uri"}}}}}},"discount_code":{"type":"string"},"metadata":{"type":"object"},"payment_methods":{"type":"array","nullable":true,"items":{"type":"string","enum":["card","bank","apple_pay","google_pay"]},"description":"Restrict which payment methods this checkout offers. Must include at least card or bank. Omitted = the workspace's configured methods. Always intersected with what the workspace actually supports — this narrows the offered methods, never adds ones the workspace doesn't have."}}},"ApplePayDomains":{"type":"object","properties":{"object":{"type":"string","example":"apple_pay_domains"},"mode":{"type":"string","enum":["test","live"]},"status":{"type":"string","enum":["registered","pending","failed","unregistered"]},"domains":{"type":"array","items":{"type":"object","properties":{"domain":{"type":"string"},"managed_by_paysio":{"type":"boolean","description":"Paysio-managed domains (paysio.com, the workspace custom domain) cannot be removed."}}}},"last_error":{"type":"string","nullable":true},"registered_at":{"type":"string","nullable":true}}},"ChargeCreate":{"type":"object","properties":{"amount":{"type":"integer","description":"Amount in cents. Provide this OR product_id OR line_items."},"currency":{"type":"string"},"customer_id":{"type":"string"},"payment_token":{"type":"string"},"stripe_payment_method_id":{"type":"string"},"payment_method_id":{"type":"string","description":"Charge a SPECIFIC saved card or bank account instead of the customer's default. Use an id from GET /customers/:id/payment-methods (\"vault_…\" or the bare uuid). To 3D-Secure a saved card, pass this SAME id to /three-ds/authenticate first, then send the result here as three_ds."},"product_id":{"type":"string"},"quantity":{"type":"integer"},"line_items":{"type":"array","items":{"type":"object","properties":{"product_id":{"type":"string"},"quantity":{"type":"integer"},"unit_price":{"type":"integer","description":"Cents. Bill at this rate instead of the catalog price; required for open_ended products."},"name":{"type":"string"},"amount":{"type":"integer"}}}},"description":{"type":"string"},"save_payment_method":{"type":"boolean"},"cvc":{"type":"string","description":"Required per-charge on Paysio Debit & Payouts."},"send_email":{"type":"boolean","default":true,"description":"Send the Paysio receipt email to the buyer. Set false to send your own; nothing else changes."},"email":{"type":"string","description":"Buyer email. Without customer_id, the customer is found-or-created and linked to the charge."},"first_name":{"type":"string"},"last_name":{"type":"string"},"phone":{"type":"string"},"billing_address_1":{"type":"string","description":"Billing street address. STRONGLY RECOMMENDED on every card charge: the address is stored on the saved card and reused for AVS on later charges and renewals."},"billing_city":{"type":"string","description":"Billing city. Send alongside billing_address_1 on every card charge."},"billing_state":{"type":"string","description":"Billing state / province. Send alongside billing_address_1 on every card charge."},"billing_postal_code":{"type":"string","description":"Billing postal code. REQUIRED for paying money back out to this card later (refund to card, payout link, disbursement) — a card saved without one is rejected at payout time with \"No billing ZIP on file for this recipient\". Billing data passed to 3DS authentication is consumed by the issuer and is NOT stored, so it is not a substitute for sending it here."},"billing_country":{"type":"string","description":"Billing country (ISO-2, e.g. \"US\"). On Paysio Debit & Payouts send a complete, valid US address; a mismatch (non-US postal code with country \"US\") is rejected with \"Request validation failed\"."},"paysio_wallet":{"type":"object","description":"An Apple Pay / Google Pay payload from the paysio.js walletPayment event (data.paysioWallet), forwarded VERBATIM. Paysio decrypts the wallet token server-side and charges it on the workspace card gateway. Cannot be combined with payment_token, a gateway override, or rail \"ach\". `three_ds` is accepted ONLY when this payload carries `prepared` (a 3DS-stepped-up Google Pay credential from POST /wallets/prepare); device tokens refuse it because they are already authenticated. The encrypted credential is single-use and expires within minutes; charge it immediately and never store it.","properties":{"type":{"type":"string","enum":["apple_pay","google_pay"]},"apple_payment_data":{"type":"object","description":"token.paymentData from the Apple Pay sheet (Apple only)."},"google_token":{"type":"string","description":"paymentMethodData.tokenizationData.token, the JSON string from the Google Pay sheet (Google only)."},"prepared":{"type":"string","description":"Sealed credential from POST /wallets/prepare. Use instead of google_token when a 3DS step-up ran, and send the authentication as `three_ds`."},"info":{"type":"object","description":"Sheet display info (card_network, card_details, card_funding_source).","properties":{"card_network":{"type":"string"},"card_details":{"type":"string"},"card_funding_source":{"type":"string"}}}}},"wallet_type":{"type":"string","enum":["apple_pay","google_pay"],"description":"Stripe-gateway wallets only, sent alongside the pm_ payment_token from Stripe's wallet flow. Never needed with paysio_wallet — the type is inside the payload."},"wallet":{"type":"object","description":"Wallet payer contact from the paysio.js walletPayment event (data.wallet). Forward it so wallet charges find-or-create the customer; the sheet's billingInfo address feeds AVS, the transaction, the customer, and any vaulted card (explicit billing_* body fields win), and shippingInfo is stored on the transaction's shipping fields — matching hosted checkout.","properties":{"payerName":{"type":"string"},"payerEmail":{"type":"string"},"payerPhone":{"type":"string"},"billingInfo":{"type":"object","description":"Sheet billing address: firstName, lastName, address1, address2, city, state, postalCode, country, phone."},"shippingInfo":{"type":"object","description":"Sheet shipping address (collectShipping wallets), same shape as billingInfo."}}},"gateway":{"type":"string","enum":["nmi","paysio","stripe","aptpay"],"description":"Per-request gateway override for a NEW-card charge. Omit to use the workspace default (and to allow Smart Routing). Must be configured for the workspace, else 400. A saved method stays locked to its own gateway — a conflicting value returns 400. Passing this disables Smart Routing for the request."},"rail":{"type":"string","enum":["card","ach"],"description":"Default \"card\". \"ach\" debits a bank account (saved via payment_method_id, or inline via routing_number + account_number); routed by the workspace bank processor."},"return_url":{"type":"string","maxLength":255,"description":"Instant ACH (Open Banking) opt-in, Paysio Debit & Payouts only. Http(s) URL on your site where the payer lands after completing the hosted bank authorization. With the workspace \"Instant bank debits\" setting on, the debit attempts the instant rail; a first-time payer gets bank_auth_url back. Omit for standard ACH."},"three_ds":{"type":"object","description":"The COMPLETE result of a prior 3DS authentication — pass the object returned by Paysio.js threeDS.authenticate() (or /three-ds/finish) through verbatim. Send every field you received; do NOT cherry-pick per gateway. Paysio maps and forwards exactly what the routed acquirer requires, and an omitted field can silently cost you the liability shift. Required on EVERY charge you want authenticated, including charges against a saved payment_method_id — nothing is attached automatically, and a charge sent without it authorizes with no cryptogram and records no 3DS data.","properties":{"status":{"type":"string","description":"Y = authenticated, A = attempted, N = denied, U = unavailable, R = rejected."},"eci":{"type":"string","description":"Electronic Commerce Indicator."},"authenticationValue":{"type":"string","description":"CAVV/AAV cryptogram."},"dsTransId":{"type":"string","description":"Directory Server Transaction ID."},"threeDSServerTransID":{"type":"string","description":"3DS Server Transaction ID (XID)."},"threeDsVersion":{"type":"string","description":"Protocol version, e.g. \"2.2.0\"."}}},"three_ds_status":{"type":"string","description":"Flat alternative to three_ds.status. Flat fields take precedence over the three_ds object; use one style or the other."},"three_ds_eci":{"type":"string","description":"Flat alternative to three_ds.eci."},"three_ds_cavv":{"type":"string","description":"Flat alternative to three_ds.authenticationValue."},"three_ds_directory_server_id":{"type":"string","description":"Flat alternative to three_ds.dsTransId."},"three_ds_xid":{"type":"string","description":"Flat alternative to three_ds.threeDSServerTransID."},"three_ds_version":{"type":"string","description":"Flat alternative to three_ds.threeDsVersion."},"three_ds_cardholder_auth":{"type":"string","description":"Optional cardholder auth hint (\"verified\" / \"attempted\"). Derived from status when omitted."},"metadata":{"type":"object"}}},"Payout":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","example":"payout"},"payout_number":{"type":"integer"},"amount":{"type":"integer","description":"Amount in cents the recipient receives."},"currency":{"type":"string"},"status":{"type":"string","enum":["pending","paid","failed","canceled"]},"rail":{"type":"string","enum":["card","ach","rtp"]},"rtp_network":{"type":"string","nullable":true},"card_last_four":{"type":"string","nullable":true},"card_brand":{"type":"string","nullable":true},"descriptor":{"type":"string","nullable":true},"customer_id":{"type":"string","nullable":true},"payout_link_id":{"type":"string","nullable":true,"description":"Source Payout Link, when the payout came from one."},"payout_request_id":{"type":"string","nullable":true,"description":"Source Payout Request, for approved request links."},"reference_id":{"type":"string","nullable":true},"error_code":{"type":"string","nullable":true},"error_message":{"type":"string","nullable":true},"returned":{"type":"boolean","description":"True once a SETTLED payout was sent back by the receiving bank (ACH return). status stays \"paid\" and error_code stays null, so check this rather than status."},"returned_at":{"type":"string","format":"date-time","nullable":true,"description":"When the return arrived."},"return_code":{"type":"string","nullable":true,"description":"NACHA return code, e.g. \"R03\"."},"return_reason":{"type":"string","nullable":true,"description":"The bank's own reason, e.g. \"NO ACCOUNT FOUND\"."},"metadata":{"type":"object"},"livemode":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}}},"BankAccount":{"type":"object","required":["routing_number","account_number"],"properties":{"routing_number":{"type":"string","description":"9 digits."},"account_number":{"type":"string","description":"4-17 digits."},"account_type":{"type":"string","enum":["checking","saving"]}}},"PayoutCreate":{"type":"object","required":["amount","customer_id"],"description":"Provide amount, customer_id, and exactly ONE destination.","properties":{"amount":{"type":"integer","description":"Amount in cents the recipient receives. Fee-exclusive: the payout fee is charged on top, so your balance is debited amount + fee."},"currency":{"type":"string","default":"USD"},"customer_id":{"type":"string"},"payment_method_id":{"type":"string","description":"A payout_eligible method id from GET /customers/:id/payment-methods. A Paysio-vaulted id (\"vault_…\") works regardless of the charging gateway — the Debit & Payouts instrument is minted on demand."},"payment_token":{"type":"string","description":"A one-time ptok_ card token."},"bank_account":{"$ref":"#/components/schemas/BankAccount"},"rail":{"type":"string","enum":["card","ach","rtp"]},"rtp_network":{"type":"string","enum":["TCH","FedNow"]},"descriptor":{"type":"string","maxLength":10},"reference_id":{"type":"string","description":"Idempotency key."},"metadata":{"type":"object"},"send_email":{"type":"boolean","default":true,"description":"Send the Paysio \"money is on the way\" email to the recipient. Set false to notify them yourself; nothing else changes."}}},"Balance":{"type":"object","properties":{"object":{"type":"string","example":"balance"},"available":{"type":"integer","description":"Spendable balance in cents (settled minus in-flight payouts)."},"pending_payouts":{"type":"integer","description":"Total reserved by in-flight payouts, in cents."},"currency":{"type":"string"},"livemode":{"type":"boolean"}}},"PayoutLink":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","example":"payout_link"},"payout_link_number":{"type":"integer","nullable":true},"payout_link_label":{"type":"string","nullable":true},"type":{"type":"string","enum":["directed","request"]},"slug":{"type":"string"},"url":{"type":"string","description":"Public claim URL to share with the recipient."},"amount":{"type":"integer","description":"Cents the recipient receives (directed). 0 for request links."},"currency":{"type":"string"},"recipient_email":{"type":"string","nullable":true},"note":{"type":"string","nullable":true},"allowed_rails":{"type":"array","items":{"type":"string","enum":["card","ach","rtp"]}},"custom_fields":{"type":"array","items":{"type":"object"}},"restrict_to_existing_customers":{"type":"boolean"},"max_request_amount":{"type":"integer","nullable":true,"description":"Request only. Cents. The most a requester may ask for; null = no limit."},"status":{"type":"string","description":"directed: pending|claiming|paid|cancelled|expired|failed; request: active|cancelled."},"payout_id":{"type":"string","nullable":true,"description":"The payout created once a directed link is claimed."},"claimed_at":{"type":"string","format":"date-time","nullable":true},"expires_at":{"type":"string","format":"date-time","nullable":true},"metadata":{"type":"object"},"sandbox":{"type":"boolean"},"livemode":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}}},"PayoutLinkCreate":{"type":"object","description":"Directed links require amount + recipient_email. Requires Paysio Debit & Payouts.","properties":{"type":{"type":"string","enum":["directed","request"],"default":"directed"},"amount":{"type":"integer","description":"Directed only. Cents the recipient receives (link holds amount + fee)."},"recipient_email":{"type":"string","description":"Directed only. The claim is locked to this email."},"currency":{"type":"string","default":"USD"},"note":{"type":"string","maxLength":300},"allowed_rails":{"type":"array","items":{"type":"string","enum":["card","ach","rtp"]}},"custom_fields":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"type":{"type":"string","enum":["text","textarea","number","select","checkbox"]},"required":{"type":"boolean"},"options":{"type":"array","items":{"type":"string"}}}}},"expires_in_days":{"type":"integer","minimum":1,"maximum":90,"default":7,"description":"Directed only. Request links never expire."},"restrict_to_existing_customers":{"type":"boolean","description":"Request only."},"max_request_amount":{"type":"integer","nullable":true,"minimum":1,"description":"Request only. Cents. The most a requester may ask for; omit or null for no limit."},"slug":{"type":"string","description":"Optional custom slug (auto-generated when omitted)."},"metadata":{"type":"object"}}},"PayoutRequest":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","example":"payout_request"},"payout_link_id":{"type":"string"},"requester_email":{"type":"string"},"requester_name":{"type":"string","nullable":true},"amount":{"type":"integer","description":"Cents the requester will receive — the decided amount, which may differ from what was asked for."},"requested_amount":{"type":"integer","nullable":true,"description":"The original ask, set only when the request was approved for a different amount."},"currency":{"type":"string"},"note":{"type":"string","nullable":true},"status":{"type":"string","enum":["pending","approving","approved","rejected","failed"]},"customer_id":{"type":"string","nullable":true},"card_last_four":{"type":"string","nullable":true},"card_bin":{"type":"string","nullable":true},"payout_id":{"type":"string","nullable":true,"description":"The payout created once approved."},"reviewed_at":{"type":"string","format":"date-time","nullable":true},"metadata":{"type":"object"},"sandbox":{"type":"boolean"},"livemode":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}}},"ThreeDsAuthenticate":{"type":"object","required":["amount","browser","redirect_url"],"description":"Identify the card with ONE of token / card_id / payment_method_id (the card is resolved from the Paysio vault server-side — raw PAN is not used here), plus amount, browser, and a public redirect_url. Requires the Paysio vault + 3DS to be enabled for the workspace.","properties":{"amount":{"type":"number","description":"Charge amount in MAJOR units (e.g. 29.99) — note: unlike charges/payouts, this is not in cents."},"currency":{"type":"string","default":"USD","description":"ISO currency code used for the 3DS risk assessment."},"browser":{"type":"object","description":"Device fingerprint collected in the browser (browserUserAgent, browserLanguage, browserColorDepth, browserScreenHeight, browserScreenWidth, browserTZ, browserJavaEnabled, browserJavaScriptEnabled, ...). Paysio.js builds this for you."},"billing":{"type":"object","description":"Billing address. Send country as ISO alpha-2 (for example, US). Paysio.js forwards this object so 3DS selects the same Smart Routing gateway and acquirer profile as the subsequent charge."},"billing_country":{"type":"string","description":"ISO alpha-2 billing country alias. Use the same value on the subsequent charge so 3DS and authorization select the same gateway."},"redirect_url":{"type":"string","description":"A PUBLIC challenge return URL (localhost is rejected). Alias: threeDSRequestorURL."},"token":{"type":"string","description":"A ptok_ payment token from POST /tokens or paysio.createToken(). Resolves the vault card server-side; not consumed by 3DS. Provide one of token / card_id / payment_method_id."},"card_id":{"type":"string","description":"A Paysio vault card id. Provide one of token / card_id / payment_method_id."},"payment_method_id":{"type":"string","description":"A saved payment method id (its vault card is used). Provide one of token / card_id / payment_method_id."},"transaction_info":{"type":"object","nullable":true,"description":"The { xid, merchantTransactionId } returned by /three-ds/initialize. Paysio.js supplies this automatically."}}},"ThreeDsFinish":{"type":"object","required":["transaction_info"],"description":"Identify the same card you authenticated with ONE of token / card_id / payment_method_id, plus the transaction_info echoed from /three-ds/authenticate.","properties":{"token":{"type":"string","description":"The ptok_ token used for /three-ds/authenticate. Provide one of token / card_id / payment_method_id."},"card_id":{"type":"string","description":"The vault card id used for /three-ds/authenticate."},"payment_method_id":{"type":"string","description":"The saved payment method id used for /three-ds/authenticate."},"transaction_info":{"type":"object","required":["xid","merchantTransactionId"],"description":"Echoed verbatim from the /three-ds/authenticate response.","properties":{"xid":{"type":"string"},"merchantTransactionId":{"type":"string"}}}}},"ThreeDsResult":{"type":"object","description":"Once terminal, forward ALL of these fields to POST /charges (as the three_ds object or the flat three_ds_* fields). Send everything you got — Paysio decides per gateway what the acquirer actually needs; leaving a field out can silently drop the liability shift.","properties":{"status":{"type":"string","description":"Terminal: Y = authenticated, A = attempted, N = denied, U = unavailable, R = rejected. Non-terminal while a challenge is outstanding — poll /three-ds/finish until terminal."},"challenge_required":{"type":"boolean","description":"authenticate only — true when the issuer requires a challenge. Render `challenge`, then poll /three-ds/finish."},"challenge":{"type":"object","nullable":true,"description":"authenticate only — present when challenge_required. The SDK renders this for you.","properties":{"form":{"type":"string","nullable":true,"description":"A self-submitting HTML form that POSTs to the issuer ACS."},"url":{"type":"string","nullable":true,"description":"The ACS challenge URL."},"creq":{"type":"string","nullable":true,"description":"The EMV 3DS challenge request to POST to the ACS when form is absent."},"session_data":{"type":"string","nullable":true,"description":"Optional threeDSSessionData value to include with creq."}}},"eci":{"type":"string","nullable":true,"description":"Electronic Commerce Indicator — pass as three_ds_eci to POST /charges for liability shift."},"cavv":{"type":"string","nullable":true,"description":"CAVV/AAV — cryptographic proof of authentication (pass as three_ds_cavv)."},"xid":{"type":"string","nullable":true,"description":"3DS transaction id (pass as three_ds_xid). Also echoed in transaction_info."},"ds_trans_id":{"type":"string","nullable":true,"description":"Directory Server Transaction ID (pass as three_ds_directory_server_id)."},"version":{"type":"string","nullable":true,"description":"3DS protocol version (e.g. \"2.2.0\")."},"transaction_info":{"type":"object","nullable":true,"description":"{ xid, merchantTransactionId } — pass back to /three-ds/finish to poll for the terminal result."},"device_fingerprint_html":{"type":"string","nullable":true,"description":"authenticate only — optional device-fingerprint HTML to render before the challenge. The SDK handles this."}}},"PaymentLink":{"type":"object","properties":{"object":{"type":"string","example":"payment_link"},"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string","description":"The public checkout URL — the merchant custom domain when one is active, paysio.com otherwise."},"status":{"type":"string"},"mode":{"type":"string","enum":["live","test"],"description":"Check this before driving paid traffic at a link."},"collect_shipping_address":{"type":"boolean"},"payment_methods":{"type":"array","nullable":true,"items":{"type":"string"}},"success_url":{"type":"string","nullable":true},"metadata":{"type":"object"},"items":{"type":"array","items":{"type":"object","properties":{"product_id":{"type":"string"},"name":{"type":"string"},"quantity":{"type":"integer"},"images":{"type":"array","items":{"type":"string"}}}}},"created":{"type":"integer","description":"Unix seconds."}}},"Fulfillment":{"type":"object","properties":{"object":{"type":"string","example":"fulfillment"},"id":{"type":"string"},"transaction_id":{"type":"string"},"status":{"type":"string","example":"fulfilled"},"tracking_number":{"type":"string","nullable":true},"tracking_carrier":{"type":"string","nullable":true},"tracking_url":{"type":"string","nullable":true},"note":{"type":"string","nullable":true},"items":{"type":"array","items":{"type":"object","properties":{"product_id":{"type":"string","nullable":true},"product_name":{"type":"string"},"quantity":{"type":"integer"}}}},"created":{"type":"integer","description":"Unix seconds."}}},"FulfillmentCreate":{"type":"object","required":["transaction_id"],"properties":{"transaction_id":{"type":"string","description":"The transaction to fulfill. Must belong to your workspace."},"tracking_number":{"type":"string","maxLength":200},"tracking_carrier":{"type":"string","maxLength":60},"tracking_url":{"type":"string","maxLength":2000},"note":{"type":"string","maxLength":1000}}},"Account":{"type":"object","description":"Identity and branding only — processor and fee configuration is deliberately not exposed.","properties":{"object":{"type":"string","example":"account"},"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"logo_url":{"type":"string","nullable":true},"currency":{"type":"string"},"timezone":{"type":"string"},"subdomain":{"type":"string","nullable":true,"description":"Where the storefront and hosted pages live when there is no custom domain."},"custom_domain":{"type":"string","nullable":true,"description":"Null unless the merchant custom domain is ACTIVE."}}},"AccountUpdate":{"type":"object","description":"At least one field is required. slug, currency, subdomain and custom_domain are read-only.","properties":{"name":{"type":"string","maxLength":120},"logo_url":{"type":"string","nullable":true,"description":"Empty string or null clears the logo."},"timezone":{"type":"string","description":"IANA timezone, e.g. \"America/New_York\"."}}},"Member":{"type":"object","properties":{"object":{"type":"string","example":"member"},"id":{"type":"string","description":"Membership id — the cursor for starting_after."},"user_id":{"type":"string"},"name":{"type":"string","nullable":true},"email":{"type":"string"},"avatar_url":{"type":"string","nullable":true},"role":{"type":"string","example":"owner"},"created":{"type":"integer","description":"Unix seconds."}}},"Storefront":{"type":"object","properties":{"object":{"type":"string","example":"storefront"},"id":{"type":"string"},"status":{"type":"string","example":"published"},"url":{"type":"string","nullable":true,"description":"The live URL (custom domain or paysio.com subdomain); null while unpublished or no subdomain is claimed."},"published":{"type":"boolean"},"created":{"type":"integer","description":"Unix seconds."},"updated":{"type":"integer","description":"Unix seconds."}}},"Pixels":{"type":"object","description":"Public pixel identifiers only — ad-platform access tokens are never stored here.","properties":{"object":{"type":"string","example":"pixels"},"meta_pixel_id":{"type":"string","nullable":true},"google_conversion_id":{"type":"string","nullable":true},"google_conversion_label":{"type":"string","nullable":true},"tiktok_pixel_id":{"type":"string","nullable":true}}},"PixelsUpdate":{"type":"object","description":"Send only the fields to change. Empty string or null clears a pixel; an omitted field is left alone. At least one field is required.","properties":{"meta_pixel_id":{"type":"string","nullable":true},"google_conversion_id":{"type":"string","nullable":true},"google_conversion_label":{"type":"string","nullable":true},"tiktok_pixel_id":{"type":"string","nullable":true}}},"AppBlock":{"type":"object","properties":{"object":{"type":"string","example":"app_block"},"id":{"type":"string"},"object_type":{"type":"string","enum":["transaction","customer","subscription"]},"object_id":{"type":"string"},"type":{"type":"string","enum":["details","download","status","link"]},"payload":{"type":"object","description":"The sanitized block content as stored."},"position":{"type":"integer"},"created":{"type":"integer","description":"Unix seconds."}}},"AppBlockCreate":{"type":"object","required":["object_type","object_id","type","payload"],"properties":{"object_type":{"type":"string","enum":["transaction","customer","subscription"],"description":"A transaction block reaches the buyer and the merchant; customer and subscription blocks reach the merchant on that record’s page."},"object_id":{"type":"string","description":"Must belong to the merchant workspace (404 otherwise)."},"type":{"type":"string","enum":["details","download","status","link"]},"payload":{"type":"object","description":"details/download: { title, description?, items: [{ label, value?, url?, copyable?, expires_at? }] } with at least one item carrying a value or url. status: { title, status, description?, items? }. link: { url, label, title?, description? }. Text is plain text (angle brackets stripped); urls must be https or mailto."},"position":{"type":"integer","minimum":0,"maximum":999,"default":0}}},"AppFile":{"type":"object","properties":{"object":{"type":"string","example":"file"},"id":{"type":"string","description":"The storage key — pass it to DELETE /files/{id}."},"url":{"type":"string","description":"Public, immutable CDN URL."},"filename":{"type":"string","nullable":true,"description":"The original filename, echoed back for your records."},"content_type":{"type":"string"},"size":{"type":"integer","description":"Bytes."},"mode":{"type":"string","enum":["live","test"]}}},"EmailSend":{"type":"object","required":["subject","body"],"description":"One of customer_id / to is required.","properties":{"customer_id":{"type":"string","description":"The customer to email (preferred)."},"to":{"type":"string","description":"Raw address — must match an existing customer of the workspace (403 recipient_not_allowed otherwise)."},"subject":{"type":"string","maxLength":200},"body":{"type":"string","maxLength":100000,"description":"Plain text; paragraphs split on blank lines and are rendered into a branded shell."},"heading":{"type":"string","maxLength":200,"description":"Optional heading shown in the email (defaults to the subject)."}}},"Email":{"type":"object","properties":{"object":{"type":"string","example":"email"},"id":{"type":"string"},"to":{"type":"string"},"subject":{"type":"string"},"delivered":{"type":"boolean","description":"Always false in test mode — sandbox sends are not delivered."},"mode":{"type":"string","enum":["live","test"]},"note":{"type":"string","description":"Present on test-mode sends only."}}},"AppData":{"type":"object","properties":{"object":{"type":"string","example":"app_data"},"key":{"type":"string"},"value":{"description":"The stored JSON value, returned verbatim."},"updated":{"type":"integer","description":"Unix seconds."}}},"AppDataPut":{"type":"object","required":["value"],"properties":{"value":{"description":"Any JSON value up to 64KB. Stored verbatim and returned as-is by GET."}}},"OAuthTokenRequest":{"type":"object","required":["grant_type","subject_token","client_id","client_secret"],"properties":{"grant_type":{"type":"string","enum":["urn:ietf:params:oauth:grant-type:token-exchange"]},"subject_token":{"type":"string","description":"The 60-second ID token the app frontend received from the embed (or paysio.idToken())."},"subject_token_type":{"type":"string","enum":["urn:ietf:params:oauth:token-type:id_token"]},"client_id":{"type":"string"},"client_secret":{"type":"string","description":"Server-side only — never ship it to a browser."},"access_type":{"type":"string","enum":["offline","online"],"default":"offline","description":"offline lasts until uninstall (background jobs); online acts as the signed-in member and expires in 24 hours."}}},"OAuthTokenResponse":{"type":"object","properties":{"access_token":{"type":"string","example":"pat_live_..."},"token_type":{"type":"string","example":"Bearer"},"scope":{"type":"string","description":"Space-separated granted scopes."},"expires_in":{"type":"integer","description":"Seconds. Present only for online tokens (86400)."},"install_id":{"type":"string"},"workspace_id":{"type":"string"},"mode":{"type":"string","enum":["live","test"],"description":"Bound from the ID token, never from the request."}}},"OAuthError":{"type":"object","description":"OAuth-shaped error, distinct from the normal { error, type, code } shape, so standard OAuth client libraries parse it.","properties":{"error":{"type":"string","example":"invalid_client"},"error_description":{"type":"string"}}}}}}