{"openapi":"3.1.0","info":{"title":"NexusPay API","version":"1.0.0","description":"API-first payment aggregator for the Philippines. One integration, every channel —\nGCash, InstaPay, Maya, cards, and bank transfers.\n\n## Authentication\n\nAll requests require Bearer authentication with a secret API key in the\n`Authorization` header:\n\n```\nAuthorization: Bearer sk_test_xxx    # sandbox (no real money)\nAuthorization: Bearer sk_live_xxx    # production\n```\n\n**Environment isolation is strict:** `sk_test_*` keys can only interact with test\npayments; `sk_live_*` keys can only interact with live payments. Attempting to\ncross environments returns `401 unauthenticated`.\n\nKeys are issued on signup (test), after KYB + activation (live), and can be\nrotated from the merchant dashboard at any time.\n\n## Idempotency\n\nEvery mutating `POST` accepts an `Idempotency-Key` header. Duplicates within a\n24-hour window return the original response without re-creating the resource.\n\n```\nIdempotency-Key: $(uuidgen)\n```\n\n## Rate limits\n\nThe default limit is **100 requests / minute per API key**. When exceeded, the\nAPI returns `429 rate_limited` with a `Retry-After` header (seconds to wait).\nCustom limits can be negotiated per merchant — contact support.\n\n## Webhooks\n\nRegister endpoints via the dashboard or `POST /v1/webhooks/endpoints`. Each\ndelivery carries HMAC-SHA256 signatures to prove authenticity. See the\n**Webhooks** section for the signature format and verification code.\n\n## Environments\n\nBase URL: `https://nexuspayph.com` for both test and live — the key\nprefix (`sk_test_` vs `sk_live_`) determines which environment the request\nhits.","contact":{"name":"NexusPay support","email":"admin@hiblafilipinohair.com"}},"servers":[{"url":"https://nexuspayph.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"secret API key (sk_test_* or sk_live_*)"}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"Deduplicate this POST for 24 hours. Duplicate requests return the original response.","example":"7a3f-4c2e-1b8d"},"KeyIdHint":{"name":"X-NexusPay-Key-Id","in":"header","required":false,"schema":{"type":"string"},"description":"Optional speed hint: your API key id (not the secret). Lets us skip the linear scan during auth."},"Limit":{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"description":"Page size (1–100)."},"StartingAfter":{"name":"starting_after","in":"query","required":false,"schema":{"type":"string"},"description":"Cursor — pass the last `id` from the previous page to fetch the next."}},"headers":{"NexusPaySignature":{"description":"HMAC-SHA256 signature of `{t}.{rawBody}` with your endpoint signing secret. Format: `t=<unix>,v1=<hex>`.","schema":{"type":"string"},"example":"t=1776839700,v1=a3f8d2b19c5f7e4d8b2a1c3e5f7a9b1d3e5f7a9b1d3e5f7a9b1d3e5f7a9b1d3e"},"NexusPayEvent":{"description":"Event type being delivered (e.g. `payment.succeeded`).","schema":{"type":"string"},"example":"payment.succeeded"},"NexusPayDelivery":{"description":"Numeric delivery attempt id. Unique per attempt, repeats on retry.","schema":{"type":"string"},"example":"42"},"RetryAfter":{"description":"Seconds to wait before retrying after a 429.","schema":{"type":"integer"},"example":30}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Machine-readable error code. Stable for programmatic handling.","enum":["invalid_request","unauthenticated","insufficient_scope","not_found","invalid_state","rate_limited","no_route","insufficient_balance","provider_error","internal_error","email_taken","invalid_token","already_used","conflict","customer_not_found","duplicate_sku","merchant_inactive","merchant_not_live","ip_not_allowed","link_inactive","link_expired","amount_required","method_required","shipment_not_found","shipment_closed","invoice_paid","invoice_void","invoice_not_sent","partial_not_allowed"]},"message":{"type":"string","description":"Human-readable explanation."},"issues":{"type":"object","additionalProperties":true,"description":"Zod-style field errors (400 only)."}}}}},"ListEnvelope":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{}},"has_more":{"type":"boolean"}}},"Payment":{"type":"object","required":["id","object","status","amount","currency","method","created"],"properties":{"id":{"type":"string","example":"pay_0e1f2a4c9b8d6a3f5c7e1d2b"},"object":{"type":"string","enum":["payment"]},"environment":{"type":"string","enum":["test","live"]},"status":{"type":"string","enum":["pending","processing","succeeded","failed","expired","refunded"],"description":"Lifecycle state. Only moves forward except refunded after succeeded."},"amount":{"type":"number","description":"Gross amount charged to the customer."},"currency":{"type":"string","example":"PHP"},"method":{"type":"string","example":"gcash_qr","description":"See the Methods reference for all values."},"provider":{"type":"string","description":"Which underlying provider routed this payment."},"provider_ref":{"type":"string","nullable":true,"description":"The provider-side reference (order number)."},"checkout_url":{"type":"string","nullable":true,"description":"URL to redirect the customer to. Branded NexusPay page for QR methods; provider-hosted for card 3DS."},"qr_code":{"type":"string","nullable":true,"description":"EMVCo QR payload (plain string). Feed into any QR-code library (e.g. `qrcode` on npm, `segno` on PyPI) to render your own QR image on your own checkout UI. Populated for `gcash_qr` / `instapay_qr` methods in live mode."},"qr_code_url":{"type":"string","nullable":true,"description":"Pre-rendered QR code image URL hosted on the provider's CDN. Use this if you'd rather not render a QR yourself — just embed it as an `<img src>`."},"app_link":{"type":"string","nullable":true,"description":"App deep link (e.g. `gcash://...`) that opens the payer's wallet app directly to the confirmation screen. Great for mobile-first merchants — show as a button/hyperlink. Not always provided."},"return_url":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"customer":{"type":"object","nullable":true,"properties":{"email":{"type":"string","format":"email"},"name":{"type":"string"}}},"metadata":{"type":"object","additionalProperties":true},"customer_id":{"type":"string","nullable":true,"description":"Customer-directory id attached to this payment, when supplied or inherited."},"payment_link_id":{"type":"string","nullable":true,"description":"Payment link that created this payment, when applicable."},"fee_amount":{"type":"number","description":"Platform fee deducted from the gross amount."},"net_amount":{"type":"number","nullable":true,"description":"amount − fee_amount. Populated once status=succeeded."},"idempotency_key":{"type":"string","nullable":true},"failure":{"type":"object","nullable":true,"properties":{"code":{"type":"string"},"message":{"type":"string"}}},"expires_at":{"type":"integer","nullable":true,"description":"Unix timestamp when the checkout expires if unpaid."},"succeeded_at":{"type":"integer","nullable":true},"failed_at":{"type":"integer","nullable":true},"created":{"type":"integer","description":"Unix timestamp of creation."},"receipt_url":{"type":"string","nullable":true,"description":"Customer-shareable receipt URL after the payment reaches a receipt-bearing terminal state."}},"example":{"id":"pay_0e1f2a4c9b8d6a3f5c7e1d2b","object":"payment","environment":"test","status":"pending","amount":500,"currency":"PHP","method":"gcash_qr","provider":"directpay","provider_ref":"DP-20260422-00042","checkout_url":"https://nexuspayph.com/checkout/pay_0e1f2a4c9b8d6a3f5c7e1d2b","qr_code":"00020101021128680014ph.ppmi.p2m0113011234567890012100005303608540550056022PH5912MAGIA STORE6011MANILA62150511ORDER10426304ABCD","qr_code_url":"https://c.tsdpay.tech/v2/qr/TlVRK0tu...TE9","app_link":null,"return_url":"https://yourstore.com/thanks","description":"Order #1042","customer":{"email":"alice@example.com","name":"Alice Santos"},"metadata":{"order_id":"1042","sku":"mage-robe"},"customer_id":null,"payment_link_id":null,"fee_amount":12.5,"net_amount":null,"idempotency_key":"7a3f-4c2e-1b8d","failure":null,"expires_at":1776840000,"succeeded_at":null,"failed_at":null,"created":1776839700,"receipt_url":null}},"CreatePaymentBody":{"type":"object","required":["amount","method"],"properties":{"amount":{"type":"number","minimum":0.01,"multipleOf":0.01,"maximum":999999999999,"example":500,"description":"In the currency listed (not cents)."},"currency":{"type":"string","minLength":3,"maxLength":3,"default":"PHP","example":"PHP"},"method":{"type":"string","example":"gcash_qr"},"description":{"type":"string","example":"Order #1042"},"return_url":{"type":"string","format":"uri","example":"https://yourstore.com/thanks"},"webhook_url":{"type":"string","format":"uri","description":"Per-payment webhook override (rare)."},"customer":{"type":"object","properties":{"email":{"type":"string","format":"email"},"name":{"type":"string"}}},"customer_id":{"type":"string","pattern":"^cus_","description":"Optional customer-directory id. The payment inherits customer email/name when not supplied inline."},"metadata":{"type":"object","additionalProperties":true,"description":"Your key/value pairs stored with the payment — great for linking to your order id.","example":{"order_id":"1042","sku":"mage-robe"}}}},"Refund":{"type":"object","properties":{"id":{"type":"string","example":"re_9f8e7d6c5b4a3210"},"object":{"type":"string","enum":["refund"]},"payment":{"type":"string","description":"The id of the payment being refunded."},"environment":{"type":"string","enum":["test","live"]},"amount":{"type":"number"},"status":{"type":"string","enum":["pending","processing","pending_manual","succeeded","failed"]},"reason":{"type":"string","nullable":true,"enum":["duplicate","fraudulent","requested_by_customer","other",null]},"provider_ref":{"type":"string","nullable":true},"failure":{"type":"object","nullable":true,"properties":{"code":{"type":"string"},"message":{"type":"string"}}},"succeeded_at":{"type":"integer","nullable":true},"failed_at":{"type":"integer","nullable":true},"created":{"type":"integer"}},"example":{"id":"re_9f8e7d6c5b4a3210","object":"refund","payment":"pay_0e1f2a4c9b8d6a3f5c7e1d2b","environment":"test","amount":500,"status":"succeeded","reason":"requested_by_customer","provider_ref":"mck_refund_1776840000000","failure":null,"succeeded_at":1776840300,"failed_at":null,"created":1776840300}},"CreateRefundBody":{"type":"object","required":["payment"],"properties":{"payment":{"type":"string","description":"The payment id to refund."},"amount":{"type":"number","description":"Partial refund. Omit for full refund of remaining balance."},"reason":{"type":"string","enum":["duplicate","fraudulent","requested_by_customer","other"]}}},"Payout":{"type":"object","properties":{"id":{"type":"string","example":"po_1a2b3c4d5e6f7890"},"object":{"type":"string","enum":["payout"]},"environment":{"type":"string","enum":["test","live"]},"status":{"type":"string","enum":["pending","processing","succeeded","failed"]},"amount":{"type":"number"},"currency":{"type":"string"},"method":{"type":"string","example":"gcash"},"provider":{"type":"string"},"provider_ref":{"type":"string","nullable":true},"destination":{"type":"object","additionalProperties":true},"description":{"type":"string","nullable":true},"metadata":{"type":"object","additionalProperties":true,"nullable":true},"fee_amount":{"type":"number","nullable":true},"failure":{"type":"object","nullable":true,"properties":{"code":{"type":"string"},"message":{"type":"string"}}},"paid_at":{"type":"integer","nullable":true},"failed_at":{"type":"integer","nullable":true},"created":{"type":"integer"}},"example":{"id":"po_1a2b3c4d5e6f7890","object":"payout","environment":"live","status":"succeeded","amount":5000,"currency":"PHP","method":"gcash","provider":"directpay","provider_ref":"DP-29384","destination":{"account_no":"09171234567"},"description":"Weekly settlement","metadata":{"batch_id":"settle-2026-06-30"},"fee_amount":null,"failure":null,"paid_at":1776850030,"failed_at":null,"created":1776850000}},"PayoutBank":{"type":"object","required":["code","name"],"properties":{"code":{"type":"string","description":"DirectPay bank code to pass as `destination.bank_code` or `destination.bankCode` when creating bank-transfer payouts.","example":"31248"},"name":{"type":"string","example":"BDO Bank"},"brstn":{"type":"string","nullable":true,"description":"Philippine BRSTN/routing number when provided by the bank-code registry.","example":"010530667"},"status":{"type":"integer","description":"Registry status from the provider list. Active banks are returned with status 1.","example":1}},"example":{"code":"31248","name":"BDO Bank","brstn":null,"status":1}},"CreatePayoutBody":{"type":"object","required":["amount","method","destination"],"properties":{"amount":{"type":"number","minimum":0.01},"currency":{"type":"string","default":"PHP"},"method":{"type":"string","example":"gcash"},"destination":{"type":"object","additionalProperties":true,"description":"Method-specific payload. Wallet payouts use `{account_no}`. Bank payouts use `{account_no, bank_code, first_name, last_name}` or `{account_no, bankCode, account_name}`. `bank_code`/`bankCode` is the DirectPay bank code returned by `GET /v1/payout-banks`, e.g. `\"31248\"` for BDO Bank.","example":{"account_no":"09171234567"}},"description":{"type":"string"},"metadata":{"type":"object","additionalProperties":true}}},"Balance":{"type":"object","properties":{"object":{"type":"string","enum":["balance"]},"environment":{"type":"string","enum":["test","live"]},"currency":{"type":"string","example":"PHP"},"available":{"type":"number","example":12450.75}},"example":{"object":"balance","environment":"live","currency":"PHP","available":12450.75}},"BalanceList":{"type":"object","properties":{"object":{"type":"string","enum":["balance_list"]},"environment":{"type":"string","enum":["test","live"]},"available":{"type":"array","items":{"type":"object","required":["currency","amount"],"properties":{"currency":{"type":"string","example":"PHP"},"amount":{"type":"number","example":12450.75}}}}},"example":{"object":"balance_list","environment":"live","available":[{"currency":"PHP","amount":12450.75}]}},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"string","example":"whe_9876543210abcdef"},"object":{"type":"string","enum":["webhook_endpoint"]},"environment":{"type":"string","enum":["test","live"]},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"},"description":"Event types to deliver. Use `*` for all."},"secret":{"type":"string","nullable":true,"description":"Returned **only** at creation. Save it — used for HMAC verification."},"description":{"type":"string","nullable":true},"enabled":{"type":"boolean"},"created":{"type":"integer"}},"example":{"id":"whe_9876543210abcdef","object":"webhook_endpoint","url":"https://yourstore.com/nexuspay/webhooks","events":["payment.succeeded","payment.failed","refund.succeeded"],"secret":"whsec_xDRpGklMN8sZy7QvT2cHAJuY3fRK6bWe","enabled":true,"description":"Production webhook","created":1776800000}},"CreateWebhookEndpointBody":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","example":"https://yourstore.com/nexuspay/webhooks"},"events":{"type":"array","items":{"type":"string"},"default":["payment.succeeded","payment.failed"],"example":["payment.succeeded","payment.failed","refund.succeeded"]},"description":{"type":"string"}}},"Event":{"type":"object","description":"Merchant-visible event. Every webhook delivery is backed by an event row written in the same DB transaction as the state change that produced it — `GET /v1/events/{id}` returns the canonical copy for reconciliation if you missed a delivery.","properties":{"id":{"type":"string","example":"evt_2e599b29fc3203f06a63cc16"},"object":{"type":"string","enum":["event"]},"type":{"type":"string","description":"Dot-namespaced event type. Common values:","example":"payment.succeeded","enum":["payment.pending","payment.processing","payment.succeeded","payment.failed","payment.expired","payment.refunded","payout.succeeded","payout.failed","refund.succeeded","refund.failed"]},"environment":{"type":"string","enum":["test","live"]},"created":{"type":"integer"},"data":{"type":"object","required":["object"],"properties":{"object":{"type":"object","additionalProperties":true,"description":"The resource that changed — a Payment, Refund, or Payout."}}}},"example":{"id":"evt_2e599b29fc3203f06a63cc16","object":"event","type":"payment.succeeded","environment":"test","created":1776840100,"data":{"object":{"id":"pay_0e1f2a4c9b8d6a3f5c7e1d2b","object":"payment","environment":"test","status":"succeeded","amount":500,"currency":"PHP","method":"gcash_qr","provider":"directpay","provider_ref":"DP-20260422-00042","checkout_url":"https://nexuspayph.com/checkout/pay_0e1f2a4c9b8d6a3f5c7e1d2b","qr_code":"00020101021128680014ph.ppmi.p2m0113011234567890012100005303608540550056022PH5912MAGIA STORE6011MANILA62150511ORDER10426304ABCD","qr_code_url":"https://c.tsdpay.tech/v2/qr/TlVRK0tu...TE9","app_link":null,"return_url":"https://yourstore.com/thanks","description":"Order #1042","customer":{"email":"alice@example.com","name":"Alice Santos"},"metadata":{"order_id":"1042","sku":"mage-robe"},"customer_id":null,"payment_link_id":null,"fee_amount":12.5,"net_amount":null,"idempotency_key":"7a3f-4c2e-1b8d","failure":null,"expires_at":1776840000,"succeeded_at":1776840100,"failed_at":null,"created":1776839700,"receipt_url":null}}}},"Customer":{"type":"object","required":["id","object","name","created"],"properties":{"id":{"type":"string","example":"cus_abcd1234efgh5678"},"object":{"type":"string","enum":["customer"]},"environment":{"type":"string","enum":["test","live"]},"name":{"type":"string"},"email":{"type":"string","format":"email","nullable":true},"phone":{"type":"string","nullable":true},"address":{"type":"object","properties":{"line1":{"type":"string","nullable":true},"line2":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"region":{"type":"string","nullable":true},"postal_code":{"type":"string","nullable":true},"country":{"type":"string","description":"ISO 3166-1 alpha-2. Defaults to PH."}}},"metadata":{"type":"object","additionalProperties":true},"receipts_history_url":{"type":"string","description":"Shareable receipt-history page for this customer."},"created":{"type":"integer"},"updated":{"type":"integer"}},"example":{"id":"cus_abcd1234efgh5678","object":"customer","environment":"live","name":"Alice Santos","email":"alice@example.com","phone":"+639175551234","address":{"line1":"123 Mabini St","line2":null,"city":"Manila","region":"Metro Manila","postal_code":"1000","country":"PH"},"metadata":{"tier":"vip"},"receipts_history_url":"https://nexuspayph.com/receipts/cus_abcd1234efgh5678?token=…","created":1776839700,"updated":1776839700}},"CreateCustomerBody":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"email":{"type":"string","format":"email","maxLength":255,"nullable":true,"description":"Empty string or null clears it."},"phone":{"type":"string","maxLength":40,"nullable":true},"address":{"type":"object","nullable":true,"properties":{"line1":{"type":"string","maxLength":200,"nullable":true},"line2":{"type":"string","maxLength":200,"nullable":true},"city":{"type":"string","maxLength":100,"nullable":true},"region":{"type":"string","maxLength":100,"nullable":true},"postal_code":{"type":"string","maxLength":20,"nullable":true},"country":{"type":"string","minLength":2,"maxLength":2}}},"metadata":{"type":"object","additionalProperties":true}}},"UpdateCustomerBody":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"email":{"type":"string","format":"email","maxLength":255,"nullable":true,"description":"Empty string or null clears it."},"phone":{"type":"string","maxLength":40,"nullable":true},"address":{"type":"object","nullable":true,"properties":{"line1":{"type":"string","maxLength":200,"nullable":true},"line2":{"type":"string","maxLength":200,"nullable":true},"city":{"type":"string","maxLength":100,"nullable":true},"region":{"type":"string","maxLength":100,"nullable":true},"postal_code":{"type":"string","maxLength":20,"nullable":true},"country":{"type":"string","minLength":2,"maxLength":2,"nullable":true}}},"metadata":{"type":"object","additionalProperties":true}}},"Product":{"type":"object","required":["id","object","name","created"],"properties":{"id":{"type":"string","example":"prd_abc123def456"},"object":{"type":"string","enum":["product"]},"environment":{"type":"string","enum":["test","live"]},"name":{"type":"string"},"description":{"type":"string","nullable":true},"price":{"type":"number","nullable":true,"description":"null = open amount (cashier/customer enters the price)."},"currency":{"type":"string"},"sku":{"type":"string","nullable":true,"description":"Auto-generated (SKU-00001) if omitted at create."},"barcode":{"type":"string","nullable":true,"description":"Auto-generated EAN-13 if omitted at create."},"image_url":{"type":"string","nullable":true},"track_inventory":{"type":"boolean"},"stock":{"type":"integer","description":"Clamped to ≥ 0."},"in_stock":{"type":"boolean","description":"true when not tracking inventory, or stock > 0."},"low_stock_threshold":{"type":"integer","nullable":true},"low_stock":{"type":"boolean"},"archived":{"type":"boolean"},"category":{"type":"string","nullable":true},"metadata":{"type":"object","additionalProperties":true},"created":{"type":"integer"},"updated":{"type":"integer"}},"example":{"id":"prd_abc123def456","object":"product","environment":"live","name":"Coffee Mug","description":"Premium ceramic mug","price":250,"currency":"PHP","sku":"SKU-00001","barcode":"2000000000017","image_url":"https://yourstore.com/mug.jpg","track_inventory":true,"stock":100,"in_stock":true,"low_stock_threshold":10,"low_stock":false,"archived":false,"metadata":{},"created":1776839700,"updated":1776839700}},"CreateProductBody":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":2000},"price":{"type":"number","minimum":0,"nullable":true,"description":"Omit or null for an open-amount product."},"currency":{"type":"string","minLength":3,"maxLength":3,"default":"PHP"},"sku":{"type":"string","maxLength":80,"description":"Omit to auto-generate."},"barcode":{"type":"string","maxLength":80,"description":"Omit to auto-generate an EAN-13."},"image_url":{"type":"string","format":"uri"},"track_inventory":{"type":"boolean","default":false},"stock":{"type":"integer","minimum":0,"default":0},"metadata":{"type":"object","additionalProperties":true}}},"UpdateProductBody":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":2000,"nullable":true},"price":{"type":"number","minimum":0,"nullable":true},"currency":{"type":"string","minLength":3,"maxLength":3},"sku":{"type":"string","maxLength":80,"nullable":true},"barcode":{"type":"string","maxLength":80,"nullable":true},"image_url":{"type":"string","format":"uri","nullable":true},"track_inventory":{"type":"boolean"},"stock":{"type":"integer","minimum":0},"metadata":{"type":"object","additionalProperties":true}}},"InvoiceLineItem":{"type":"object","required":["description","quantity","unit_amount"],"properties":{"description":{"type":"string","minLength":1,"maxLength":500},"quantity":{"type":"number","exclusiveMinimum":0},"unit_amount":{"type":"number","minimum":0},"amount":{"type":"number","minimum":0,"description":"Line total. Auto-computed as quantity × unit_amount if omitted."}}},"Invoice":{"type":"object","required":["id","object","status","amount","currency","line_items"],"properties":{"id":{"type":"string","example":"inv_a7b3c9d2e1f4g5h6"},"object":{"type":"string","enum":["invoice"]},"environment":{"type":"string","enum":["test","live"]},"kind":{"type":"string","enum":["invoice","activation_fee"]},"number":{"type":"string","nullable":true,"description":"INV-YYYY-NNNN. null for activation_fee invoices."},"status":{"type":"string","enum":["draft","sent","partial","paid","void"]},"amount":{"type":"number","description":"Total = subtotal − discount_amount + tax_amount."},"subtotal":{"type":"number","nullable":true},"tax_amount":{"type":"number"},"discount_amount":{"type":"number"},"currency":{"type":"string"},"description":{"type":"string","nullable":true},"line_items":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceLineItem"}},"customer_id":{"type":"string","nullable":true},"due_date":{"type":"string","nullable":true,"description":"YYYY-MM-DD."},"notes":{"type":"string","nullable":true},"terms":{"type":"string","nullable":true},"allow_partial_payment":{"type":"boolean"},"amount_paid":{"type":"number"},"amount_remaining":{"type":"number"},"deposit_rate":{"type":"number","nullable":true,"description":"Fraction 0–1 (e.g. 0.5 = 50% deposit)."},"deposit_due_at":{"type":"integer","nullable":true},"balance_due_at":{"type":"integer","nullable":true},"shipment_id":{"type":"string","nullable":true},"forfeited_at":{"type":"integer","nullable":true},"payment_id":{"type":"string","nullable":true},"issued_at":{"type":"integer","nullable":true},"sent_at":{"type":"integer","nullable":true},"paid_at":{"type":"integer","nullable":true},"void_at":{"type":"integer","nullable":true},"metadata":{"type":"object","additionalProperties":true},"url":{"type":"string","description":"Customer-facing pay page."}},"example":{"id":"inv_a7b3c9d2e1f4g5h6","object":"invoice","environment":"live","kind":"invoice","number":"INV-2026-0001","status":"sent","amount":1150,"subtotal":1000,"tax_amount":150,"discount_amount":0,"currency":"PHP","description":"Order #1042","line_items":[{"description":"Widget A","quantity":10,"unit_amount":100,"amount":1000}],"customer_id":"cus_abcd1234efgh5678","due_date":"2026-06-20","notes":"Net 14","terms":null,"allow_partial_payment":false,"amount_paid":0,"amount_remaining":1150,"deposit_rate":null,"deposit_due_at":null,"balance_due_at":null,"shipment_id":null,"forfeited_at":null,"payment_id":null,"issued_at":1776839700,"sent_at":1776839705,"paid_at":null,"void_at":null,"metadata":{"order_id":"1042"},"url":"https://nexuspayph.com/invoice/inv_a7b3c9d2e1f4g5h6"}},"CreateInvoiceBody":{"type":"object","required":["line_items"],"properties":{"line_items":{"type":"array","minItems":1,"maxItems":50,"items":{"$ref":"#/components/schemas/InvoiceLineItem"}},"customer_id":{"type":"string","pattern":"^cus_"},"description":{"type":"string","maxLength":500},"tax_amount":{"type":"number","minimum":0},"discount_amount":{"type":"number","minimum":0},"currency":{"type":"string","minLength":3,"maxLength":3,"default":"PHP"},"due_date":{"type":"string","description":"YYYY-MM-DD."},"notes":{"type":"string","maxLength":2000},"terms":{"type":"string","maxLength":2000},"allow_partial_payment":{"type":"boolean"},"deposit_rate":{"type":"number","exclusiveMinimum":0,"exclusiveMaximum":1,"description":"Two-stage invoices: fraction collected upfront."},"shipment_id":{"type":"string","pattern":"^shp_"},"metadata":{"type":"object","additionalProperties":true}}},"UpdateInvoiceBody":{"type":"object","properties":{"line_items":{"type":"array","minItems":1,"maxItems":50,"items":{"$ref":"#/components/schemas/InvoiceLineItem"}},"customer_id":{"type":"string","pattern":"^cus_"},"description":{"type":"string","maxLength":500},"tax_amount":{"type":"number","minimum":0},"discount_amount":{"type":"number","minimum":0},"due_date":{"type":"string","description":"YYYY-MM-DD."},"notes":{"type":"string","maxLength":2000},"terms":{"type":"string","maxLength":2000},"allow_partial_payment":{"type":"boolean"},"metadata":{"type":"object","additionalProperties":true}}},"PaymentLink":{"type":"object","required":["id","object","status","description","url"],"properties":{"id":{"type":"string","example":"plk_abc123def456"},"object":{"type":"string","enum":["payment_link"]},"environment":{"type":"string","enum":["test","live"]},"amount":{"type":"number","nullable":true,"description":"null = customer enters the amount."},"currency":{"type":"string"},"method":{"type":"string","nullable":true,"description":"null = customer picks at checkout."},"description":{"type":"string"},"image_url":{"type":"string","nullable":true},"success_url":{"type":"string","nullable":true},"cancel_url":{"type":"string","nullable":true},"status":{"type":"string","enum":["active","inactive"]},"customer_id":{"type":"string","nullable":true},"usage_count":{"type":"integer"},"last_used_at":{"type":"integer","nullable":true},"expires_at":{"type":"integer","nullable":true},"metadata":{"type":"object","additionalProperties":true},"created":{"type":"integer"},"url":{"type":"string","description":"Shareable public checkout URL."}},"example":{"id":"plk_abc123def456","object":"payment_link","environment":"live","amount":500,"currency":"PHP","method":"gcash_qr","description":"Concert ticket","image_url":null,"success_url":"https://yourstore.com/thanks","cancel_url":null,"status":"active","customer_id":null,"usage_count":3,"last_used_at":1776840000,"expires_at":null,"metadata":{},"created":1776839700,"url":"https://nexuspayph.com/pay/plk_abc123def456"}},"CreatePaymentLinkBody":{"type":"object","required":["description"],"properties":{"description":{"type":"string","minLength":1,"maxLength":500},"amount":{"type":"number","exclusiveMinimum":0,"description":"Omit for a customer-entered amount."},"currency":{"type":"string","minLength":3,"maxLength":3,"default":"PHP"},"method":{"type":"string","minLength":1,"maxLength":40,"description":"Omit to let the customer choose."},"image_url":{"type":"string","format":"uri"},"success_url":{"type":"string","format":"uri"},"cancel_url":{"type":"string","format":"uri"},"expires_at":{"type":"string","format":"date-time"},"customer_id":{"type":"string","pattern":"^cus_"},"metadata":{"type":"object","additionalProperties":true}}},"UpdatePaymentLinkBody":{"type":"object","properties":{"description":{"type":"string","minLength":1,"maxLength":500},"amount":{"type":"number","exclusiveMinimum":0,"nullable":true},"currency":{"type":"string","minLength":3,"maxLength":3},"method":{"type":"string","minLength":1,"maxLength":40,"nullable":true},"image_url":{"type":"string","format":"uri","nullable":true},"success_url":{"type":"string","format":"uri","nullable":true},"cancel_url":{"type":"string","format":"uri","nullable":true},"status":{"type":"string","enum":["active","inactive"]}}},"StaticQr":{"type":"object","required":["id","object","name","payment_link_id","url"],"properties":{"id":{"type":"string","example":"sqr_abc123def456"},"object":{"type":"string","enum":["static_qr"]},"environment":{"type":"string","enum":["test","live"]},"name":{"type":"string"},"reference":{"type":"string","nullable":true},"location":{"type":"string","nullable":true},"payment_link_id":{"type":"string","description":"The open-amount payment link this QR encodes."},"url":{"type":"string","description":"Public checkout URL the QR points to."},"qr_svg_url":{"type":"string","description":"Server-rendered SVG for printing."},"default_method":{"type":"string","nullable":true},"currency":{"type":"string"},"archived":{"type":"boolean"},"archived_at":{"type":"integer","nullable":true},"created":{"type":"integer"}},"example":{"id":"sqr_abc123def456","object":"static_qr","environment":"live","name":"Stall 5 — Noodles","reference":"ST-05","location":"North Aisle, Food Court","payment_link_id":"plk_xyz789","url":"https://nexuspayph.com/pay/plk_xyz789","qr_svg_url":"/wapi/static-qrs/sqr_abc123def456/qr.svg","default_method":"gcash_qr","currency":"PHP","archived":false,"archived_at":null,"created":1776839700}},"CreateStaticQrBody":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":120},"reference":{"type":"string","minLength":1,"maxLength":60},"location":{"type":"string","maxLength":200},"default_method":{"type":"string","minLength":1,"maxLength":40,"description":"Omit to let the customer choose."},"currency":{"type":"string","minLength":3,"maxLength":3,"default":"PHP"}}},"EmbedToken":{"type":"object","required":["token","expires_at"],"properties":{"token":{"type":"string","description":"Short-lived JWT to mount an /embed/* widget. scope_value is never echoed back."},"expires_at":{"type":"string","format":"date-time"},"project_uuid":{"type":"string","format":"uuid"},"surface":{"type":"string","enum":["payments","panel"]},"audience":{"type":"string","enum":["merchant","customer"]},"scope_field":{"type":"string","nullable":true,"enum":["customer_id","external_id",null]},"tabs":{"type":"array","nullable":true,"items":{"type":"string"}},"ttl_seconds":{"type":"integer"}},"example":{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…","expires_at":"2026-06-13T18:30:00Z","project_uuid":"cedf830f-1234-5678-9abc-def012345678","surface":"payments","audience":"merchant","scope_field":null,"tabs":null,"ttl_seconds":1800}},"CreateEmbedTokenBody":{"type":"object","required":["project_uuid","audience"],"properties":{"project_uuid":{"type":"string","format":"uuid"},"audience":{"type":"string","enum":["merchant","customer"]},"surface":{"type":"string","enum":["payments","panel"],"default":"payments"},"scope_field":{"type":"string","enum":["customer_id","external_id"]},"scope_value":{"type":"string","minLength":1,"maxLength":255},"tabs":{"type":"array","items":{"type":"string","enum":["payments","payouts","balance","invoices","customers","events"]}},"ttl_seconds":{"type":"integer","minimum":60,"maximum":86400,"default":1800}}}},"responses":{"InvalidRequest":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}}}}}},"Unauthenticated":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"InsufficientScope":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"insufficient_scope":{"summary":"Key lacks required scope","value":{"error":{"code":"insufficient_scope","message":"api key missing required scope"}}}}}}},"NotFound":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"RateLimited":{"description":"Too many requests","headers":{"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"code":"rate_limited","message":"too many requests"}}}}}}}}},"paths":{"/v1/payments":{"post":{"tags":["Payments"],"summary":"Create a payment","description":"Start a new payment. Returns a `checkout_url` to redirect your customer to. On success (polled or via webhook) the ledger is credited with `net_amount`.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/KeyIdHint"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePaymentBody"},"examples":{"gcash_qr":{"summary":"GCash QR","value":{"amount":500,"currency":"PHP","method":"gcash_qr","description":"Order #1042","return_url":"https://yourstore.com/thanks","metadata":{"order_id":"1042"}}},"card":{"summary":"Card with 3DS","value":{"amount":1299,"method":"card","customer":{"email":"alice@example.com","name":"Alice Santos"},"return_url":"https://yourstore.com/thanks"}}}}}},"responses":{"201":{"description":"Payment created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Payment"},"examples":{"default":{"value":{"id":"pay_0e1f2a4c9b8d6a3f5c7e1d2b","object":"payment","environment":"test","status":"pending","amount":500,"currency":"PHP","method":"gcash_qr","provider":"directpay","provider_ref":"DP-20260422-00042","checkout_url":"https://nexuspayph.com/checkout/pay_0e1f2a4c9b8d6a3f5c7e1d2b","qr_code":"00020101021128680014ph.ppmi.p2m0113011234567890012100005303608540550056022PH5912MAGIA STORE6011MANILA62150511ORDER10426304ABCD","qr_code_url":"https://c.tsdpay.tech/v2/qr/TlVRK0tu...TE9","app_link":null,"return_url":"https://yourstore.com/thanks","description":"Order #1042","customer":{"email":"alice@example.com","name":"Alice Santos"},"metadata":{"order_id":"1042","sku":"mage-robe"},"customer_id":null,"payment_link_id":null,"fee_amount":12.5,"net_amount":null,"idempotency_key":"7a3f-4c2e-1b8d","failure":null,"expires_at":1776840000,"succeeded_at":null,"failed_at":null,"created":1776839700,"receipt_url":null}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"insufficient_scope":{"summary":"Key lacks required scope","value":{"error":{"code":"insufficient_scope","message":"api key missing required scope"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"code":"rate_limited","message":"too many requests"}}}}}}}}},"get":{"tags":["Payments"],"summary":"List payments","parameters":[{"$ref":"#/components/parameters/Limit"},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","processing","succeeded","failed","expired","refunded"]}},{"$ref":"#/components/parameters/StartingAfter"}],"responses":{"200":{"description":"Paginated list of payments","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Payment"}},"has_more":{"type":"boolean"}}},"examples":{"default":{"value":{"object":"list","data":[{"id":"pay_0e1f2a4c9b8d6a3f5c7e1d2b","object":"payment","environment":"test","status":"pending","amount":500,"currency":"PHP","method":"gcash_qr","provider":"directpay","provider_ref":"DP-20260422-00042","checkout_url":"https://nexuspayph.com/checkout/pay_0e1f2a4c9b8d6a3f5c7e1d2b","qr_code":"00020101021128680014ph.ppmi.p2m0113011234567890012100005303608540550056022PH5912MAGIA STORE6011MANILA62150511ORDER10426304ABCD","qr_code_url":"https://c.tsdpay.tech/v2/qr/TlVRK0tu...TE9","app_link":null,"return_url":"https://yourstore.com/thanks","description":"Order #1042","customer":{"email":"alice@example.com","name":"Alice Santos"},"metadata":{"order_id":"1042","sku":"mage-robe"},"customer_id":null,"payment_link_id":null,"fee_amount":12.5,"net_amount":null,"idempotency_key":"7a3f-4c2e-1b8d","failure":null,"expires_at":1776840000,"succeeded_at":null,"failed_at":null,"created":1776839700,"receipt_url":null}],"has_more":false}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"code":"rate_limited","message":"too many requests"}}}}}}}}}},"/v1/payments/{id}":{"get":{"tags":["Payments"],"summary":"Retrieve a payment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"expand","in":"query","schema":{"type":"string","enum":["events"]},"description":"Pass `events` to include the full event timeline for this payment."}],"responses":{"200":{"description":"Payment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Payment"},"examples":{"default":{"value":{"id":"pay_0e1f2a4c9b8d6a3f5c7e1d2b","object":"payment","environment":"test","status":"pending","amount":500,"currency":"PHP","method":"gcash_qr","provider":"directpay","provider_ref":"DP-20260422-00042","checkout_url":"https://nexuspayph.com/checkout/pay_0e1f2a4c9b8d6a3f5c7e1d2b","qr_code":"00020101021128680014ph.ppmi.p2m0113011234567890012100005303608540550056022PH5912MAGIA STORE6011MANILA62150511ORDER10426304ABCD","qr_code_url":"https://c.tsdpay.tech/v2/qr/TlVRK0tu...TE9","app_link":null,"return_url":"https://yourstore.com/thanks","description":"Order #1042","customer":{"email":"alice@example.com","name":"Alice Santos"},"metadata":{"order_id":"1042","sku":"mage-robe"},"customer_id":null,"payment_link_id":null,"fee_amount":12.5,"net_amount":null,"idempotency_key":"7a3f-4c2e-1b8d","failure":null,"expires_at":1776840000,"succeeded_at":null,"failed_at":null,"created":1776839700,"receipt_url":null}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}}}}},"/v1/refunds":{"post":{"tags":["Refunds"],"summary":"Create a refund","description":"Refund all or part of a succeeded payment. Partial refunds (when `amount` < payment amount) leave the payment status as `succeeded`; full refunds transition to `refunded`.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRefundBody"},"examples":{"full":{"summary":"Full refund","value":{"payment":"pay_0e1f2a4c9b8d6a3f5c7e1d2b","reason":"requested_by_customer"}},"partial":{"summary":"Partial refund","value":{"payment":"pay_0e1f2a4c9b8d6a3f5c7e1d2b","amount":100,"reason":"other"}}}}}},"responses":{"201":{"description":"Refund created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Refund"},"examples":{"default":{"value":{"id":"re_9f8e7d6c5b4a3210","object":"refund","payment":"pay_0e1f2a4c9b8d6a3f5c7e1d2b","environment":"test","amount":500,"status":"succeeded","reason":"requested_by_customer","provider_ref":"mck_refund_1776840000000","failure":null,"succeeded_at":1776840300,"failed_at":null,"created":1776840300}}}}}},"400":{"description":"Invalid request or invalid state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}},"invalid_state":{"summary":"Illegal state transition","value":{"error":{"code":"invalid_state","message":"only succeeded payments can be refunded"}}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"code":"rate_limited","message":"too many requests"}}}}}}}}},"get":{"tags":["Refunds"],"summary":"List refunds","parameters":[{"$ref":"#/components/parameters/Limit"},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","succeeded","failed"]}},{"name":"payment","in":"query","schema":{"type":"string"},"description":"Filter to refunds for a specific payment."},{"$ref":"#/components/parameters/StartingAfter"}],"responses":{"200":{"description":"Paginated list of refunds","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Refund"}},"has_more":{"type":"boolean"}}},"examples":{"default":{"value":{"object":"list","data":[{"id":"re_9f8e7d6c5b4a3210","object":"refund","payment":"pay_0e1f2a4c9b8d6a3f5c7e1d2b","environment":"test","amount":500,"status":"succeeded","reason":"requested_by_customer","provider_ref":"mck_refund_1776840000000","failure":null,"succeeded_at":1776840300,"failed_at":null,"created":1776840300}],"has_more":false}}}}}}}}},"/v1/refunds/{id}":{"get":{"tags":["Refunds"],"summary":"Retrieve a refund","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Refund","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Refund"},"examples":{"default":{"value":{"id":"re_9f8e7d6c5b4a3210","object":"refund","payment":"pay_0e1f2a4c9b8d6a3f5c7e1d2b","environment":"test","amount":500,"status":"succeeded","reason":"requested_by_customer","provider_ref":"mck_refund_1776840000000","failure":null,"succeeded_at":1776840300,"failed_at":null,"created":1776840300}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}}}}},"/v1/payouts":{"post":{"tags":["Payouts"],"summary":"Create a payout","description":"Move funds from your NexusPay balance to an external destination. Debits your ledger immediately; on failure the debit is reversed automatically.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePayoutBody"},"examples":{"gcash":{"summary":"GCash","value":{"amount":5000,"method":"gcash","destination":{"account_no":"09171234567"},"description":"Weekly settlement"}},"bank_transfer":{"summary":"Bank transfer","value":{"amount":1000,"method":"bank_transfer","destination":{"account_no":"1234567890","bank_code":"31248","first_name":"Juan","last_name":"Dela Cruz"},"description":"Supplier payment"}}}}}},"responses":{"201":{"description":"Payout created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Payout"},"examples":{"default":{"value":{"id":"po_1a2b3c4d5e6f7890","object":"payout","environment":"live","status":"succeeded","amount":5000,"currency":"PHP","method":"gcash","provider":"directpay","provider_ref":"DP-29384","destination":{"account_no":"09171234567"},"description":"Weekly settlement","metadata":{"batch_id":"settle-2026-06-30"},"fee_amount":null,"failure":null,"paid_at":1776850030,"failed_at":null,"created":1776850000}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}},"insufficient_balance":{"summary":"Payout exceeds balance","value":{"error":{"code":"insufficient_balance","message":"balance 100.00 PHP < payout amount 500.00"}}},"no_route":{"summary":"No provider for method","value":{"error":{"code":"no_route","message":"no provider available for gcash_qr/PHP"}}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}}}},"get":{"tags":["Payouts"],"summary":"List payouts","parameters":[{"$ref":"#/components/parameters/Limit"},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","processing","succeeded","failed"]}},{"$ref":"#/components/parameters/StartingAfter"}],"responses":{"200":{"description":"List of payouts","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Payout"}},"has_more":{"type":"boolean"}}},"examples":{"default":{"value":{"object":"list","data":[{"id":"po_1a2b3c4d5e6f7890","object":"payout","environment":"live","status":"succeeded","amount":5000,"currency":"PHP","method":"gcash","provider":"directpay","provider_ref":"DP-29384","destination":{"account_no":"09171234567"},"description":"Weekly settlement","metadata":{"batch_id":"settle-2026-06-30"},"fee_amount":null,"failure":null,"paid_at":1776850030,"failed_at":null,"created":1776850000}],"has_more":false}}}}}}}}},"/v1/payouts/{id}":{"get":{"tags":["Payouts"],"summary":"Retrieve a payout","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Payout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Payout"},"examples":{"default":{"value":{"id":"po_1a2b3c4d5e6f7890","object":"payout","environment":"live","status":"succeeded","amount":5000,"currency":"PHP","method":"gcash","provider":"directpay","provider_ref":"DP-29384","destination":{"account_no":"09171234567"},"description":"Weekly settlement","metadata":{"batch_id":"settle-2026-06-30"},"fee_amount":null,"failure":null,"paid_at":1776850030,"failed_at":null,"created":1776850000}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}}}}},"/v1/payout-banks":{"get":{"tags":["Payouts"],"summary":"List payout bank codes","description":"Returns the NexusPay payout bank-code registry accepted by DirectPay `bank_transfer` and `bank_transfer_nrt` payouts. Use `code` as `destination.bank_code` or `destination.bankCode` when creating the payout.","parameters":[{"$ref":"#/components/parameters/KeyIdHint"}],"responses":{"200":{"description":"List of bank codes","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/PayoutBank"}},"has_more":{"type":"boolean"}}},"examples":{"default":{"value":{"object":"list","data":[{"code":"31248","name":"BDO Bank","brstn":null,"status":1}],"has_more":false}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"insufficient_scope":{"summary":"Key lacks required scope","value":{"error":{"code":"insufficient_scope","message":"api key missing required scope"}}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"code":"rate_limited","message":"too many requests"}}}}}}}}}},"/v1/events":{"get":{"tags":["Events"],"summary":"List events","description":"Every merchant-visible webhook delivery has a matching event row here. Use this endpoint to reconcile missed webhooks — fetch events created after your last-seen `id`.","parameters":[{"$ref":"#/components/parameters/Limit"},{"name":"type","in":"query","schema":{"type":"string"},"description":"Filter by exact event type (e.g. `payment.succeeded`)."},{"$ref":"#/components/parameters/StartingAfter"}],"responses":{"200":{"description":"List of events","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"has_more":{"type":"boolean"}}},"examples":{"default":{"value":{"object":"list","data":[{"id":"evt_2e599b29fc3203f06a63cc16","object":"event","type":"payment.succeeded","environment":"test","created":1776840100,"data":{"object":{"id":"pay_0e1f2a4c9b8d6a3f5c7e1d2b","object":"payment","environment":"test","status":"succeeded","amount":500,"currency":"PHP","method":"gcash_qr","provider":"directpay","provider_ref":"DP-20260422-00042","checkout_url":"https://nexuspayph.com/checkout/pay_0e1f2a4c9b8d6a3f5c7e1d2b","qr_code":"00020101021128680014ph.ppmi.p2m0113011234567890012100005303608540550056022PH5912MAGIA STORE6011MANILA62150511ORDER10426304ABCD","qr_code_url":"https://c.tsdpay.tech/v2/qr/TlVRK0tu...TE9","app_link":null,"return_url":"https://yourstore.com/thanks","description":"Order #1042","customer":{"email":"alice@example.com","name":"Alice Santos"},"metadata":{"order_id":"1042","sku":"mage-robe"},"customer_id":null,"payment_link_id":null,"fee_amount":12.5,"net_amount":null,"idempotency_key":"7a3f-4c2e-1b8d","failure":null,"expires_at":1776840000,"succeeded_at":1776840100,"failed_at":null,"created":1776839700,"receipt_url":null}}}],"has_more":false}}}}}}}}},"/v1/events/{id}":{"get":{"tags":["Events"],"summary":"Retrieve an event","description":"The `id` arrives as the `id` field in every webhook payload — you can use this endpoint to verify a delivery you received.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Event","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"},"examples":{"default":{"value":{"id":"evt_2e599b29fc3203f06a63cc16","object":"event","type":"payment.succeeded","environment":"test","created":1776840100,"data":{"object":{"id":"pay_0e1f2a4c9b8d6a3f5c7e1d2b","object":"payment","environment":"test","status":"succeeded","amount":500,"currency":"PHP","method":"gcash_qr","provider":"directpay","provider_ref":"DP-20260422-00042","checkout_url":"https://nexuspayph.com/checkout/pay_0e1f2a4c9b8d6a3f5c7e1d2b","qr_code":"00020101021128680014ph.ppmi.p2m0113011234567890012100005303608540550056022PH5912MAGIA STORE6011MANILA62150511ORDER10426304ABCD","qr_code_url":"https://c.tsdpay.tech/v2/qr/TlVRK0tu...TE9","app_link":null,"return_url":"https://yourstore.com/thanks","description":"Order #1042","customer":{"email":"alice@example.com","name":"Alice Santos"},"metadata":{"order_id":"1042","sku":"mage-robe"},"customer_id":null,"payment_link_id":null,"fee_amount":12.5,"net_amount":null,"idempotency_key":"7a3f-4c2e-1b8d","failure":null,"expires_at":1776840000,"succeeded_at":1776840100,"failed_at":null,"created":1776839700,"receipt_url":null}}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}}}}},"/v1/webhooks/endpoints":{"post":{"tags":["Webhooks"],"summary":"Register a webhook endpoint","description":"Register a URL to receive signed POSTs for specified events.\n\nThe returned `secret` is **shown only once** — save it. Use it to verify every incoming webhook:\n\n```js\n// Node.js verification\nconst crypto = require('crypto');\nfunction verify(rawBody, signatureHeader, secret) {\n  const parts = Object.fromEntries(signatureHeader.split(',').map(kv => kv.split('=')));\n  const expected = crypto.createHmac('sha256', secret).update(`${parts.t}.${rawBody}`).digest('hex');\n  return crypto.timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(parts.v1, 'hex'));\n}\n```\n\nDelivery retries on non-2xx: **1m, 5m, 30m, 2h, 6h, 24h** — after 6 failures the delivery is marked failed (replay manually from the dashboard).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookEndpointBody"},"examples":{"default":{"value":{"url":"https://yourstore.com/nexuspay/webhooks","events":["payment.succeeded","payment.failed"],"description":"Test integration"}}}}}},"responses":{"201":{"description":"Created (returns secret once)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"},"examples":{"default":{"value":{"id":"whe_9876543210abcdef","object":"webhook_endpoint","url":"https://yourstore.com/nexuspay/webhooks","events":["payment.succeeded","payment.failed","refund.succeeded"],"secret":"whsec_xDRpGklMN8sZy7QvT2cHAJuY3fRK6bWe","enabled":true,"description":"Production webhook","created":1776800000}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}}}},"get":{"tags":["Webhooks"],"summary":"List webhook endpoints","responses":{"200":{"description":"List of endpoints (secret omitted after creation)","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"examples":{"default":{"value":{"object":"list","data":[{"id":"whe_9876543210abcdef","url":"https://yourstore.com/nexuspay/webhooks","events":["payment.succeeded"],"enabled":true,"description":"Production webhook","created":1776800000}]}}}}}}}}},"/v1/balance":{"get":{"tags":["Balance"],"summary":"Get merchant balance","description":"Returns all balances for the API key environment. Pass `currency` to retrieve a single-currency balance object.","parameters":[{"name":"currency","in":"query","required":false,"schema":{"type":"string","minLength":3,"maxLength":3},"description":"Optional ISO currency code, e.g. `PHP`."}],"responses":{"200":{"description":"Balance list or single-currency balance","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/BalanceList"},{"$ref":"#/components/schemas/Balance"}]},"examples":{"list":{"value":{"object":"balance_list","environment":"live","available":[{"currency":"PHP","amount":12450.75}]}},"single_currency":{"value":{"object":"balance","environment":"live","currency":"PHP","available":12450.75}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}}}}},"/v1/ping":{"get":{"tags":["Meta"],"summary":"Health check","description":"Public, unauthenticated — returns `{ok: true, time}`. Use for load balancer checks and merchant connectivity tests.","security":[],"responses":{"200":{"description":"Healthy","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"time":{"type":"integer","description":"Unix timestamp."}}},"examples":{"default":{"value":{"ok":true,"time":1776840000}}}}}}}}},"/v1/customers":{"post":{"tags":["Customers"],"summary":"Create a customer","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerBody"}}}},"responses":{"201":{"description":"Customer created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Customer"},"examples":{"default":{"value":{"id":"cus_abcd1234efgh5678","object":"customer","environment":"live","name":"Alice Santos","email":"alice@example.com","phone":"+639175551234","address":{"line1":"123 Mabini St","line2":null,"city":"Manila","region":"Metro Manila","postal_code":"1000","country":"PH"},"metadata":{"tier":"vip"},"receipts_history_url":"https://nexuspayph.com/receipts/cus_abcd1234efgh5678?token=…","created":1776839700,"updated":1776839700}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"insufficient_scope":{"summary":"Key lacks required scope","value":{"error":{"code":"insufficient_scope","message":"api key missing required scope"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"code":"rate_limited","message":"too many requests"}}}}}}}}},"get":{"tags":["Customers"],"summary":"List customers","parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Free-text search across name, email, phone."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Paginated list of customers","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Customer"}},"total":{"type":"integer"},"has_more":{"type":"boolean"}}},"examples":{"default":{"value":{"object":"list","data":[{"id":"cus_abcd1234efgh5678","object":"customer","environment":"live","name":"Alice Santos","email":"alice@example.com","phone":"+639175551234","address":{"line1":"123 Mabini St","line2":null,"city":"Manila","region":"Metro Manila","postal_code":"1000","country":"PH"},"metadata":{"tier":"vip"},"receipts_history_url":"https://nexuspayph.com/receipts/cus_abcd1234efgh5678?token=…","created":1776839700,"updated":1776839700}],"total":1,"has_more":false}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}}}}},"/v1/customers/{id}":{"get":{"tags":["Customers"],"summary":"Retrieve a customer","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Customer","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Customer"},"examples":{"default":{"value":{"id":"cus_abcd1234efgh5678","object":"customer","environment":"live","name":"Alice Santos","email":"alice@example.com","phone":"+639175551234","address":{"line1":"123 Mabini St","line2":null,"city":"Manila","region":"Metro Manila","postal_code":"1000","country":"PH"},"metadata":{"tier":"vip"},"receipts_history_url":"https://nexuspayph.com/receipts/cus_abcd1234efgh5678?token=…","created":1776839700,"updated":1776839700}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}}}},"patch":{"tags":["Customers"],"summary":"Update a customer","description":"PATCH semantics — send only the fields you want to change. Pass `null` (or `\"\"` for email/phone) to clear a nullable field.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCustomerBody"}}}},"responses":{"200":{"description":"Updated customer","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Customer"},"examples":{"default":{"value":{"id":"cus_abcd1234efgh5678","object":"customer","environment":"live","name":"Alice Santos","email":"alice@example.com","phone":"+639175551234","address":{"line1":"123 Mabini St","line2":null,"city":"Manila","region":"Metro Manila","postal_code":"1000","country":"PH"},"metadata":{"tier":"vip"},"receipts_history_url":"https://nexuspayph.com/receipts/cus_abcd1234efgh5678?token=…","created":1776839700,"updated":1776839700}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"insufficient_scope":{"summary":"Key lacks required scope","value":{"error":{"code":"insufficient_scope","message":"api key missing required scope"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"code":"rate_limited","message":"too many requests"}}}}}}}}},"delete":{"tags":["Customers"],"summary":"Delete a customer","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"},"id":{"type":"string"}}},"examples":{"default":{"value":{"deleted":true,"id":"cus_abcd1234efgh5678"}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}}}}},"/v1/invoices":{"post":{"tags":["Invoices"],"summary":"Create an invoice (draft)","description":"Creates a draft invoice. `subtotal` = Σ line_items.amount; `amount` (total) = subtotal − discount_amount + tax_amount. Call **send** to issue it.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInvoiceBody"}}}},"responses":{"201":{"description":"Invoice created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"},"examples":{"default":{"value":{"id":"inv_a7b3c9d2e1f4g5h6","object":"invoice","environment":"live","kind":"invoice","number":"INV-2026-0001","status":"sent","amount":1150,"subtotal":1000,"tax_amount":150,"discount_amount":0,"currency":"PHP","description":"Order #1042","line_items":[{"description":"Widget A","quantity":10,"unit_amount":100,"amount":1000}],"customer_id":"cus_abcd1234efgh5678","due_date":"2026-06-20","notes":"Net 14","terms":null,"allow_partial_payment":false,"amount_paid":0,"amount_remaining":1150,"deposit_rate":null,"deposit_due_at":null,"balance_due_at":null,"shipment_id":null,"forfeited_at":null,"payment_id":null,"issued_at":1776839700,"sent_at":1776839705,"paid_at":null,"void_at":null,"metadata":{"order_id":"1042"},"url":"https://nexuspayph.com/invoice/inv_a7b3c9d2e1f4g5h6"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"insufficient_scope":{"summary":"Key lacks required scope","value":{"error":{"code":"insufficient_scope","message":"api key missing required scope"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"code":"rate_limited","message":"too many requests"}}}}}}}}},"get":{"tags":["Invoices"],"summary":"List invoices","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["draft","sent","partial","paid","void"]}},{"name":"customer_id","in":"query","schema":{"type":"string","pattern":"^cus_"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Paginated list of invoices","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Invoice"}},"has_more":{"type":"boolean"}}},"examples":{"default":{"value":{"object":"list","data":[{"id":"inv_a7b3c9d2e1f4g5h6","object":"invoice","environment":"live","kind":"invoice","number":"INV-2026-0001","status":"sent","amount":1150,"subtotal":1000,"tax_amount":150,"discount_amount":0,"currency":"PHP","description":"Order #1042","line_items":[{"description":"Widget A","quantity":10,"unit_amount":100,"amount":1000}],"customer_id":"cus_abcd1234efgh5678","due_date":"2026-06-20","notes":"Net 14","terms":null,"allow_partial_payment":false,"amount_paid":0,"amount_remaining":1150,"deposit_rate":null,"deposit_due_at":null,"balance_due_at":null,"shipment_id":null,"forfeited_at":null,"payment_id":null,"issued_at":1776839700,"sent_at":1776839705,"paid_at":null,"void_at":null,"metadata":{"order_id":"1042"},"url":"https://nexuspayph.com/invoice/inv_a7b3c9d2e1f4g5h6"}],"has_more":false}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}}}}},"/v1/invoices/{id}":{"get":{"tags":["Invoices"],"summary":"Retrieve an invoice","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invoice","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"},"examples":{"default":{"value":{"id":"inv_a7b3c9d2e1f4g5h6","object":"invoice","environment":"live","kind":"invoice","number":"INV-2026-0001","status":"sent","amount":1150,"subtotal":1000,"tax_amount":150,"discount_amount":0,"currency":"PHP","description":"Order #1042","line_items":[{"description":"Widget A","quantity":10,"unit_amount":100,"amount":1000}],"customer_id":"cus_abcd1234efgh5678","due_date":"2026-06-20","notes":"Net 14","terms":null,"allow_partial_payment":false,"amount_paid":0,"amount_remaining":1150,"deposit_rate":null,"deposit_due_at":null,"balance_due_at":null,"shipment_id":null,"forfeited_at":null,"payment_id":null,"issued_at":1776839700,"sent_at":1776839705,"paid_at":null,"void_at":null,"metadata":{"order_id":"1042"},"url":"https://nexuspayph.com/invoice/inv_a7b3c9d2e1f4g5h6"}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}}}},"patch":{"tags":["Invoices"],"summary":"Update a draft invoice","description":"Only `draft` invoices can be edited (409 otherwise). PATCH semantics; `line_items` replaces the whole array.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateInvoiceBody"}}}},"responses":{"200":{"description":"Updated invoice","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"},"examples":{"default":{"value":{"id":"inv_a7b3c9d2e1f4g5h6","object":"invoice","environment":"live","kind":"invoice","number":"INV-2026-0001","status":"sent","amount":1150,"subtotal":1000,"tax_amount":150,"discount_amount":0,"currency":"PHP","description":"Order #1042","line_items":[{"description":"Widget A","quantity":10,"unit_amount":100,"amount":1000}],"customer_id":"cus_abcd1234efgh5678","due_date":"2026-06-20","notes":"Net 14","terms":null,"allow_partial_payment":false,"amount_paid":0,"amount_remaining":1150,"deposit_rate":null,"deposit_due_at":null,"balance_due_at":null,"shipment_id":null,"forfeited_at":null,"payment_id":null,"issued_at":1776839700,"sent_at":1776839705,"paid_at":null,"void_at":null,"metadata":{"order_id":"1042"},"url":"https://nexuspayph.com/invoice/inv_a7b3c9d2e1f4g5h6"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"insufficient_scope":{"summary":"Key lacks required scope","value":{"error":{"code":"insufficient_scope","message":"api key missing required scope"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"409":{"description":"Not a draft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_state":{"summary":"Illegal state transition","value":{"error":{"code":"invalid_state","message":"only succeeded payments can be refunded"}}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"code":"rate_limited","message":"too many requests"}}}}}}}}},"delete":{"tags":["Invoices"],"summary":"Delete a draft invoice","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"},"id":{"type":"string"}}},"examples":{"default":{"value":{"deleted":true,"id":"inv_a7b3c9d2e1f4g5h6"}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"409":{"description":"Not a draft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_state":{"summary":"Illegal state transition","value":{"error":{"code":"invalid_state","message":"only succeeded payments can be refunded"}}}}}}}}}},"/v1/invoices/{id}/send":{"post":{"tags":["Invoices"],"summary":"Send an invoice (draft → sent)","description":"Issues the invoice and makes its pay page live. If `deposit_rate` is set, arms the deposit due date.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invoice sent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"},"examples":{"default":{"value":{"id":"inv_a7b3c9d2e1f4g5h6","object":"invoice","environment":"live","kind":"invoice","number":"INV-2026-0001","status":"sent","amount":1150,"subtotal":1000,"tax_amount":150,"discount_amount":0,"currency":"PHP","description":"Order #1042","line_items":[{"description":"Widget A","quantity":10,"unit_amount":100,"amount":1000}],"customer_id":"cus_abcd1234efgh5678","due_date":"2026-06-20","notes":"Net 14","terms":null,"allow_partial_payment":false,"amount_paid":0,"amount_remaining":1150,"deposit_rate":null,"deposit_due_at":null,"balance_due_at":null,"shipment_id":null,"forfeited_at":null,"payment_id":null,"issued_at":1776839700,"sent_at":1776839705,"paid_at":null,"void_at":null,"metadata":{"order_id":"1042"},"url":"https://nexuspayph.com/invoice/inv_a7b3c9d2e1f4g5h6"}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"409":{"description":"Not a draft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_state":{"summary":"Illegal state transition","value":{"error":{"code":"invalid_state","message":"only succeeded payments can be refunded"}}}}}}}}}},"/v1/invoices/{id}/void":{"post":{"tags":["Invoices"],"summary":"Void an invoice","description":"Cancels a draft or sent invoice. Paid invoices cannot be voided.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invoice voided","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"},"examples":{"default":{"value":{"id":"inv_a7b3c9d2e1f4g5h6","object":"invoice","environment":"live","kind":"invoice","number":"INV-2026-0001","status":"void","amount":1150,"subtotal":1000,"tax_amount":150,"discount_amount":0,"currency":"PHP","description":"Order #1042","line_items":[{"description":"Widget A","quantity":10,"unit_amount":100,"amount":1000}],"customer_id":"cus_abcd1234efgh5678","due_date":"2026-06-20","notes":"Net 14","terms":null,"allow_partial_payment":false,"amount_paid":0,"amount_remaining":1150,"deposit_rate":null,"deposit_due_at":null,"balance_due_at":null,"shipment_id":null,"forfeited_at":null,"payment_id":null,"issued_at":1776839700,"sent_at":1776839705,"paid_at":null,"void_at":1776840500,"metadata":{"order_id":"1042"},"url":"https://nexuspayph.com/invoice/inv_a7b3c9d2e1f4g5h6"}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"409":{"description":"Cannot void","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_state":{"summary":"Illegal state transition","value":{"error":{"code":"invalid_state","message":"only succeeded payments can be refunded"}}}}}}}}}},"/v1/products":{"post":{"tags":["Products"],"summary":"Create a product","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductBody"}}}},"responses":{"201":{"description":"Product created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"},"examples":{"default":{"value":{"id":"prd_abc123def456","object":"product","environment":"live","name":"Coffee Mug","description":"Premium ceramic mug","price":250,"currency":"PHP","sku":"SKU-00001","barcode":"2000000000017","image_url":"https://yourstore.com/mug.jpg","track_inventory":true,"stock":100,"in_stock":true,"low_stock_threshold":10,"low_stock":false,"archived":false,"metadata":{},"created":1776839700,"updated":1776839700}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"insufficient_scope":{"summary":"Key lacks required scope","value":{"error":{"code":"insufficient_scope","message":"api key missing required scope"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"code":"rate_limited","message":"too many requests"}}}}}}}}},"get":{"tags":["Products"],"summary":"List products","parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Search across name, SKU, barcode."},{"name":"include_archived","in":"query","schema":{"type":"boolean","default":false}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Paginated list of products","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Product"}},"total":{"type":"integer"},"has_more":{"type":"boolean"}}},"examples":{"default":{"value":{"object":"list","data":[{"id":"prd_abc123def456","object":"product","environment":"live","name":"Coffee Mug","description":"Premium ceramic mug","price":250,"currency":"PHP","sku":"SKU-00001","barcode":"2000000000017","image_url":"https://yourstore.com/mug.jpg","track_inventory":true,"stock":100,"in_stock":true,"low_stock_threshold":10,"low_stock":false,"archived":false,"metadata":{},"created":1776839700,"updated":1776839700}],"total":1,"has_more":false}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}}}}},"/v1/products/{id}":{"get":{"tags":["Products"],"summary":"Retrieve a product","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Product","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"},"examples":{"default":{"value":{"id":"prd_abc123def456","object":"product","environment":"live","name":"Coffee Mug","description":"Premium ceramic mug","price":250,"currency":"PHP","sku":"SKU-00001","barcode":"2000000000017","image_url":"https://yourstore.com/mug.jpg","track_inventory":true,"stock":100,"in_stock":true,"low_stock_threshold":10,"low_stock":false,"archived":false,"metadata":{},"created":1776839700,"updated":1776839700}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}}}},"patch":{"tags":["Products"],"summary":"Update a product","description":"PATCH semantics. A duplicate SKU returns 409.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProductBody"}}}},"responses":{"200":{"description":"Updated product","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"},"examples":{"default":{"value":{"id":"prd_abc123def456","object":"product","environment":"live","name":"Coffee Mug","description":"Premium ceramic mug","price":250,"currency":"PHP","sku":"SKU-00001","barcode":"2000000000017","image_url":"https://yourstore.com/mug.jpg","track_inventory":true,"stock":100,"in_stock":true,"low_stock_threshold":10,"low_stock":false,"archived":false,"metadata":{},"created":1776839700,"updated":1776839700}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"insufficient_scope":{"summary":"Key lacks required scope","value":{"error":{"code":"insufficient_scope","message":"api key missing required scope"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"409":{"description":"Duplicate SKU","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"code":"rate_limited","message":"too many requests"}}}}}}}}},"delete":{"tags":["Products"],"summary":"Archive a product","description":"Soft-delete — sets `archived: true`; the product stops appearing in lists by default.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Archived product","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"},"examples":{"default":{"value":{"id":"prd_abc123def456","object":"product","environment":"live","name":"Coffee Mug","description":"Premium ceramic mug","price":250,"currency":"PHP","sku":"SKU-00001","barcode":"2000000000017","image_url":"https://yourstore.com/mug.jpg","track_inventory":true,"stock":100,"in_stock":true,"low_stock_threshold":10,"low_stock":false,"archived":true,"metadata":{},"created":1776839700,"updated":1776839700}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}}}}},"/v1/payment-links":{"post":{"tags":["Payment Links"],"summary":"Create a payment link","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePaymentLinkBody"}}}},"responses":{"201":{"description":"Payment link created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentLink"},"examples":{"default":{"value":{"id":"plk_abc123def456","object":"payment_link","environment":"live","amount":500,"currency":"PHP","method":"gcash_qr","description":"Concert ticket","image_url":null,"success_url":"https://yourstore.com/thanks","cancel_url":null,"status":"active","customer_id":null,"usage_count":3,"last_used_at":1776840000,"expires_at":null,"metadata":{},"created":1776839700,"url":"https://nexuspayph.com/pay/plk_abc123def456"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"insufficient_scope":{"summary":"Key lacks required scope","value":{"error":{"code":"insufficient_scope","message":"api key missing required scope"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"code":"rate_limited","message":"too many requests"}}}}}}}}},"get":{"tags":["Payment Links"],"summary":"List payment links","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["active","inactive"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"Paginated list of payment links","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/PaymentLink"}},"has_more":{"type":"boolean"}}},"examples":{"default":{"value":{"object":"list","data":[{"id":"plk_abc123def456","object":"payment_link","environment":"live","amount":500,"currency":"PHP","method":"gcash_qr","description":"Concert ticket","image_url":null,"success_url":"https://yourstore.com/thanks","cancel_url":null,"status":"active","customer_id":null,"usage_count":3,"last_used_at":1776840000,"expires_at":null,"metadata":{},"created":1776839700,"url":"https://nexuspayph.com/pay/plk_abc123def456"}],"has_more":false}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}}}}},"/v1/payment-links/{id}":{"get":{"tags":["Payment Links"],"summary":"Retrieve a payment link","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Payment link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentLink"},"examples":{"default":{"value":{"id":"plk_abc123def456","object":"payment_link","environment":"live","amount":500,"currency":"PHP","method":"gcash_qr","description":"Concert ticket","image_url":null,"success_url":"https://yourstore.com/thanks","cancel_url":null,"status":"active","customer_id":null,"usage_count":3,"last_used_at":1776840000,"expires_at":null,"metadata":{},"created":1776839700,"url":"https://nexuspayph.com/pay/plk_abc123def456"}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}}}},"patch":{"tags":["Payment Links"],"summary":"Update a payment link","description":"PATCH semantics. Set `status` to `inactive` to disable the link.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePaymentLinkBody"}}}},"responses":{"200":{"description":"Updated payment link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentLink"},"examples":{"default":{"value":{"id":"plk_abc123def456","object":"payment_link","environment":"live","amount":500,"currency":"PHP","method":"gcash_qr","description":"Concert ticket","image_url":null,"success_url":"https://yourstore.com/thanks","cancel_url":null,"status":"active","customer_id":null,"usage_count":3,"last_used_at":1776840000,"expires_at":null,"metadata":{},"created":1776839700,"url":"https://nexuspayph.com/pay/plk_abc123def456"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"insufficient_scope":{"summary":"Key lacks required scope","value":{"error":{"code":"insufficient_scope","message":"api key missing required scope"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"code":"rate_limited","message":"too many requests"}}}}}}}}}},"/v1/static-qrs":{"post":{"tags":["Static QRs"],"summary":"Create a static QR","description":"Creates a reusable, open-amount QR (backed by a payment link). Print `qr_svg_url`; customers scan and enter the amount.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateStaticQrBody"}}}},"responses":{"201":{"description":"Static QR created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaticQr"},"examples":{"default":{"value":{"id":"sqr_abc123def456","object":"static_qr","environment":"live","name":"Stall 5 — Noodles","reference":"ST-05","location":"North Aisle, Food Court","payment_link_id":"plk_xyz789","url":"https://nexuspayph.com/pay/plk_xyz789","qr_svg_url":"/wapi/static-qrs/sqr_abc123def456/qr.svg","default_method":"gcash_qr","currency":"PHP","archived":false,"archived_at":null,"created":1776839700}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"insufficient_scope":{"summary":"Key lacks required scope","value":{"error":{"code":"insufficient_scope","message":"api key missing required scope"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"code":"rate_limited","message":"too many requests"}}}}}}}}},"get":{"tags":["Static QRs"],"summary":"List static QRs","parameters":[{"name":"include_archived","in":"query","schema":{"type":"boolean","default":false}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Paginated list of static QRs","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/StaticQr"}},"has_more":{"type":"boolean"}}},"examples":{"default":{"value":{"object":"list","data":[{"id":"sqr_abc123def456","object":"static_qr","environment":"live","name":"Stall 5 — Noodles","reference":"ST-05","location":"North Aisle, Food Court","payment_link_id":"plk_xyz789","url":"https://nexuspayph.com/pay/plk_xyz789","qr_svg_url":"/wapi/static-qrs/sqr_abc123def456/qr.svg","default_method":"gcash_qr","currency":"PHP","archived":false,"archived_at":null,"created":1776839700}],"has_more":false}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}}}}},"/v1/static-qrs/{id}":{"get":{"tags":["Static QRs"],"summary":"Retrieve a static QR","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Static QR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaticQr"},"examples":{"default":{"value":{"id":"sqr_abc123def456","object":"static_qr","environment":"live","name":"Stall 5 — Noodles","reference":"ST-05","location":"North Aisle, Food Court","payment_link_id":"plk_xyz789","url":"https://nexuspayph.com/pay/plk_xyz789","qr_svg_url":"/wapi/static-qrs/sqr_abc123def456/qr.svg","default_method":"gcash_qr","currency":"PHP","archived":false,"archived_at":null,"created":1776839700}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}}}},"patch":{"tags":["Static QRs"],"summary":"Update a static QR","description":"PATCH semantics (name/reference/location only). `default_method` and `currency` are fixed at creation.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"reference":{"type":"string","maxLength":60,"nullable":true},"location":{"type":"string","maxLength":200,"nullable":true}}}}}},"responses":{"200":{"description":"Updated static QR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaticQr"},"examples":{"default":{"value":{"id":"sqr_abc123def456","object":"static_qr","environment":"live","name":"Stall 5 — Noodles","reference":"ST-05","location":"North Aisle, Food Court","payment_link_id":"plk_xyz789","url":"https://nexuspayph.com/pay/plk_xyz789","qr_svg_url":"/wapi/static-qrs/sqr_abc123def456/qr.svg","default_method":"gcash_qr","currency":"PHP","archived":false,"archived_at":null,"created":1776839700}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"insufficient_scope":{"summary":"Key lacks required scope","value":{"error":{"code":"insufficient_scope","message":"api key missing required scope"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"code":"rate_limited","message":"too many requests"}}}}}}}}},"delete":{"tags":["Static QRs"],"summary":"Archive a static QR","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Archived static QR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaticQr"},"examples":{"default":{"value":{"id":"sqr_abc123def456","object":"static_qr","environment":"live","name":"Stall 5 — Noodles","reference":"ST-05","location":"North Aisle, Food Court","payment_link_id":"plk_xyz789","url":"https://nexuspayph.com/pay/plk_xyz789","qr_svg_url":"/wapi/static-qrs/sqr_abc123def456/qr.svg","default_method":"gcash_qr","currency":"PHP","archived":true,"archived_at":1776840500,"created":1776839700}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}}}}},"/v1/embed_tokens":{"post":{"tags":["Embed"],"summary":"Mint an embed token","description":"Returns a short-lived JWT to mount an `/embed/*` widget (payments checkout or merchant panel). `scope_value` is never echoed back.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEmbedTokenBody"}}}},"responses":{"201":{"description":"Embed token created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbedToken"},"examples":{"default":{"value":{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…","expires_at":"2026-06-13T18:30:00Z","project_uuid":"cedf830f-1234-5678-9abc-def012345678","surface":"payments","audience":"merchant","scope_field":null,"tabs":null,"ttl_seconds":1800}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Missing or malformed field","value":{"error":{"code":"invalid_request","message":"amount must be a positive number"}}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"insufficient_scope":{"summary":"Key lacks required scope","value":{"error":{"code":"insufficient_scope","message":"api key missing required scope"}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Resource not found","value":{"error":{"code":"not_found","message":"payment not found"}}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"code":"rate_limited","message":"too many requests"}}}}}}}}}},"/v1/methods":{"get":{"tags":["Meta"],"summary":"List available payment methods","description":"Methods enabled for the environment implied by your API key, with the currencies and providers that support each.","responses":{"200":{"description":"Methods","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"method":{"type":"string"},"currencies":{"type":"array","items":{"type":"string"}},"providers":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"display_name":{"type":"string"}}}}}}}}},"examples":{"default":{"value":{"data":[{"method":"gcash_qr","currencies":["PHP"],"providers":[{"code":"directpay","display_name":"DirectPay"}]}]}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}}}}},"/v1/currencies":{"get":{"tags":["Meta"],"summary":"List supported currencies","responses":{"200":{"description":"Currencies","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"string"}}}},"examples":{"default":{"value":{"data":["PHP"]}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}}}}},"/v1/audit_events":{"get":{"tags":["Audit"],"summary":"List audit events","description":"Your account's audit trail. Cursor-paginate with `starting_after` (numeric id). For rows not attributable to your own merchant actions, `actor_id`/`ip`/`user_agent` are scrubbed to null.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"starting_after","in":"query","schema":{"type":"integer","minimum":1},"description":"Numeric cursor — the last id from the previous page."},{"name":"action","in":"query","schema":{"type":"string","maxLength":100},"description":"Filter by action."}],"responses":{"200":{"description":"Audit events","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"actor_type":{"type":"string","enum":["api","merchant","admin","system"]},"actor_id":{"type":"string","nullable":true},"action":{"type":"string"},"resource_type":{"type":"string","nullable":true},"resource_id":{"type":"string","nullable":true},"metadata":{"type":"object","additionalProperties":true,"nullable":true},"ip":{"type":"string","nullable":true},"user_agent":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"}}}},"has_more":{"type":"boolean"}}},"examples":{"default":{"value":{"data":[{"id":12345,"actor_type":"api","actor_id":null,"action":"payment.created","resource_type":"payment","resource_id":"pay_001","metadata":{"amount":500},"ip":null,"user_agent":null,"created_at":"2026-06-13T12:30:00Z"}],"has_more":false}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"summary":"Missing / invalid API key","value":{"error":{"code":"unauthenticated","message":"missing Authorization bearer token"}}}}}}}}}},"/v1/health":{"get":{"tags":["Meta"],"summary":"Service health","description":"Public, unauthenticated. Rolls up component (db, redis) health with per-component latency. Returns 503 when overall status is `down`.","security":[],"responses":{"200":{"description":"Health (ok or degraded)","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","degraded","down"]},"components":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"status":{"type":"string","enum":["ok","degraded","down"]},"latency_ms":{"type":"number"}}}},"time":{"type":"integer"}}},"examples":{"default":{"value":{"status":"ok","components":[{"name":"db","status":"ok","latency_ms":12},{"name":"redis","status":"ok","latency_ms":1}],"time":1776840000}}}}}},"503":{"description":"Down","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["down"]},"components":{"type":"array","items":{"type":"object"}},"time":{"type":"integer"}}}}}}}}}},"tags":[{"name":"Payments","description":"Create and look up payments."},{"name":"Refunds","description":"Refund all or part of a succeeded payment."},{"name":"Payouts","description":"Move funds from your balance to an external destination."},{"name":"Events","description":"The canonical log of every merchant-visible state change. Backs webhook delivery."},{"name":"Webhooks","description":"Register endpoints, understand delivery format, verify signatures."},{"name":"Balance","description":"Your ledger balance per environment."},{"name":"Customers","description":"Store customer records to attach to payments and invoices."},{"name":"Invoices","description":"Create, send, and collect itemized invoices with a shareable pay page."},{"name":"Products","description":"Your catalog — used by the POS, invoice line-items, and inventory."},{"name":"Payment Links","description":"Shareable, reusable checkout links (fixed or customer-entered amount)."},{"name":"Static QRs","description":"Printable open-amount QR codes backed by a payment link."},{"name":"Embed","description":"Mint short-lived tokens for embeddable /embed/* widgets."},{"name":"Audit","description":"Your account audit trail."},{"name":"Meta","description":"Operational endpoints (methods, currencies, health check, API reference)."}],"webhooks":{"payment":{"post":{"summary":"Payment state changes","description":"NexusPay POSTs a signed JSON envelope to your registered endpoint whenever a payment transitions state.\n\n**Headers delivered:**\n- `X-NexusPay-Signature`: HMAC-SHA256 signature (see format below)\n- `X-NexusPay-Event`: the event type being delivered\n- `X-NexusPay-Delivery`: numeric delivery attempt id\n- `User-Agent`: `NexusPay/1.0 (+https://nexuspayph.com)`\n\n**Signature format:**\n\n```\nX-NexusPay-Signature: t=<unix>,v1=<hex>\nsignedPayload = `${t}.${rawBody}`\nsignature     = hmacSha256(signingSecret, signedPayload)\n```\n\nAlways compute the HMAC over the **raw request body** (no whitespace normalisation). Reject any webhook where `|now − t| > 5 minutes`.\n\n**Retries:** 1 min, 5 min, 30 min, 2 h, 6 h, 24 h. After 6 consecutive non-2xx responses the delivery is parked as `failed`. Replay manually from the dashboard.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"},"examples":{"default":{"value":{"id":"evt_2e599b29fc3203f06a63cc16","object":"event","type":"payment.succeeded","environment":"test","created":1776840100,"data":{"object":{"id":"pay_0e1f2a4c9b8d6a3f5c7e1d2b","object":"payment","environment":"test","status":"succeeded","amount":500,"currency":"PHP","method":"gcash_qr","provider":"directpay","provider_ref":"DP-20260422-00042","checkout_url":"https://nexuspayph.com/checkout/pay_0e1f2a4c9b8d6a3f5c7e1d2b","qr_code":"00020101021128680014ph.ppmi.p2m0113011234567890012100005303608540550056022PH5912MAGIA STORE6011MANILA62150511ORDER10426304ABCD","qr_code_url":"https://c.tsdpay.tech/v2/qr/TlVRK0tu...TE9","app_link":null,"return_url":"https://yourstore.com/thanks","description":"Order #1042","customer":{"email":"alice@example.com","name":"Alice Santos"},"metadata":{"order_id":"1042","sku":"mage-robe"},"customer_id":null,"payment_link_id":null,"fee_amount":12.5,"net_amount":null,"idempotency_key":"7a3f-4c2e-1b8d","failure":null,"expires_at":1776840000,"succeeded_at":1776840100,"failed_at":null,"created":1776839700,"receipt_url":null}}}}}}}},"responses":{"2XX":{"description":"Your server acknowledges receipt. NexusPay stops retrying."}}}}}}