{"components":{"securitySchemes":{"BearerAuth":{"bearerFormat":"JWT","description":"JWT token from /merchants/login","scheme":"bearer","type":"http"},"HMACAuth":{"description":"API key + HMAC-SHA256 signature. Headers: X-API-Key, X-Timestamp, X-Signature. Payload: timestamp\\nMETHOD\\n/v1/path\\nbody","in":"header","name":"X-API-Key","type":"apiKey"}}},"info":{"contact":{"email":"support@fintrapay.io","name":"FintraPay Support","url":"https://fintrapay.io"},"description":"Crypto payment gateway API. Accept stablecoins across 7 blockchains with 0.4% fees.","title":"FintraPay API","version":"1.0.0"},"openapi":"3.0.3","paths":{"/balance":{"get":{"description":"Get custodial balances per token/chain.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get Balances"}},"/deposit-api/deposits":{"get":{"description":"Deposits across all of your users.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List All Deposits"}},"/deposit-api/deposits/{id}":{"get":{"description":"Get a single deposit.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get Deposit"}},"/deposit-api/users":{"get":{"description":"List your end users.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List End Users"},"post":{"description":"Register one of your own users so they can be issued persistent deposit addresses.","requestBody":{"content":{"application/json":{"schema":{"properties":{"email":{"description":"Max 255 characters","type":"string"},"external_user_id":{"description":"Your identifier for the user; unique within your account, max 255 characters","type":"string"},"label":{"description":"Max 255 characters","type":"string"},"metadata":{"description":"Arbitrary JSON. Must be valid JSON","type":"string"}},"required":["external_user_id"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Create End User"}},"/deposit-api/users/{ext_id}":{"get":{"description":"Get a user with their addresses and balances.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get End User"},"patch":{"description":"Update a user. A blocked or deactivated user is refused new deposit addresses.","requestBody":{"content":{"application/json":{"schema":{"properties":{"block_reason":{"description":"Recorded against the block","type":"string"},"email":{"description":"Max 255 characters","type":"string"},"is_active":{"description":"Deactivate without blocking","type":"boolean"},"is_blocked":{"description":"Block the user","type":"boolean"},"label":{"description":"Max 255 characters","type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Update End User"}},"/deposit-api/users/{ext_id}/addresses":{"get":{"description":"Addresses issued to this user across every chain.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List Deposit Addresses"},"post":{"description":"Issue a persistent address on one chain. Calling it again for the same user and chain returns the address already issued rather than minting a second one.","requestBody":{"content":{"application/json":{"schema":{"properties":{"blockchain":{"description":"Chain to issue on","type":"string"}},"required":["blockchain"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Create Deposit Address"}},"/deposit-api/users/{ext_id}/addresses/all":{"post":{"description":"Issue addresses on all seven chains at once.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Create All Deposit Addresses"}},"/deposit-api/users/{ext_id}/balances":{"get":{"description":"Per-token, per-chain balances for one user.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List User Balances"}},"/deposit-api/users/{ext_id}/deposits":{"get":{"description":"Deposits for one user, filterable by token, chain and status.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List User Deposits"}},"/earn/contracts":{"get":{"description":"List your earn contracts.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List Earn Contracts"},"post":{"description":"Lock stablecoins to earn daily interest.","requestBody":{"content":{"application/json":{"schema":{"properties":{"amount":{"description":"Amount to lock","type":"string"},"blockchain":{"description":"Chain","type":"string"},"currency":{"description":"Token","type":"string"},"duration_months":{"description":"Lock period: 1, 3, 6, or 12 months","type":"integer"}},"required":["amount","currency","blockchain","duration_months"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Create Earn Contract"}},"/earn/contracts/{id}":{"get":{"description":"Get a single Earn contract, including accrued and withdrawn interest.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get Earn Contract"}},"/earn/contracts/{id}/break":{"post":{"description":"End a contract before maturity. Returned principal is the deposit minus interest already withdrawn; undrawn interest is forfeited.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Break Earn Contract"}},"/earn/contracts/{id}/interest-history":{"get":{"description":"Daily interest accrual entries for a contract.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Earn Interest History"}},"/earn/contracts/{id}/withdraw-interest":{"post":{"description":"Withdraw accrued interest. Minimum $10 USD equivalent. Interest is paid from the platform treasury wallet.","requestBody":{"content":{"application/json":{"schema":{"properties":{"amount":{"description":"Amount to withdraw. Omit to withdraw all accrued interest.","type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Withdraw Earn Interest"}},"/earn/rates":{"get":{"description":"Public endpoint — no auth required. Returns current APY rates for all durations.","responses":{"200":{"description":"APY rates"}},"security":[],"summary":"Get APY Rates"}},"/earn/withdrawals":{"get":{"description":"List every interest withdrawal you've requested, across all your earn contracts, with its current status. Interest withdrawals are paid from the treasury wallet by our team, not broadcast automatically — status stays \"requested\" until sent.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List Earn Withdrawals"}},"/fees/estimate":{"post":{"description":"Quote the platform fee, network fee and resulting net amount before committing to a payout or withdrawal.","requestBody":{"content":{"application/json":{"schema":{"properties":{"amount":{"description":"Gross amount","type":"string"},"blockchain":{"description":"Chain","type":"string"},"currency":{"description":"Token","type":"string"},"fee_deduction":{"description":"\"from_amount\" (default) or \"from_balance\"","type":"string"},"type":{"description":"payout or withdrawal","type":"string"}},"required":["amount","currency","blockchain"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Estimate Fees"}},"/health":{"get":{"description":"Public endpoint — no auth required. Returns service health status.","responses":{"200":{"description":"Service healthy"}},"security":[],"summary":"Health Check"}},"/invoices":{"get":{"description":"List invoices with pagination and filters.","requestBody":{"content":{"application/json":{"schema":{"properties":{"blockchain":{"description":"Filter by blockchain","type":"string"},"currency":{"description":"Filter by token","type":"string"},"page":{"description":"Page number (default: 1)","type":"integer"},"page_size":{"description":"Items per page (default: 20, max: 100)","type":"integer"},"status":{"description":"Filter: pending, awaiting_selection, paid, confirmed, confirmed_overpaid, confirmed_underpaid, expired","type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List Invoices"},"post":{"description":"Create a stablecoin invoice. Omit currency/blockchain to let the customer choose on the hosted checkout page.","requestBody":{"content":{"application/json":{"schema":{"properties":{"accepted_chains":{"description":"Limit chains customer can pick. Omit for all.","type":"array"},"accepted_tokens":{"description":"Limit tokens customer can pick. Omit for all.","type":"array"},"amount":{"description":"Payment amount (e.g. \"100.00\")","type":"string"},"blockchain":{"description":"Chain: tron, bsc, ethereum, solana, base, arbitrum, polygon. Omit to let customer choose.","type":"string"},"cancel_url":{"description":"Redirect URL if payment expires","type":"string"},"currency":{"description":"Token: USDT, USDC, DAI, FDUSD, TUSD, PYUSD. Omit to let customer choose.","type":"string"},"expiry_minutes":{"description":"Expiration in minutes (default: 60, max: 1440)","type":"integer"},"external_id":{"description":"Your internal order/reference ID","type":"string"},"mode":{"description":"\"custodial\" (default) or \"non_custodial\"","type":"string"},"success_url":{"description":"Redirect URL after payment confirmed","type":"string"}},"required":["amount"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Create Invoice"}},"/invoices/{id}":{"get":{"description":"Get invoice by ID.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get Invoice"}},"/invoices/{id}/overpayment/accept":{"post":{"description":"Keep a customer's surplus. It stays on your balance. No request body.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Accept Overpayment"}},"/invoices/{id}/overpayment/refund":{"post":{"description":"Return a customer's surplus. Your balance is debited immediately and the amount reserved while the refund is in flight. The customer receives the overage minus the network fee. No request body.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Refund Overpayment"}},"/invoices/{id}/refunds":{"get":{"description":"Every refund issued against this invoice, including partials.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List Invoice Refunds"},"post":{"description":"Refund an invoice, in full or in part, back to the payer on the original chain and token.","requestBody":{"content":{"application/json":{"schema":{"properties":{"amount":{"description":"Amount to refund; must not exceed the unrefunded remainder","type":"string"},"reason":{"description":"Your internal reason","type":"string"}},"required":["amount"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Create Refund"}},"/merchants/me":{"get":{"description":"Get your merchant profile.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get Profile"}},"/merchants/me/api-keys":{"get":{"description":"List your API keys.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List API Keys"},"post":{"description":"Create a new API key with its own settings.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Create API Key"}},"/merchants/me/settings":{"patch":{"description":"Update webhook URL, wallet addresses, and other settings.","requestBody":{"content":{"application/json":{"schema":{"properties":{"wallet_bsc":{"description":"BSC withdrawal wallet","type":"string"},"wallet_ethereum":{"description":"Ethereum withdrawal wallet","type":"string"},"wallet_tron":{"description":"TRON withdrawal wallet","type":"string"},"webhook_url":{"description":"Callback URL for payment notifications","type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Update Settings"}},"/merchants/me/wallets":{"get":{"description":"List your registered withdrawal wallets.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List Wallets"},"post":{"description":"Register a withdrawal destination wallet for a chain.","requestBody":{"content":{"application/json":{"schema":{"properties":{"address":{"description":"Wallet address; validated for that chain's format","type":"string"},"blockchain":{"description":"Chain: tron, bsc, ethereum, solana, base, arbitrum, polygon","type":"string"},"label":{"description":"Your label for this wallet","type":"string"}},"required":["blockchain","address"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Add Wallet"}},"/merchants/me/webhook-deliveries":{"get":{"description":"Every delivery attempt for your endpoint, newest first. Use this to reconcile events you may have missed.","requestBody":{"content":{"application/json":{"schema":{"properties":{"event":{"description":"Filter by event name, e.g. invoice.paid","type":"string"},"page":{"description":"Page number (default: 1)","type":"integer"},"page_size":{"description":"Items per page (default: 20, max: 100)","type":"integer"},"status":{"description":"Filter: pending, retrying, delivered, failed, skipped","type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List Webhook Deliveries"}},"/merchants/me/webhook-deliveries/{id}":{"get":{"description":"One delivery attempt, including the request body and response code.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get Webhook Delivery"}},"/merchants/me/webhook-deliveries/{id}/resend":{"post":{"description":"Re-deliver a webhook. It is re-signed with a CURRENT timestamp, so it passes a receiver's freshness check. Rate limited to 10/min, 30s cooldown per delivery, 20 resends per delivery lifetime.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Resend Webhook"}},"/merchants/me/webhook-subscriptions":{"get":{"description":"Which events you receive. Opt-out model: an event absent from this list is ENABLED.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get Webhook Subscriptions"},"put":{"description":"Enable or disable individual events.","requestBody":{"content":{"application/json":{"schema":{"properties":{"subscriptions":{"description":"Array of {event, enabled}.","type":"array"}},"required":["subscriptions"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Update Webhook Subscriptions"}},"/merchants/stats":{"get":{"description":"Dashboard stats: total invoices, paid invoices, total volume, pending payouts/withdrawals, active earn contracts.","requestBody":{"content":{"application/json":{"schema":{"properties":{"mode":{"description":"\"custodial\" or \"non_custodial\" — restricts invoice counts/volume to that mode. Omit for both modes combined. Payouts/withdrawals/earn counts are always custodial-only.","type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get Merchant Stats"}},"/payment-links":{"get":{"description":"List your payment links.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List Payment Links"},"post":{"description":"A reusable payment URL that never expires.","requestBody":{"content":{"application/json":{"schema":{"properties":{"amount":{"description":"Required when fixed_amount is true","type":"string"},"fixed_amount":{"description":"Default true. When false the payer chooses an amount within min/max","type":"boolean"},"max_amount":{"description":"Upper bound for flexible links (default 10000.00)","type":"string"},"min_amount":{"description":"Lower bound for flexible links (default 1.00)","type":"string"},"slug":{"description":"Public URL segment; must be unique across all merchants","type":"string"},"title":{"description":"Shown on the checkout page","type":"string"}},"required":["slug","title"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Create Payment Link"}},"/payment-links/{id}":{"get":{"description":"Get a link with its total_paid and total_payments counters.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get Payment Link"},"patch":{"description":"Update a link. amount, min_amount and max_amount are validated the same way as on create, and min/max are checked against the values already stored.","requestBody":{"content":{"application/json":{"schema":{"properties":{"amount":{"description":"Must be a positive number","type":"string"},"max_amount":{"description":"Must be positive and not fall below min_amount","type":"string"},"min_amount":{"description":"Must be positive and not exceed max_amount","type":"string"},"status":{"description":"active, paused or archived. A paused link stops accepting payments","type":"string"},"title":{"description":"Display title","type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Update Payment Link"}},"/payouts":{"get":{"description":"List payouts with pagination.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List Payouts"},"post":{"description":"Send crypto to any external address.","requestBody":{"content":{"application/json":{"schema":{"properties":{"amount":{"description":"Amount to send","type":"string"},"blockchain":{"description":"Chain (tron, bsc, etc.)","type":"string"},"currency":{"description":"Token (USDT, USDC, etc.)","type":"string"},"fee_deduction":{"description":"\"from_amount\" (default) — recipient gets amount minus fees. \"from_balance\" — recipient gets exactly amount; fees debited on top.","type":"string"},"reason":{"description":"payment, refund, reward, airdrop, salary, other","type":"string"},"reference":{"description":"Your internal reference","type":"string"},"to_address":{"description":"Recipient wallet address","type":"string"}},"required":["to_address","amount","currency","blockchain"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Create Payout"}},"/payouts/batch":{"post":{"description":"Send crypto to multiple recipients in one call.","requestBody":{"content":{"application/json":{"schema":{"properties":{"blockchain":{"description":"Chain for all recipients","type":"string"},"currency":{"description":"Token for all recipients","type":"string"},"fee_deduction":{"description":"Applies to every recipient. \"from_amount\" (default) — each recipient gets amount minus the per-recipient fee (payout fee + network fee); a line not exceeding it is rejected. \"from_balance\" — each recipient gets exactly amount; the per-recipient fee is debited on top. batch.total_amount is the total debited: the sum of every payout's gross_amount.","type":"string"},"recipients":{"description":"Array of {to_address, amount, reference}. amount supports at most 8 decimal places. A validation failure returns 422 with one field error per bad recipient, keyed by array position, e.g. recipients[0].amount, recipients[2].to_address.","type":"array"}},"required":["currency","blockchain","recipients"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Batch Payout"}},"/payouts/batches":{"get":{"description":"List batch payouts.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List Payout Batches"}},"/payouts/batches/{id}":{"get":{"description":"Get a batch and its per-recipient items.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get Payout Batch"}},"/payouts/{id}":{"get":{"description":"Get a payout by ID.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get Payout"}},"/refunds":{"get":{"description":"List refunds across all invoices. Response includes a summary object (refunded_amount, pending_count, completed_count) computed over every matching refund, not just the current page.","requestBody":{"content":{"application/json":{"schema":{"properties":{"blockchain":{"description":"Filter by blockchain","type":"string"},"page":{"description":"Page number","type":"integer"},"page_size":{"description":"Items per page (max 100)","type":"integer"},"status":{"description":"pending, processed, completed, cancelled, failed","type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List Refunds"}},"/refunds/{id}":{"get":{"description":"Get a refund by ID.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get Refund"}},"/subscription-plans":{"get":{"description":"List your subscription plans.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List Plans"},"post":{"description":"A recurring billing plan.","requestBody":{"content":{"application/json":{"schema":{"properties":{"amount":{"description":"Amount charged each interval","type":"string"},"currency":{"description":"Token","type":"string"},"interval":{"description":"day, week, month or year","type":"string"},"interval_count":{"description":"Number of intervals between charges (default 1)","type":"integer"},"name":{"description":"Plan name","type":"string"}},"required":["name","amount","currency","interval"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Create Plan"}},"/subscription-plans/{id}":{"get":{"description":"Get a plan by ID.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get Plan"},"patch":{"description":"Update a plan's name, amount or status.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Update Plan"}},"/subscriptions":{"get":{"description":"List subscriptions, filterable by status and plan.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List Subscriptions"},"post":{"description":"Subscribe a customer to a plan.","requestBody":{"content":{"application/json":{"schema":{"properties":{"customer_email":{"description":"Customer identifier","type":"string"},"plan_id":{"description":"Plan to subscribe to","type":"string"}},"required":["plan_id"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Create Subscription"}},"/subscriptions/{id}":{"get":{"description":"Get a subscription and its invoice history.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get Subscription"}},"/subscriptions/{id}/cancel":{"post":{"description":"Cancel a subscription. No further invoices are raised.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Cancel Subscription"}},"/subscriptions/{id}/pause":{"post":{"description":"Pause billing without cancelling.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Pause Subscription"}},"/subscriptions/{id}/resume":{"post":{"description":"Resume a paused subscription. Billing anchors to the original billing day.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Resume Subscription"}},"/tickets":{"get":{"description":"List your support tickets.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List Tickets"},"post":{"description":"Open a support ticket.","requestBody":{"content":{"application/json":{"schema":{"properties":{"category":{"description":"Ticket category","type":"string"},"message":{"description":"First message body","type":"string"},"subject":{"description":"Ticket subject","type":"string"}},"required":["subject","message"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Create Ticket"}},"/tickets/{id}":{"get":{"description":"A ticket with its full message thread.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get Ticket"}},"/tickets/{id}/reply":{"post":{"description":"Add a message to an existing ticket.","requestBody":{"content":{"application/json":{"schema":{"properties":{"message":{"description":"Message body","type":"string"}},"required":["message"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Reply to Ticket"}},"/transfers":{"get":{"description":"Transfers in both directions; each row carries a direction of in or out.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List Transfers"},"post":{"description":"Move custodial balance to another FintraPay merchant by email. Settles on our ledger with no on-chain transaction and no network fee. Requires a one-time code from /transfers/otp.","requestBody":{"content":{"application/json":{"schema":{"properties":{"amount":{"description":"Amount to transfer","type":"string"},"blockchain":{"description":"Chain","type":"string"},"currency":{"description":"Token","type":"string"},"note":{"description":"Free-text note shown to the recipient","type":"string"},"otp":{"description":"One-time code from /transfers/otp, bound to this transfer and single use","type":"string"},"to_email":{"description":"Recipient merchant email","type":"string"}},"required":["to_email","amount","currency","blockchain","otp"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Create Internal Transfer"}},"/transfers/lookup":{"get":{"description":"Resolve a recipient email to a display name before sending.","requestBody":{"content":{"application/json":{"schema":{"properties":{"email":{"description":"Recipient merchant email","type":"string"}},"required":["email"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Look Up Recipient"}},"/transfers/otp":{"post":{"description":"Email a one-time confirmation code to the authenticated sender.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Request Transfer OTP"}},"/withdrawals":{"get":{"description":"List withdrawals with pagination.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"List Withdrawals"},"post":{"description":"Withdraw custodial balance. No flat fee — you pay the network fee only.","requestBody":{"content":{"application/json":{"schema":{"properties":{"amount":{"description":"Amount to withdraw","type":"string"},"blockchain":{"description":"Chain","type":"string"},"currency":{"description":"Token","type":"string"},"fee_deduction":{"description":"\"from_amount\" (default) — recipient gets amount minus fees. \"from_balance\" — recipient gets exactly amount; fees debited on top.","type":"string"},"to_address":{"description":"Destination; falls back to your registered wallet for this chain","type":"string"}},"required":["amount","currency","blockchain"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Create Withdrawal"}},"/withdrawals/{id}":{"get":{"description":"Get a withdrawal by ID.","responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}},"summary":"Get Withdrawal"}}},"security":[{"HMACAuth":[]},{"BearerAuth":[]}],"servers":[{"description":"Production","url":"https://fintrapay.io/v1"}]}
