Webhooks

Overview

Webhooks allow you to receive notifications of events that happen to your Xsolla transactions. Use webhooks to automate back-end and supplementary functions, such as providing status and other transaction-related information.

We use webhooks for payments, including purchases of virtual currency, items, games, physical goods and so on.

In most cases, webhooks are triggered by user actions on your website. But they can come from other actions, too. For example, a back-end process on your website may invoke an API method to refund a payment, or the payment system may send a notification about a disputed charge.

You must write or use a so-called listener, or handler, to receive and process webhooks. This is a program that waits for a webhook and usually passes it to an internal workflow of yours, which responds appropriately.

For example, you can do the following after receiving a webhook:

  • Filling up a user’s balance
  • Unlocking new item for a user
  • Delivering physical goods to a user

Listen to webhooks at the following IP addresses: 185.30.20.0/24, 185.30.21.0/24.

Notice: Your database must NOT contain two successful transactions with the same ID. If your listener receives a webhook with an existing transaction ID, it must return the latest result for that transaction. Avoid charging the user twice or creating duplicate records in your database.

We cannot guarantee that your listener will receive all the webhooks we send. As internet connection is not 100% reliable, webhooks may fail to come on time or at all. Moreover, your listener may return a 5xx HTTP code for a temporary error on your server. For example, your listener returns a 500 HTTP response code in case a virtual item that a user purchased successfully was not added to the user's inventory.

To address these issues, we provide a retry mechanism that resends failed messages at various intervals until your listener receives them. A repeated webhook may be sent within 12 hours after the previous one. The maximum number of retries is 12.

Note: Although connection problems may indeed result in lost, delayed, or duplicate webhooks, the most common cause is faulty logic on the listener side.

Response Codes

Xsolla API accepts conventional HTTP response codes for successful and failed requests. Code 204 indicates successful processing. Return code 400 in case of an error in the provided information (e.g., a required parameter missing, a failed recharge, etc.). Use code 500 for temporary errors with your servers.

Sign Requests

Digital signatures enable secure data transmission. To generate the signature, (1) concatenate the request's JSON body with your project's secret key and (2) apply SHA-1 hashing to the resulting string.

Make sure that the created signature matches the one passed in the HTTP header.

Copy
Full screen
http
  • http
  • curl
Request
POST /your_uri HTTP/1.1
Host: your.host
Accept: application/json
Content-Type: application/json
Content-Length: 165
Authorization: Signature 52eac2713985e212351610d008e7e14fae46f902

{
  "notification_type":"user_validation",
  "user":
    {
      "ip":"127.0.0.1",
      "phone":"18777976552",
      "email":"email@example.com",
      "id":1234567,
      "name":"Xsolla User",
      "country":"US"
    }
}
$curl -v 'https://your.hostname/your/uri' \
-X POST \
-H 'Authorization: Signature 52eac2713985e212351610d008e7e14fae46f902' \
-d '{
  "notification_type":
    "user_validation",
    "user":
      {
        "ip":"127.0.0.1",
        "phone":"18777976552",
        "email":"email@example.com",
        "id":1234567,
        "name":"Xsolla User",
        "country":"US"
      }
    }'
Response

Webhooks List

The type of notification is sent in the notification_type parameter.

Notification TypeDescription
order_paidNotification about getting the cart’s content when making a purchase.
order_canceledNotification about payment cancellation.

Getting Cart’s Content When Making Purchase

When the user confirms the cart’s content when making a purchase, Xsolla sends the order_paid notification to the webhook URL.

