{"openapi":"3.1.1","info":{"title":"Paymegate Merchant API","version":"1.0.0","description":"Create orders, manage payout wallets, and reconcile payments with tenant-isolated server APIs. Keep API keys on your server."},"servers":[{"url":"https://www.paymegate.shop/api","description":"Merchant API"}],"tags":[{"name":"Configuration"},{"name":"Orders"},{"name":"Payments"}],"paths":{"/v1/wallet":{"get":{"tags":["Configuration"],"operationId":"getApiWallet","summary":"Get the payout wallet used by future orders","security":[{"MerchantApiKey":[]}],"responses":{"200":{"description":"Current payout-wallet configuration.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiWalletEnvelope"}}}},"401":{"$ref":"#/components/responses/InvalidApiKey"},"403":{"$ref":"#/components/responses/Forbidden"}}},"put":{"tags":["Configuration"],"operationId":"updateApiWallet","summary":"Replace the payout wallet used by future orders","description":"Requires a live API key. Existing orders keep their snapshotted receiving wallet and checkout session.","security":[{"MerchantApiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiWalletUpdateRequest"},"example":{"payoutWallet":"0x2222222222222222222222222222222222222222","orderWalletOverrideEnabled":true}}}},"responses":{"200":{"description":"Updated payout-wallet configuration.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiWalletEnvelope"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/InvalidApiKey"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/v1/webhook":{"get":{"tags":["Configuration"],"operationId":"getApiWebhook","summary":"Get the merchant webhook URL","description":"Returns the authenticated merchant's single outbound webhook configuration. Signing secrets and digests are never returned by this operation.","security":[{"MerchantApiKey":[]}],"x-required-scope":"api:read","responses":{"200":{"description":"Current webhook configuration","including an explicit unconfigured state.":null,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiWebhookEnvelope"}}}},"401":{"$ref":"#/components/responses/InvalidApiKey"},"403":{"$ref":"#/components/responses/Forbidden"}}},"put":{"tags":["Configuration"],"operationId":"updateApiWebhook","summary":"Create or replace the merchant webhook URL","description":"Requires a live API key with webhooks:write. The operation preserves the current signing secret and subscribed events, and reactivates a disabled endpoint when replacing its URL. On first configuration only, signingSecret is returned once and cannot be recovered later.","security":[{"MerchantApiKey":[]}],"x-required-scope":"webhooks:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiWebhookUpdateRequest"},"example":{"url":"https://merchant.example/webhooks/paymegate"}}}},"responses":{"200":{"description":"Created or updated webhook configuration. signingSecret is present only when the endpoint is configured for the first time.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ApiWebhookEnvelope"},{"$ref":"#/components/schemas/ApiWebhookCreatedEnvelope"}]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/InvalidApiKey"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/UnprocessableEntity"}}}},"/v1/payment-methods":{"get":{"tags":["Payments"],"operationId":"listPaymentMethods","summary":"List active payment methods and their minimums","description":"Returns concrete active payment-provider keys and their minimums without filtering by an entered amount. The special all and legacy hosted sentinels are never returned to API-key clients. The upstream provider-status catalogue is cached in memory for one hour, and concurrent cache misses share one provider request.","security":[{"MerchantApiKey":[]}],"parameters":[{"name":"forceFetch","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"When true","bypasses and refreshes the one-hour provider-status cache. Concurrent refreshes still share one provider request.":null}],"responses":{"200":{"description":"Active provider-status methods with minimum amount and currency.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderStatusMethodListEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"502":{"$ref":"#/components/responses/ProviderUnavailable"}}}},"/v1/orders":{"post":{"tags":["Orders"],"operationId":"createOrder","summary":"Initialize an unpaid order","description":"Every request creates a new UNPAID order and one private order-scoped checkout session. The response exposes only safe session-derived details; private provider URLs and credentials are never returned. transactionRef starts null and a transaction is created only after verified settlement. A receivingWallet override is accepted only when the merchant enabled order wallet overrides. Test API keys cannot call this live route.","security":[{"MerchantApiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePaymentRequest"}}}},"responses":{"201":{"description":"Order initialized with a platform-owned checkoutUrl.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderEnvelope"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/InvalidApiKey"},"403":{"description":"The API key cannot create orders","wallet overrides are disabled":null,"or the merchant has blocked this customer.":null,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"502":{"$ref":"#/components/responses/ProviderUnavailable"}}}}},"components":{"schemas":{"ApiWalletEnvelope":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ApiWallet"}}}]},"ApiWalletUpdateRequest":{"type":"object","additionalProperties":false,"required":["payoutWallet"],"properties":{"payoutWallet":{"type":"string","pattern":"^0x[0-9A-Fa-f]{40}$"},"orderWalletOverrideEnabled":{"type":"boolean","description":"Allows receivingWallet on API order creation when true."}}},"ApiWebhookEnvelope":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ApiWebhook"}}}]},"ApiWebhookUpdateRequest":{"type":"object","additionalProperties":false,"required":["url"],"properties":{"url":{"type":"string","format":"uri","pattern":"^https://","maxLength":2048,"description":"Public HTTPS destination. Localhost","private IP ranges":null,"credentials":null,"and internal hostnames are rejected.":null}}},"ApiWebhookCreatedEnvelope":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ApiWebhookCreated"}}}]},"ProviderStatusMethodListEnvelope":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","required":["paymentMethods","paymentMethodsKeys"],"properties":{"paymentMethods":{"type":"array","items":{"$ref":"#/components/schemas/PaymentMethod"}},"paymentMethodsKeys":{"type":"array","items":{"type":"string"}}}}}}]},"CreatePaymentRequest":{"type":"object","additionalProperties":false,"required":["amount","currency","paymentMethodsKeys","customer"],"properties":{"externalId":{"type":["string","null"],"minLength":1,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$","description":"Optional merchant metadata; duplicates are allowed and no lookup uniqueness is implied."},"amount":{"$ref":"#/components/schemas/Amount"},"currency":{"$ref":"#/components/schemas/Currency"},"paymentMethodsKeys":{"$ref":"#/components/schemas/PaymentMethodsKeys"},"receivingWallet":{"type":"string","pattern":"^0x[0-9A-Fa-f]{40}$","description":"Optional order-scoped payout wallet. The merchant must first enable order wallet overrides."},"customer":{"$ref":"#/components/schemas/CustomerInput"},"description":{"type":"string","minLength":1,"maxLength":512},"productImageUrl":{"type":"string","format":"uri","maxLength":2048,"pattern":"^https://"},"returnUrl":{"type":"string","format":"uri","maxLength":2048,"pattern":"^https://"},"expiresAt":{"type":"string","format":"date-time","description":"Optional future expiry no more than one year from creation."},"metadata":{"$ref":"#/components/schemas/Metadata"}}},"OrderEnvelope":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Order"}}}]},"Error":{"type":"object","required":["success","error"],"properties":{"success":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}},"SuccessEnvelope":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{}}},"ApiWallet":{"type":"object","required":["configured","payoutWallet","walletType","orderWalletOverrideEnabled","createdAt","updatedAt"],"properties":{"configured":{"type":"boolean"},"payoutWallet":{"type":"string"},"walletType":{"type":"string","enum":["custom","custodial"]},"orderWalletOverrideEnabled":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}}},"ApiWebhook":{"type":"object","additionalProperties":false,"required":["configured","endpointId","url","events","status","createdAt","updatedAt"],"properties":{"configured":{"type":"boolean"},"endpointId":{"type":["string","null"],"format":"uuid"},"url":{"type":["string","null"],"format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["order.paid","payment.created","payment.processing","payment.paid","payment.failed","payment.expired"]}},"status":{"type":"string","enum":["not_configured","active","disabled"]},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}}},"ApiWebhookCreated":{"type":"object","additionalProperties":false,"required":["configured","endpointId","url","events","status","createdAt","updatedAt","signingSecret"],"properties":{"configured":{"type":"boolean","const":true},"endpointId":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["order.paid","payment.created","payment.processing","payment.paid","payment.failed","payment.expired"]}},"status":{"type":"string","enum":["active","disabled"]},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"signingSecret":{"type":"string","readOnly":true,"description":"Returned once","and only when PUT creates the first webhook configuration. Store it securely for signature verification.":null}}},"PaymentMethod":{"type":"object","required":["key","displayName","minimumAmount","minimumCurrency","status"],"properties":{"key":{"type":"string","example":"stripe","pattern":"^[a-z0-9][a-z0-9_-]*$"},"displayName":{"type":"string","example":"Stripe"},"minimumAmount":{"$ref":"#/components/schemas/Amount"},"minimumCurrency":{"$ref":"#/components/schemas/Currency"},"status":{"type":"string","const":"AVAILABLE"}}},"Amount":{"type":"string","pattern":"^[0-9]{1,18}(?:\\\\.[0-9]{1,3})?$","example":"100.00","description":"Positive exact decimal string. The permitted scale is determined by the ISO 4217 currency (zero","two":null,"or three decimal places); the service normalizes valid values.":null},"Currency":{"type":"string","pattern":"^[A-Z]{3}$","example":"USD"},"PaymentMethodsKeys":{"description":"Unique provider keys, or the all sentinel by itself to snapshot every active concrete provider.","oneOf":[{"type":"array","minItems":1,"maxItems":1,"uniqueItems":true,"prefixItems":[{"type":"string","const":"all"}],"items":false},{"type":"array","minItems":1,"maxItems":64,"uniqueItems":true,"items":{"type":"string","maxLength":64,"pattern":"^(?!(?:all|hosted)$)[a-z0-9][a-z0-9_-]{0,63}$"}}]},"CustomerInput":{"type":"object","additionalProperties":false,"required":["email","fullName"],"properties":{"email":{"type":"string","format":"email","maxLength":254},"fullName":{"type":"string","minLength":1,"maxLength":128}}},"Metadata":{"type":"object","additionalProperties":true,"description":"Plain JSON object","maximum depth 3; dangerous prototype keys are rejected.":null},"Order":{"type":"object","required":["merchantId","orderUUID","transactionRef","externalId","amount","currency","status","customerId","customerEmail","customerFullName","feePercent","platformFeeAmount","netAmount","feeCollectionStatus","paymentMethodsKeys","checkoutUrl","createdAt","updatedAt"],"properties":{"merchantId":{"type":"string"},"orderUUID":{"type":"string","format":"uuid"},"transactionRef":{"type":["string","null"],"description":"Null until a verified provider webhook supplies the reference; remains null for forced reconciliation."},"externalId":{"type":["string","null"]},"amount":{"$ref":"#/components/schemas/Amount"},"currency":{"$ref":"#/components/schemas/Currency"},"receivingWallet":{"type":"string","pattern":"^0x[0-9A-Fa-f]{40}$"},"status":{"type":"string","enum":["UNPAID","PAID","FAILED","EXPIRED","CANCELLED"]},"provisioningStatus":{"type":"string","enum":["CREATED","PROVISIONING","READY","FAILED","SETTLED","EXPIRED","ABANDONED"],"description":"Safe lifecycle value derived from the order's active private checkout session."},"expiresAt":{"type":"string","format":"date-time"},"customerId":{"type":"string","format":"uuid"},"customerEmail":{"type":"string","format":"email"},"customerFullName":{"type":"string"},"feePercent":{"$ref":"#/components/schemas/FeePercent"},"platformFeeAmount":{"$ref":"#/components/schemas/Amount"},"netAmount":{"$ref":"#/components/schemas/Amount"},"feeCollectionStatus":{"type":"string","enum":["PROVIDER_SPLIT","ACCOUNTED_NOT_COLLECTED"]},"paymentMethodsKeys":{"type":"array","uniqueItems":true,"items":{"type":"string"},"description":"Concrete provider keys snapshotted on this order. The all sentinel is expanded and never returned here."},"source":{"type":"string","enum":["api","web"]},"checkoutUrl":{"type":"string","format":"uri","description":"Platform-owned customer checkout URL at /pay/{orderUUID}; upstream provider URLs are never returned."},"directPaymentLink":{"type":"string","format":"uri","description":"Present only when paymentMethodsKeys contains exactly one provider; points to /payment/process/{orderUUID}."},"providerAddressIn":{"type":"string"},"providerPayoutAddress":{"type":"string"},"providerTxIn":{"type":"string"},"providerTxOut":{"type":"string"},"receivedAmount":{"type":"string"},"receivedCurrency":{"type":"string"},"paidTransactionUUID":{"type":"string"},"paidAt":{"type":"string","format":"date-time"},"forced":{"type":"boolean"},"forcedAt":{"type":"string","format":"date-time"},"forcedBy":{"type":"string"},"forceReason":{"type":"string"},"forcedProviderStatus":{"type":"string","description":"payment provider status observed immediately before the merchant forced payment."},"forcedTransactionId":{"type":"string","pattern":"^FORCED_[0-9a-f-]{36}$"},"description":{"type":"string"},"metadata":{"$ref":"#/components/schemas/Metadata"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"FeePercent":{"type":"string","pattern":"^(?:(?:\\\\d|[1-8]\\\\d)(?:\\\\.\\\\d{1,4})?|99(?:\\\\.0{1,4})?)$","example":"0.8","description":"Exact percentage from 0 through 99","snapshotted on each order and transaction.":null}},"responses":{"InvalidApiKey":{"description":"Invalid","unknown":null,"or revoked API key.":null,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"invalid_api_key","message":"Invalid API key.","requestId":"req_01J123"}}}}},"ValidationError":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"validation_error","message":"Invalid request data.","requestId":"req_01J123"}}}}},"UnprocessableEntity":{"description":"The request is valid but cannot be fulfilled in current merchant or provider state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"payout_wallet_required","message":"Configure a valid EVM payout wallet before creating payments.","requestId":"req_01J123"}}}}},"Unauthorized":{"description":"Missing or invalid authentication.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"unauthorized","message":"Authentication is required.","requestId":"req_01J123"}}}}},"ProviderUnavailable":{"description":"Provider unavailable; no provider secrets are exposed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"provider_unavailable","message":"Payment provider is temporarily unavailable.","requestId":"req_01J123"}}}}}},"securitySchemes":{"MerchantApiKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Your live merchant API key. Keep it on your server and never expose it in browser code."}}}}