{"templateId":"openapi_docs","sharedDataIds":{"openAPIDocsStore":"oas-deprecated-webhooks/index.yaml","sidebar":"sidebar-webhooks-deprecated-en.sidebars.yaml"},"props":{"definitionId":"deprecated-webhooks/index.yaml","dynamicMarkdocComponents":[],"baseSlug":"/deprecated-webhooks","seo":{"title":"Webhooks","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"itemId":"","disableAutoScroll":true,"metadata":{"type":"openapi","title":"Webhooks","description":"# Overview\n\nWebhooks allow you to receive instant notifications of configured events that happen on Xsolla’s side. You can use webhooks to automate back-end and supplementary functions of your application.\n\nExamples of events that you can be notified about:\n\n- payments, including purchases of virtual currency and items\n- recurring payments and actions with subscriptions\n- refunds\n\nWhen a configured event occurs, Xsolla notifies your system about it via webhooks. For example, you can do the following after receiving a webhook:\n\n- add to a user’s balance\n- unlock new items for a user\n- start subscription service\n- block user after fraud detection\n\nBelow is an example of how a payment processing webhook works:\n\n![Payment processing webhook](https://cdn.xsolla.net/developers/current/images/api_docs/webhooks-general.svg)\n\n# Set up server side\n\nThe following settings have to be applied for webhooks to work correctly:\n\n- Listen to webhooks at the following IP addresses: `185.30.20.0/24`, `185.30.21.0/24`, `185.30.23.0/24`.\n- Application database must not contain two successful transactions with the same ID.\n\n<div lang=\"en\" class=\"notice\">\n  <p><strong>Notice</strong></p>\n  <p>If your listener receives a webhook with an existing transaction ID, it must return the previous result for that transaction. It is not recommended to charge the user twice or create duplicate records in the database.</p>\n</div>\n\n- A created [signature](https://developers.xsolla.com/webhooks/overview/#section/Sign-requests) has to match the one passed in the HTTP header.\n- In case of an error, return [code 400](https://developers.xsolla.com/webhooks/overview/#section/Errors) (e.g., when a required parameter is missing or a recharge has failed). For temporary errors with your servers, use code 500.\n\n<div lang=\"en\" class=\"note\">\n  <p><strong>Note</strong></p>\n  <p>Xsolla API accepts conventional HTTP response codes for successful and failed requests. Code 204 indicates successful processing.</p>\n</div>\n\nAs internet connections are not always 100% reliable, webhooks may be lost or delayed. To address this issue, Xsolla resends failed webhooks until your listener receives them. Webhook resends are sent within 12 hours after the previous one until your listener confirms receiving. The maximum number of retries is 12.\n\n<div lang=\"en\" class=\"note\">\n  <p><strong>Note</strong></p>\n  <p>Although connection problems may result in lost, delayed, or duplicate webhooks, the most common cause is incorrect logic on the listener side.</p>\n</div>\n\n# Sign requests\n\nDigital signatures enable secure data transmission. To generate a signature:\n\n1. Concatenate the request’s JSON body with your project’s secret key.\n2. Apply SHA-1 hashing to the resulting string.\n\n```\nPOST /your_uri HTTP/1.1\nhost: your.host\naccept: application/json\ncontent-type: application/json\ncontent-length: 165\nauthorization: Signature 52eac2713985e212351610d008e7e14fae46f902\n{\n  \"notification_type\":\"user_validation\",\n  \"user\":{\n      \"ip\":\"127.0.0.1\",\n      \"phone\":\"18777976552\",\n      \"email\":\"email@example.com\",\n      \"id\":1234567,\n      \"name\":\"Xsolla User\",\n      \"country\":\"US\"\n  }\n}\n```\n\n```\ncurl -v 'https://your.hostname/your/uri' \\\n-X POST \\\n-H 'authorization: Signature 52eac2713985e212351610d008e7e14fae46f902' \\\n-d '{\n  \"notification_type\":\n    \"user_validation\",\n    \"user\":\n      {\n        \"ip\": \"127.0.0.1\",\n        \"phone\": \"18777976552\",\n        \"email\": \"email@example.com\",\n        \"id\": 1234567,\n        \"name\": \"Xsolla User\",\n        \"country\": \"US\"\n      }\n    }'\n```\n\n# Errors\n\nError codes for HTTP code 400:\n\n<table>\n  <thead>\n    <tr>\n        <th>Code</th>\n        <th>Message</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n        <td>INVALID_USER</td>\n        <td>Invalid user</td>\n    </tr>\n    <tr>\n        <td>INVALID_PARAMETER</td>\n        <td>Invalid parameter</td>\n    </tr>\n    <tr>\n        <td>INVALID_SIGNATURE</td>\n        <td>Invalid signature</td>\n    </tr>\n    <tr>\n        <td>INCORRECT_AMOUNT</td>\n        <td>Incorrect amount</td>\n    </tr>\n    <tr>\n        <td>INCORRECT_INVOICE</td>\n        <td>Incorrect invoice</td>\n    </tr>\n  </tbody>\n</table>\n\n```\nHTTP/1.1 400 Bad Request\n{\n    \"error\":{\n        \"code\":\"INVALID_USER\",\n        \"message\":\"Invalid user\"\n    }\n}\n```\n"},"compilationErrors":[],"markdown":{"partials":{},"variables":{"rbac":{"teams":["anonymous"]},"user":{},"remoteAddr":{"hostname":"xsolla.redocly.app","port":4000,"ipAddress":"185.30.21.18"},"lang":"en","env":{"PUBLIC_REDOCLY_BRANCH_NAME":"realm"}}},"pagePropGetterError":{"message":"","name":""}},"slug":"/deprecated-webhooks","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}