ParameterTypeDescription
items
arrayList of items purchased by a user.
items.sku
stringItem’s unique ID. Items with the game_key type use the value in the sku_drm format.
items.type
stringItems type. It can have the following values: virtual_good, virtual_currency, game_key, physical_good.
items.quantity
integerQuantity of items.
items.amount
stringTotal cost of items that considers their quantity. May differ from the item’s price due to changes of currency rates and commission.
items.promotions
objectApplied promotions. If the promotion wasn’t applied, an empty array is written to the parameter.
items.promotions.amount_without_discount
stringTotal cost of items without a discount.
items.promotions.amount_with_discount
stringTotal cost of items with a discount.
items.promotions.sequence
integerID of the applied promotion.
notification_type
stringNotification type. Required.
order
objectPayment information.
order.id
integerTransaction ID.
order.mode
stringPayment type. It can have the following values: default or sandbox.
order.currency_type
stringPayment type. It can have the following values: real for real currency or virtual for virtual currency.
order.currency
stringCurrency of order. Virtual currency uses the SKU and real currency uses a three-letter code per ISO 4217.
order.amount
stringThe total cost of a cart that considers a chosen currency.
order.status
stringOrder status.
order.platform
stringPayment platform. The xsolla value is used for payments via Xsolla. Other payments use the value that corresponds with the name of the integrated payment system.
order.comment
stringUser’s commentary to the order.
order.invoice_id
stringReal currency payments invoice ID. Virtual currency payments use the null value.
order.promotions
stringApplied promotions. If the promotion wasn't applied, an empty array is written to the parameter.
order.promotions.amount_without_discount
stringOrder total cost without a discount.
order.promotions.amount_with_discount
stringOrder total cost with a discount.
order.promotions.sequence
stringID of the applied promotion.
user
objectUser information.
user.external_id
stringUser ID.
user.email
stringUser email address.
custom_parameters
objectAdditional information.
Copy
Full screen
http
  • http
  • curl
Request
POST /your/uri HTTP/1.1
Host: your.hostname
Accept: application/json
Content-Type: application/json
Content-Length: 240
Authorization: Signature 13342703ccaca5064ad33ba451d800c5e823db8f

{
  "items": [
    {
      "sku": "virtual-good-item-sku",
      "type": "virtual_good",
      "quantity": 3,
      "amount": "100",
      "promotions": [
        {
          "amount_without_discount": "200",
          "amount_with_discount": "100",
          "sequence": 1
        }
      ]
    },
    {
      "sku": "game_sku_steam",
      "type": "game_key",
      "quantity": 1,
      "amount": "200",
      "promotions": []
    },
    {
      "sku": "gold",
      "type": "virtual_currency",
      "quantity": 1500,
      "amount": "100",
      "promotions": []
    }
  ],
  "notification_type": "order_paid",
  "order": {
    "id": 42,
    "mode": "default",
    "currency_type": "real",
    "currency": "USD",
    "amount": "200",
    "status": "paid",
    "platform": "xsolla",
    "comment": null,
    "invoice_id": "23444",
    "promotions": [
      {
        "amount_without_discount": "400",
        "amount_with_discount": "200",
        "sequence": 1
      }
    ]
  },
  "user": {
    "external_id": "gamer_external_id",
    "email": "gamer@email.com"
  }
}
$ curl -v 'https://your.hostname/your/uri' \
-X POST \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Authorization: Signature 13342703ccaca5064ad33ba451d800c5e823db8f' \
-d '{
  "items": [
    {
      "sku": "virtual-good-item-sku",
      "type": "virtual_good",
      "quantity": 3,
      "amount": "100",
      "promotions": [
        {
          "amount_without_discount": "200",
          "amount_with_discount": "100",
          "sequence": 1
        }
      ]
    },
    {
      "sku": "game_sku_steam",
      "type": "game_key",
      "quantity": 1,
      "amount": "200",
      "promotions": []
    },
    {
      "sku": "gold",
      "type": "virtual_currency",
      "quantity": 1500,
      "amount": "100",
      "promotions": []
    }
  ],
  "notification_type": "order_paid",
  "order": {
    "id": 42,
    "mode": "default",
    "currency_type": "real",
    "currency": "USD",
    "amount": "200",
    "status": "paid",
    "platform": "xsolla",
    "comment": null,
    "invoice_id": "23444",
    "promotions": [
      {
        "amount_without_discount": "400",
        "amount_with_discount": "200",
        "sequence": 1
      }
    ]
  },
  "user": {
    "external_id": "gamer_external_id",
    "email": "gamer@email.com"
  }
}'
Response
HTTP/1.1 204 No Content

Payment Cancellation

When the user cancels the payment, Xsolla sends the order_canceled notification to the webhook URL.

