{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition","code-group"]},"type":"markdown"},"seo":{"title":"Submerchant onboarding for marketplaces | xMoney Documentation","description":"Redirect submerchants from your marketplace to the hosted xMoney onboarding flow and track their onboarding status.","llmstxt":{"hide":false,"title":"xMoney Documentation","description":"Guides and API references for integrating xMoney card and crypto payments.","sections":[{"title":"Guides","description":"Integration guides for card payments, crypto, checkout, and dashboard.","includeFiles":["guides/**/*.md"]},{"title":"Card API","description":"REST API reference and concepts for xMoney card payments.","includeFiles":["api/**/*.md","api/**/*.yaml"]},{"title":"Crypto API","description":"REST API reference and concepts for xMoney crypto payments.","includeFiles":["crypto_api/**/*.md","crypto_api/**/*.yaml"]},{"title":"Card Issuing API","description":"Guides and API reference for xMoney whitelabel card issuing partners.","includeFiles":["card_issuing_api/**/*.md","card_issuing_api/**/*.yaml"]}]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"submerchant-onboarding","__idx":0},"children":["Submerchant onboarding"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the marketplace onboarding flow to connect a submerchant to your xMoney account and send them to a hosted onboarding experience at ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dashboard.xmoney.com"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Your marketplace creates a short-lived, signed redirect URL on its backend. The submerchant follows the URL, creates or connects an xMoney account, and provides their business and compliance information directly to xMoney. Your marketplace does not collect or send KYB documents through this flow."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"how-the-flow-works","__idx":1},"children":["How the flow works"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Your backend assigns a stable internal ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantId"]}," to the submerchant."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Your backend creates and signs an xMoney Connect URL."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Your application redirects the submerchant's browser to the signed URL."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["xMoney validates the signature and starts a secure browser session."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The submerchant creates an account or signs in to an existing account."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The submerchant completes the hosted business onboarding flow."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Your backend polls the onboarding status using the same ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantId"]},". xMoney does not send marketplace onboarding-status webhooks."]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"Hosted onboarding"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The onboarding form and all KYB data collection are hosted by xMoney. Do not include business data, personal data, or documents in the redirect URL."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"before-you-start","__idx":2},"children":["Before you start"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Contact your xMoney representative to receive the credentials for your marketplace:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Value"},"children":["Value"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Purpose"},"children":["Purpose"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["slug"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Public identifier used in your Connect URL, for example ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["acme-marketplace"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signingSecret"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Shared secret used by your backend to sign redirect URLs."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["keyId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Username for onboarding-status polling."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pollingSecret"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Password for onboarding-status polling."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Keep ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signingSecret"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pollingSecret"]}," in a secret manager and use them only from your backend. Never expose them in browser code, mobile applications, client-side logs, or public repositories."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Confirm the production and test dashboard base URLs with your xMoney representative before integrating."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"create-a-signed-onboarding-url","__idx":3},"children":["Create a signed onboarding URL"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The production redirect URL has this format:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"text","header":{"controls":{"copy":{}}},"source":"https://dashboard.xmoney.com/connect/{slug}?merchantId={MERCHANT_ID}&timestamp={ISO8601_UTC}&nonce={NONCE}&signature={SIGNATURE}\n","lang":"text"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"url-parameters","__idx":4},"children":["URL parameters"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Parameter"},"children":["Parameter"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Required"},"children":["Required"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Rules"},"children":["Rules"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["slug"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Your xMoney-provisioned marketplace identifier. Lowercase letters, numbers, and hyphens only; 2–64 characters."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Your stable internal identifier for the submerchant; maximum 191 characters."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["timestamp"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Current UTC time in ISO 8601 format. Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["YYYY-MM-DDTHH:mm:ssZ"]},". The URL is accepted for 15 minutes."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nonce"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A cryptographically random, one-time value. Use 8–128 letters, numbers, underscores, or hyphens."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signature"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A base64url-encoded HMAC-SHA256 signature of the complete URL without the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signature"]}," parameter."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use a new timestamp and nonce every time you create a redirect, including when retrying a failed or expired redirect. Keep your server clock synchronized with UTC."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"sign-the-exact-url","__idx":5},"children":["Sign the exact URL"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["First, construct the complete URL without ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signature"]},". This unsigned URL is the payload:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"text","header":{"controls":{"copy":{}}},"source":"https://dashboard.xmoney.com/connect/acme-marketplace?merchantId=merchant-123&timestamp=2026-09-03T10:15:00Z&nonce=I6d9jK2L0mN4pQ8R\n","lang":"text"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Then compute:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"text","header":{"controls":{"copy":{}}},"source":"signature = base64url(\n  HMAC-SHA256(\n    key = signingSecret,\n    message = unsignedUrl\n  )\n)\n","lang":"text"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Append the result as the final ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signature"]}," query parameter."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"The signed value must match exactly"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Query parameter order and encoding are part of the signature. Sign the exact URL string that you redirect the browser to, before appending ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signature"]},". Do not parse, reorder, decode, or re-encode the URL after signing it."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the recommended query parameter order: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantId"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["timestamp"]},", then ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nonce"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"signing-examples","__idx":6},"children":["Signing examples"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["These examples use only standard libraries."]},{"$$mdtype":"Tag","name":"CodeGroup","attributes":{"mode":"tabs"},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"js","data-title":"Node.js","header":{"title":"Node.js","controls":{"copy":{}}},"source":"const crypto = require('crypto');\n\nfunction createSubmerchantOnboardingUrl({\n  dashboardBaseUrl = 'https://dashboard.xmoney.com',\n  slug,\n  signingSecret,\n  merchantId,\n}) {\n  const timestamp = new Date().toISOString().replace(/\\.\\d{3}Z$/, 'Z');\n  const nonce = crypto.randomBytes(16).toString('base64url');\n\n  const payloadUrl = new URL(`${dashboardBaseUrl}/connect/${slug}`);\n  payloadUrl.searchParams.set('merchantId', merchantId);\n  payloadUrl.searchParams.set('timestamp', timestamp);\n  payloadUrl.searchParams.set('nonce', nonce);\n\n  const payload = payloadUrl.toString();\n  const signature = crypto\n    .createHmac('sha256', signingSecret)\n    .update(payload, 'utf8')\n    .digest('base64url');\n\n  return `${payload}&signature=${signature}`;\n}\n","lang":"js"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"php","data-title":"PHP","header":{"title":"PHP","controls":{"copy":{}}},"source":"<?php\n\nfunction base64url_encode(string $data): string {\n    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');\n}\n\nfunction createSubmerchantOnboardingUrl(\n    string $slug,\n    string $signingSecret,\n    string $merchantId,\n    string $dashboardBaseUrl = 'https://dashboard.xmoney.com'\n): string {\n    $timestamp = gmdate('Y-m-d\\TH:i:s\\Z');\n    $nonce = base64url_encode(random_bytes(16));\n\n    $payload = sprintf(\n        '%s/connect/%s?merchantId=%s&timestamp=%s&nonce=%s',\n        rtrim($dashboardBaseUrl, '/'),\n        rawurlencode($slug),\n        rawurlencode($merchantId),\n        rawurlencode($timestamp),\n        rawurlencode($nonce)\n    );\n\n    $signature = base64url_encode(\n        hash_hmac('sha256', $payload, $signingSecret, true)\n    );\n\n    return $payload . '&signature=' . rawurlencode($signature);\n}\n","lang":"php"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","data-title":"Python","header":{"title":"Python","controls":{"copy":{}}},"source":"import base64\nimport hashlib\nimport hmac\nimport secrets\nfrom datetime import datetime, timezone\nfrom urllib.parse import urlencode\n\n\ndef base64url_encode(raw: bytes) -> str:\n    return base64.urlsafe_b64encode(raw).decode(\"ascii\").rstrip(\"=\")\n\n\ndef create_submerchant_onboarding_url(\n    slug: str,\n    signing_secret: str,\n    merchant_id: str,\n    dashboard_base_url: str = \"https://dashboard.xmoney.com\",\n) -> str:\n    timestamp = datetime.now(timezone.utc).strftime(\"%Y-%m-%dT%H:%M:%SZ\")\n    nonce = base64url_encode(secrets.token_bytes(16))\n    query = urlencode(\n        {\n            \"merchantId\": merchant_id,\n            \"timestamp\": timestamp,\n            \"nonce\": nonce,\n        }\n    )\n    payload = f\"{dashboard_base_url.rstrip('/')}/connect/{slug}?{query}\"\n    digest = hmac.new(\n        signing_secret.encode(\"utf-8\"),\n        payload.encode(\"utf-8\"),\n        hashlib.sha256,\n    ).digest()\n    signature = base64url_encode(digest)\n\n    return f\"{payload}&signature={signature}\"\n","lang":"python"},"children":[]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Call the relevant function on your backend and redirect the browser to the returned URL."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"redirect-the-submerchant","__idx":7},"children":["Redirect the submerchant"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Return the signed URL from your backend and navigate the submerchant's browser to it using a full-page redirect."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Do not generate the signature in frontend code. A frontend application can request a newly signed URL from your backend immediately before redirecting:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"js","header":{"controls":{"copy":{}}},"source":"const response = await fetch('/api/xmoney/onboarding-url', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ merchantId: 'merchant-123' }),\n});\n\nconst { redirectUrl } = await response.json();\nwindow.location.assign(redirectUrl);\n","lang":"js"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A valid redirect starts an xMoney browser session for up to 24 hours. If the link is not validated within 15 minutes, or if its nonce was already used, generate a new signed URL."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"what-the-submerchant-completes","__idx":8},"children":["What the submerchant completes"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After xMoney validates the redirect, the submerchant can create a new xMoney account or connect an existing account. New accounts must verify their email address."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The hosted onboarding flow then collects:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["legal business and contact information;"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["business activity, ownership, and legal-representative information;"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["website and processing information;"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["required company and identity documents;"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["payout bank-account information; and"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["final declarations and submission for review."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Referred submerchants must apply for FIAT processing. After submission, xMoney reviews the business and may request additional information before activation."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"poll-onboarding-status","__idx":9},"children":["Poll onboarding status"]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"Polling instead of webhooks"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["xMoney does not send webhook notifications when a referred submerchant's onboarding status changes. Poll this endpoint from your backend to retrieve the latest status."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the marketplace's internal ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantId"]}," to retrieve the current high-level onboarding status:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"http","header":{"controls":{"copy":{}}},"source":"GET {partnersApiBaseUrl}/business-referrals/{merchantId}/onboarding-status\nAuthorization: Basic base64(keyId:pollingSecret)\nAccept: application/json\n","lang":"http"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For example:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl --user \"$XMONEY_KEY_ID:$XMONEY_POLLING_SECRET\" \\\n  --header \"Accept: application/json\" \\\n  \"$XMONEY_PARTNERS_API_URL/business-referrals/merchant-123/onboarding-status\"\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A successful response has this shape:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"merchantId\": \"merchant-123\",\n  \"xmoneyMerchantId\": 7291,\n  \"status\": \"kyb_review_in_progress\",\n  \"kybDecisionStatus\": \"pending\",\n  \"contractStatus\": null\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The endpoint returns only referrals associated with the business represented by your credentials. A ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantId"]}," belonging to another marketplace is not accessible."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"response-fields","__idx":10},"children":["Response fields"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Field"},"children":["Field"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Type"},"children":["Type"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Your parent-scoped merchant identifier from the signed redirect."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["xmoneyMerchantId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["number or null"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The xMoney business identifier. It remains ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}," until the submerchant submits a business application."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The current overall onboarding lifecycle status."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["kybDecisionStatus"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string or null"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The current KYB decision: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pending"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["success"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}," when no decision is available."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["contractStatus"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string or null"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The contract delivery status: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sent"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["completed"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]},". A declined contract is represented by ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status: contract_declined"]},"."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"status-values","__idx":11},"children":["Status values"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Status"},"children":["Status"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Meaning"},"children":["Meaning"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["redirect_received"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The signed redirect was validated, but the submerchant has not connected an account."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["application_started"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["An account is connected, but the FIAT business application has not been submitted."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ubo_kyc_pending"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["At least one ultimate beneficial owner still needs to complete KYC."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["kyb_review_in_progress"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["xMoney is reviewing the submitted FIAT business application."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["kyb_approved"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["KYB is approved and the application has reached the contract stage."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["kyb_rejected"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The FIAT business application was rejected."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["contract_sent"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The contract was sent for signature."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["contract_declined"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The contract was declined."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["contract_signed"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The contract was signed and account activation is pending."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["account_active"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The FIAT onboarding is complete and the account is active."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Before the submerchant first opens and validates a signed redirect URL, xMoney has no record of the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantId"]},". Polling that ID returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["404 Not Found"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Treat the other common responses as follows:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"HTTP status"},"children":["HTTP status"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Meaning"},"children":["Meaning"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["200 OK"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Status returned successfully."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401 Unauthorized"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The polling credentials are missing or invalid."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["404 Not Found"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantId"]}," is unknown to this marketplace."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Continue polling while the onboarding process is progressing and stop after ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["account_active"]},". Coordinate any follow-up for ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["kyb_rejected"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["contract_declined"]}," with xMoney. Use exponential backoff and avoid polling more often than the interval agreed with xMoney."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"authentication-and-ip-restrictions","__idx":12},"children":["Authentication and IP restrictions"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The polling endpoint uses HTTP Basic authentication:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Set the username to your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["keyId"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Set the password to your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pollingSecret"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Send credentials only over HTTPS."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["xMoney validates that the credential is active and verifies the polling secret securely. If an IP allowlist is configured for your credential, requests must also originate from an allowed IP address. Invalid credentials and disallowed IP addresses return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401 Unauthorized"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"security-checklist","__idx":13},"children":["Security checklist"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Create signed URLs only on your backend."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Store ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signingSecret"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pollingSecret"]}," in a secret manager."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Generate a cryptographically random nonce for every redirect."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Never reuse a nonce, even for the same ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantId"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Generate the timestamp immediately before redirecting."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Keep the unsigned URL byte-for-byte identical after signing."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Use HTTPS in production."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Do not log secrets or complete signed URLs."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Do not place personal, business, or KYB data in query parameters."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Scope polling results by the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantId"]}," stored in your own system."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"troubleshooting-signed-redirects","__idx":14},"children":["Troubleshooting signed redirects"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For security, invalid, expired, and reused redirects display a generic invalid-link response. Check the following before contacting xMoney:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Problem"},"children":["Problem"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"What to check"},"children":["What to check"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Invalid signature"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Confirm that both systems use the same ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signingSecret"]},", HMAC-SHA256, UTF-8 input, and unpadded base64url output."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Invalid signature"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Confirm that you signed the complete URL without ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signature"]}," and did not alter its parameter order or encoding afterward."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Expired link"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Generate the timestamp at redirect time and confirm that your server clock is synchronized."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Reused link"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Generate a fresh nonce and a new signature for every redirect attempt."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Unknown marketplace"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Confirm that the URL path uses the exact lowercase ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["slug"]}," provisioned by xMoney."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Missing merchant"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Include a non-empty ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantId"]}," that is no longer than 191 characters."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When requesting support, share the assigned ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["slug"]},", environment, your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantId"]},", and the approximate UTC time of the failure. Do not send your signing or polling secrets."]}]},"headings":[{"value":"Submerchant onboarding","id":"submerchant-onboarding","depth":1},{"value":"How the flow works","id":"how-the-flow-works","depth":2},{"value":"Before you start","id":"before-you-start","depth":2},{"value":"Create a signed onboarding URL","id":"create-a-signed-onboarding-url","depth":2},{"value":"URL parameters","id":"url-parameters","depth":3},{"value":"Sign the exact URL","id":"sign-the-exact-url","depth":3},{"value":"Signing examples","id":"signing-examples","depth":2},{"value":"Redirect the submerchant","id":"redirect-the-submerchant","depth":2},{"value":"What the submerchant completes","id":"what-the-submerchant-completes","depth":2},{"value":"Poll onboarding status","id":"poll-onboarding-status","depth":2},{"value":"Response fields","id":"response-fields","depth":3},{"value":"Status values","id":"status-values","depth":3},{"value":"Authentication and IP restrictions","id":"authentication-and-ip-restrictions","depth":3},{"value":"Security checklist","id":"security-checklist","depth":2},{"value":"Troubleshooting signed redirects","id":"troubleshooting-signed-redirects","depth":2}],"frontmatter":{"seo":{"title":"Submerchant onboarding for marketplaces | xMoney Documentation","description":"Redirect submerchants from your marketplace to the hosted xMoney onboarding flow and track their onboarding status."}},"lastModified":"2026-09-08T07:07:40.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/marketplaces/submerchant-onboarding","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}