ParameterTypeDescription
items
arrayList of items purchased by a user.
items.sku
stringItem’s unique ID. Items with the game_key type use the value in the sku_drm format.
items.type
stringItems type. It can have the following values: virtual_good, virtual_currency, game_key, physical_good.
items.quantity
integerQuantity of items.
items.amount
stringTotal cost of items that considers their quantity. May differ from the items price due to changes of currency rates and commission.
items.promotions
objectApplied promotions. If the promotion wasnt applied, an empty array is written to the parameter.
items.promotions.amount_without_discount
stringTotal cost of items without a discount.
items.promotions.amount_with_discount
stringTotal cost of items with a discount.
items.promotions.sequence
integerID of the applied promotion.
notification_type
stringNotification type. Required.
order
objectPayment information.
order.id
integerTransaction ID.
order.mode
stringPayment type. It can have the following values: default or sandbox.
order.currency_type
stringPayment type. It can have the following values: real for real currency or virtual for virtual currency.
order.currency
stringCurrency of order. Virtual currency uses the SKU and real currency uses a three-letter code per ISO 4217.
order.amount
stringThe total cost of a cart that considers a chosen currency.
order.status
stringOrder status.
order.platform
stringPayment platform. The xsolla value is used for payments via Xsolla. Other payments use the value that corresponds with the name of the integrated payment system.
order.comment
stringUsers commentary to the order.
order.invoice_id
stringReal currency payments invoice ID. Virtual currency payments use the null value.
order.promotions
stringApplied promotions. If the promotion wasnt applied, an empty array is written to the parameter.
order.promotions.amount_without_discount
stringOrder total cost without a discount.
order.promotions.amount_with_discount
stringOrder total cost with a discount.
order.promotions.sequence
stringID of the applied promotion.
user
objectUser information.
user.external_id
stringUser ID.
user.email
stringUser email address.
custom_parameters
objectAdditional information.
Copy
Full screen
http
  • http
  • curl
Request
POST /your/uri HTTP/1.1
Host: your.hostname
Accept: application/json
Content-Type: application/json
Content-Length: 240
Authorization: Signature 13342703ccaca5064ad33ba451d800c5e823db8f

{
  "items": [
    {
      "sku": "virtual-good-item-sku",
      "type": "virtual_good",
      "quantity": 3,
      "amount": "100",
      "promotions": [
        {
          "amount_without_discount": "200",
          "amount_with_discount": "100",
          "sequence": 1
        }
      ]
    },
    {
      "sku": "game_sku_steam",
      "type": "game_key",
      "quantity": 1,
      "amount": "200",
      "promotions": []
    },
    {
      "sku": "gold",
      "type": "virtual_currency",
      "quantity": 1500,
      "amount": "100",
      "promotions": []
    }
  ],
  "notification_type": "order_canceled",
  "order": {
    "id": 42,
    "mode": "default",
    "currency_type": "real",
    "currency": "USD",
    "amount": "200",
    "status": "canceled",
    "platform": "xsolla",
    "comment": null,
    "invoice_id": "23444",
    "promotions": [
      {
        "amount_without_discount": "400",
        "amount_with_discount": "200",
        "sequence": 1
      }
    ]
  },
  "user": {
    "external_id": "gamer_external_id",
    "email": "gamer@email.com"
  }
}
$ curl -v 'https://your.hostname/your/uri' \
-X POST \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Authorization: Signature 13342703ccaca5064ad33ba451d800c5e823db8f' \
-d '{
  "items": [
    {
      "sku": "virtual-good-item-sku",
      "type": "virtual_good",
      "quantity": 3,
      "amount": "100",
      "promotions": [
        {
          "amount_without_discount": "200",
          "amount_with_discount": "100",
          "sequence": 1
        }
      ]
    },
    {
      "sku": "game_sku_steam",
      "type": "game_key",
      "quantity": 1,
      "amount": "200",
      "promotions": []
    },
    {
      "sku": "gold",
      "type": "virtual_currency",
      "quantity": 1500,
      "amount": "100",
      "promotions": []
    }
  ],
  "notification_type": "order_canceled",
  "order": {
    "id": 42,
    "mode": "default",
    "currency_type": "real",
    "currency": "USD",
    "amount": "200",
    "status": "canceled",
    "platform": "xsolla",
    "comment": null,
    "invoice_id": "23444",
    "promotions": [
      {
        "amount_without_discount": "400",
        "amount_with_discount": "200",
        "sequence": 1
      }
    ]
  },
  "user": {
    "external_id": "gamer_external_id",
    "email": "gamer@email.com"
  }
}'
Response
HTTP/1.1 204 No Content