Webhooks são notificações sobre eventos que ocorrem no sistema. Quando ocorre um evento específico, a Xsolla envia uma solicitação HTTP na qual os dados do evento são transmitidos para seu aplicativo. Isso geralmente é uma solicitação POST no formato JSON.
Exemplos de eventos:
Quando um evento definido acontece, a Xsolla notifica o seu sistema sobre o pagamento através de um webhook. Como resultado, você pode executar ações como:
Exemplo de um fluxo de trabalho de webhook de processamento de pagamentos:
Observação
Dependendo da solução utilizada e do tipo de integração, o conjunto de webhooks e a sequência de interações podem ser diferentes do exemplo fornecido.
Guia de vídeo para integração de webhooks da Xsolla:
Configurações de webhooks ao trabalhar com produtos e soluções Xsolla:
Produto/Solução | Obrigatório/Opcional | Para que servem os webhooks |
---|---|---|
Pagamentos | Obrigatório |
|
In-Game Store | Obrigatório |
|
Game Sales | Opcional | Para vender chaves de jogo, a validação do usuário e o ato de creditar itens não são necessários. Você pode conectar webhooks se quiser receber informações sobre eventos, como pagamento ou cancelamento de pedido. Se você conectar webhooks, é importante processar todos os webhooks necessários acionados. |
Subscriptions | Opcional | Recebendo informações sobre criação, atualização ou cancelamento de uma assinatura. Como alternativa, você pode solicitar informações por meio da API. |
Web Shop | Obrigatório |
|
Digital Distribution Hub | Obrigatório |
Consulte a documentação para obter informações detalhadas sobre como configurar webhooks para o Digital Distribution Hub. |
Login | Opcional |
Recebendo informações do evento:
Consulte a documentação de Login para obter informações detalhadas sobre como configurar webhooks. |
Se você usa produtos e soluções que exijam trabalhar com webhooks, habilite e teste os webhooks em sua Conta de Distribuidor e configure o processamento deles. Quando ocorrem eventos específicos, os webhooks são enviados sequencialmente. Portanto, se você não processar um dos webhooks, os webhooks subsequentes não serão enviados. A lista de webhooks necessários é apresentada abaixo.
2 opções de envio de webhook foram configuradas no lado da Xsolla ao comprar e devolver itens no site — informações com dados de pagamento e transação, e informações sobre itens comprados, podem vir separadamente ou podem ser combinadas em um webhook.
Recebimento de informações em webhooks combinados:
Se você se registrou na Conta de
Distribuidor após 22 de janeiro de 2025, você receberá todas as informações
nos webhooks Pagamento
bem-sucedido do pedido (order_paid
) e Cancelamento do pedido (order_canceled
). Nesse caso, você
não precisa processar os webhooks Pagamento (payment
) e Reembolso (refund
).
Recebimento de informações em webhooks separados:
Se você se registrou na Conta de Distribuidor até 22 de janeiro de 2025, você receberá os seguintes webhooks:
payment
) e Reembolso (refund
) com informações
sobre dados de pagamento e detalhes da transação.order_paid
) e Cancelamento do pedido (order_canceled
) com
informações sobre os itens comprados.Você precisa processar todos os webhooks de entrada. Para alternar para a nova opção com o recebimento de webhooks combinados, entre em contato com seus Gerentes de Sucesso do Cliente ou envie um e-mail para csm@xsolla.com.
Para o pleno funcionamento gerenciamento da loja do jogo e de pagamentos, é necessário implementar o processamento dos principais webhooks.
Se você receber webhooks combinados:
Nome e tipo do webhook | Descrição |
---|---|
Validação de usuário > Validação de usuário (user_validation ) |
É enviado em diferentes estágios do processo de pagamento para garantir que o usuário esteja registrado no jogo. |
Serviços de jogo > Webhooks combinados > Pagamento bem-sucedido do pedido (order_paid ) |
Ele contém dados de pagamento, detalhes da transação e informações sobre itens comprados. Use os dados do webhook para adicionar itens ao usuário. |
Serviços de jogo > Webhooks combinados > Cancelamento de pedidos (order_canceled ) |
Ele contém dados do pagamento cancelado, detalhes da transação e informações sobre itens comprados. Use os dados do webhook para remover os itens comprados. |
Se você receber webhooks separados:
Nome e tipo do webhook | Descrição |
---|---|
Validação de usuário > Validação de usuário (user_validation ) |
É enviado em diferentes estágios do processo de pagamento para garantir que o usuário esteja registrado no jogo. |
Pagamentos > Pagamento (payment ) |
Ele contém dados de pagamento e detalhes da transação. |
Serviços de jogo > Webhooks separados > Pagamento bem-sucedido do pedido (order_paid ) |
Ele contém informações sobre itens comprados. Use os dados do webhook para adicionar itens ao usuário. |
Pagamentos > Reembolso (refund ) |
Ele contém dados de pagamento e detalhes da transação. |
Serviços de jogo > Webhooks separados > Cancelamento de pedidos (order_canceled ) |
Ele contém informações sobre os itens comprados e o ID da transação cancelada. Use os dados do webhook para remover os itens comprados. |
Se a personalização do catálogo de itens for implementada no lado do aplicativo, configure o processamento do webhook Personalização de catálogo do lado do parceiro.
Observação
Para receber pagamentos reais, você só precisa assinar o Contrato de Licenciamento e implementar o processamento dos webhooks:
Para gerenciar automaticamente os planos de assinatura, é necessário implementar o processamento dos principais webhooks:
user_validation
) — é enviado em diferentes estágios do processo de pagamento
para garantir que o usuário esteja registrado no jogo.payment
) — é enviado
quando um pedido é pago e contém dados de pagamento e detalhes da transação.create_subscription
) — é enviado quando um webhook Pagamento foi processado com êxito ou o
usuário comprou uma assinatura com um período de avaliação. Ele contém os dados
da assinatura comprada e os do usuário. Use os dados do webhook para adicionar
uma assinatura ao usuário.update_subscription
) — é enviado quando uma assinatura é renovada ou
alterada, quando um webhook Pagamento
foi processado com êxito. Ele contém os dados da assinatura comprada e os dados
do usuário. Use os dados do webhook para estender a assinatura do usuário ou
alterar os parâmetros de assinatura.refund
) — é enviado
quando um pedido é cancelado e contém os dados de pagamento cancelados e
detalhes da transação.cancel_subscription
) — é enviadao quando um webhook Reembolso foi processado com êxito ou a
assinatura foi cancelada por outro motivo. Ele contém informações sobre a
assinatura e os dados do usuário. Use os dados do webhook para deduzir
assinaturas compradas do usuário.Para habilitar o recebimento de webhooks:
https://example.com
. Você também pode
especificar o URL encontrado em uma ferramenta para testar webhooks.Atenção
O protocolo HTTPS é usado para transferir dados; o protocolo HTTP não é suportado.
Observação
Para testar webhooks, você pode selecionar qualquer site dedicado, como webhook.site, ou uma plataforma, como ngrok.
Observação
Não é possível enviar webhooks simultaneamente para URLs diferentes. O que você pode fazer na Conta de Distribuidor é especificar um URL para teste primeiro e, em seguida, substituí-lo pelo real.
Para desativar o recebimento de webhooks:
As configurações avançadas são disponibilizadas para os webhooks na seção Pagamentos e Loja. Eles aparecerão automaticamente no bloco Configurações gerais depois que você clicar no botão Obter webhooks.
Observação
Se as configurações avançadas não forem exibidas, verifique se a recepção do webhook está conectada nas configurações gerais e se você está na aba Teste > Pagamentos e Loja.
Nesta seção, você pode configurar o recebimento de informações adicionais em webhooks. Para fazer isso, coloque os interruptores correspondentes na posição ativa. A linha de cada permissão indica os webhooks que serão afetados pela alteração das configurações.
Opção | Descrição |
---|---|
Exibir informações sobre a conta de pagamento salva | As informações sobre a forma de pagamento salva são passadas no objeto personalizado payment_account . |
Exibir informações sobre transações pelos métodos de pagamento salvos | As informações são passadas nos seguintes parâmetros personalizados do webhook:
|
Adicionar objeto de ordem ao webhook | As informações sobre o pedido são passadas no objeto order do webhook Pagamento. |
Enviar apenas os parâmetros de usuário necessários sem dados confidenciais | Somente as seguintes informações sobre o usuário são passadas no webhook:
|
Enviar parâmetros personalizados | As informações sobre os parâmetros de token personalizados são passadas no webhook. |
Exibir BIN e sufixo do cartão | As seguintes informações sobre o número do cartão bancário são passadas no webhook:
|
Exibir marca do cartão | A bandeira do cartão utilizado para efetuar o pagamento. Por exemplo, Mastercard ou Visa. |
Testar webhooks ajuda a garantir a configuração correta do projeto tanto do seu lado quanto do lado da Xsolla.
Se os webhooks forem configurados com êxito, uma seção de teste de webhooks será exibida abaixo da seção de configuração de webhooks.
A seção de testes na Conta de Distribuidor varia de acordo com a opção de recebimento do webhook.
Se você receber webhooks combinados:
Nome da aba para testar webhooks | Nome e tipo do webhook |
---|---|
Pagamentos e Loja | Validação de usuário > Validação de usuário (user_validation ) |
Serviços de jogo > Webhooks combinados > Pagamento bem-sucedido do pedido (order_paid ) |
|
Serviços de jogo > Webhooks combinados > Cancelamento de pedidos (order_canceled ) |
|
Assinaturas | Validação de usuário > Validação de usuário (user_validation ) |
Pagamentos > Pagamento (payment ) |
Se você receber webhooks separados:
Nome da aba para testar webhooks | Nome e tipo do webhook |
---|---|
Loja | Serviços de jogo > Webhooks separados > Pagamento bem-sucedido do pedido (order_paid ) |
Serviços de jogo > Webhooks separados > Cancelamento de pedidos (order_canceled ) |
|
Pagamentos | Validação de usuário > Validação de usuário (user_validation ) |
Pagamentos > Pagamento (payment ) |
|
Assinaturas | Validação de usuário > Validação de usuário (user_validation ) |
Pagamentos > Pagamento (payment ) |
Observação
Se um aviso de que o teste não passou aparecer na seção de testes, verifique as configurações de resposta do webhook no ouvinte do webhook. As razões para os erros no teste são indicadas nos resultados do teste.
Exemplo:
Você usa o site especializado webhook.site para teste.
Um erro é exibido na seção Teste de respostas a assinaturas inválidas.
Isso acontece porque a Xsolla envia um webhook com uma assinatura incorreta e espera que seu manipulador responda com um código HTTP 4xx
especificando o código de erro INVALID_SIGNATURE
.
webhook.site envia um código HTTP 200
em resposta a todos os webhooks, incluindo um webhook com uma assinatura incorreta. O código HTTP 4xx
esperado não pode ser obtido e, portanto, um erro é exibido no resultado do teste.
O processo de teste para o cenário com webhooks combinados é descrito abaixo.
Na aba Pagamentos e Loja, você pode testar os seguintes webhooks:
user_validation
)order_paid
)order_canceled
)Para testar:
Na seção de teste de webhooks, vá para a aba Pagamentos e Loja.
No menu suspenso, selecione o tipo de item. Se o item do tipo selecionado não estiver configurado na Conta de Distribuidor, clique em:
Preencha os campos necessários:
Clique em Testar webhooks.
Os webhooks Validação do usuário, Pagamento bem-sucedido do pedido e Cancelamento do pedido com os dados especificados são enviados para o URL fornecido. Os resultados do teste de cada tipo de webhook são exibidos abaixo do botão Testar webhooks.
Se o ID de usuário público estiver ativado em seu projeto, você também verá os resultados de uma verificação de pesquisa de usuário.
Para cada webhook, você precisa configurar o processamento de ambos os cenários: um bem-sucedido e outro com um erro.
Na aba Subscriptions, você pode testar os seguintes webhooks:
user_validation
)payment
)Observação
Na Conta de Distribuidor, você só pode testar webhooks básicos de Validação de Usuário e Pagamento. Para testar outros tipos de webhook, vá para:
Observação
Para testar webhooks, você deve ter pelo menos um plano de assinatura criado na seção Conta de Distribuidor > Assinaturas > Planos de Assinatura.
Para testar:
0
.No URL especificado, você receberá webhooks com dados preenchidos. Os resultados do teste de cada webhook, tanto para um cenário bem-sucedido quanto para um cenário com um erro, são exibidos no botão Testar webhooks.
Ouvinte webhook é o código de programa que permite receber webhooks acionados em um endereço URL especificado, gerando uma assinatura e enviando uma resposta para o servidor webhook Xsolla.
Observação
Você pode usar a biblioteca Pay Station PHP SDK, que contém classes prontas para processar webhooks.
No lado do aplicativo, implemente o recebimento de webhooks dos seguintes endereços IP:
185.30.20.0/24
185.30.21.0/24
185.30.22.0/24
185.30.23.0/24
34.102.38.178
34.94.43.207
35.236.73.234
34.94.69.44
34.102.22.197
Se você integrou o produto Login, adicione também o processamento de webhooks dos seguintes endereços IP:
34.94.0.85
34.94.14.95
34.94.25.33
34.94.115.185
34.94.154.26
34.94.173.132
34.102.48.30
35.235.99.248
35.236.32.131
35.236.35.100
35.236.117.164
Limitações:
Para garantir a transmissão segura de dados, você deve verificar se o webhook
foi realmente enviado do servidor Xsolla e se não foi adulterado durante a
transmissão. Para fazer isso, gere sua própria assinatura com base no conteúdo
do corpo da solicitação e compare-a com a assinatura fornecida no cabeçalho
authorization
da solicitação de entrada. Se as assinaturas corresponderem, o
webhook é autêntico e seguro de processar.
Etapas de verificação:
Recupere a assinatura do cabeçalho authorization
da solicitação de webhook de
entrada. O formato do cabeçalho é Signature <signature_value>
.
Recupere o corpo da solicitação do webhook no formato JSON.
Aviso
Use o conteúdo JSON exatamente como foi recebido. Não analise nem recodifique a carga, pois isso alterará a formatação e fará com que a verificação da assinatura falhe.
Gere sua própria assinatura para comparação:
Compare sua assinatura gerada com a authorization
do cabeçalho. Se elas
corresponderem, o webhook é autêntico.
Abaixo, você pode encontrar exemplos de implementação de geração de assinatura para as seguintes linguagens: C#, C++, Go, PHP e Node.js.
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"
}
}'
using System;
using System.Security.Cryptography;
using System.Text;
public static class XsollaWebhookSignature
{
public static string ComputeSha1(string jsonBody, string secretKey)
{
// Concatenation of the JSON from the request body and the project's secret key
string dataToSign = jsonBody + secretKey;
using var sha1 = SHA1.Create();
byte[] hashBytes = sha1.ComputeHash(Encoding.UTF8.GetBytes(dataToSign));
return Convert.ToHexString(hashBytes).ToLower();
}
public static bool VerifySignature(string jsonBody, string secretKey, string receivedSignature)
{
string computedSignature = ComputeSha1(jsonBody, secretKey);
return string.Equals(computedSignature, receivedSignature, StringComparison.OrdinalIgnoreCase);
}
}
#include <string>
#include <sstream>
#include <iomanip>
#include <openssl/sha.h>
class XsollaWebhookSignature {
public:
static std::string computeSha1(const std::string& jsonBody, const std::string& secretKey) {
// Concatenation of the JSON from the request body and the project's secret key
std::string dataToSign = jsonBody + secretKey;
unsigned char digest[SHA_DIGEST_LENGTH];
// Create SHA1 hash
SHA1(reinterpret_cast<const unsigned char*>(dataToSign.c_str()),
dataToSign.length(), digest);
// Convert to lowercase hexadecimal string
std::ostringstream hexStream;
hexStream << std::hex << std::setfill('0');
for (int i = 0; i < SHA_DIGEST_LENGTH; ++i) {
hexStream << std::setw(2) << static_cast<unsigned int>(digest[i]);
}
return hexStream.str();
}
static bool verifySignature(const std::string& jsonBody, const std::string& secretKey, const std::string& receivedSignature) {
std::string computedSignature = computeSha1(jsonBody, secretKey);
// Timing-safe comparison
if (computedSignature.length() != receivedSignature.length()) {
return false;
}
volatile unsigned char result = 0;
for (size_t i = 0; i < computedSignature.length(); ++i) {
result |= (computedSignature[i] ^ receivedSignature[i]);
}
return result == 0;
}
};
package main
import (
"crypto/sha1"
"crypto/subtle"
"encoding/hex"
"strings"
)
type XsollaWebhookSignature struct{}
func (x *XsollaWebhookSignature) ComputeSha1(jsonBody, secretKey string) string {
// Concatenation of the JSON from the request body and the project's secret key
dataToSign := jsonBody + secretKey
// Create SHA1 hash
h := sha1.New()
h.Write([]byte(dataToSign))
signature := h.Sum(nil)
// Convert to lowercase hexadecimal string
return strings.ToLower(hex.EncodeToString(signature))
}
func (x *XsollaWebhookSignature) VerifySignature(jsonBody, secretKey, receivedSignature string) bool {
computedSignature := x.ComputeSha1(jsonBody, secretKey)
receivedSignatureLower := strings.ToLower(receivedSignature)
// Use constant time comparison to prevent timing attacks
return subtle.ConstantTimeCompare([]byte(computedSignature), []byte(receivedSignatureLower)) == 1
}
<?php
class XsollaWebhookSignature
{
/**
* Compute SHA1 signature from webhook JSON body and secret key
*
* @param string $jsonBody The raw JSON body from webhook
* @param string $secretKey The project's secret key
* @return string The lowercase SHA1 signature
*/
public static function computeSha1(string $jsonBody, string $secretKey): string
{
// Concatenation of the JSON from the request body and the project's secret key
$dataToSign = $jsonBody . $secretKey;
// Generate SHA1 signature
$signature = sha1($dataToSign);
return strtolower($signature);
}
/**
* Verify webhook signature using timing-safe comparison
*
* @param string $jsonBody The raw JSON body from webhook
* @param string $secretKey The project's secret key
* @param string $receivedSignature The signature from authorization header
* @return bool True if signature is valid, false otherwise
*/
public static function verifySignature(string $jsonBody, string $secretKey, string $receivedSignature): bool
{
$computedSignature = self::computeSha1($jsonBody, $secretKey);
// Use hash_equals for timing-safe comparison
return hash_equals($computedSignature, strtolower($receivedSignature));
}
}
?>
const crypto = require('crypto');
class XsollaWebhookSignature {
// IMPORTANT: jsonBody must be the raw JSON string exactly as received from Xsolla
static computeSha1(jsonBody, secretKey) {
// Concatenation of the JSON from the request body and the project's secret key
const dataToSign = jsonBody + secretKey;
// Create SHA1 hash
const hash = crypto.createHash('sha1');
hash.update(dataToSign, 'utf8');
// Convert to lowercase hexadecimal string
return hash.digest('hex').toLowerCase();
}
static verifySignature(jsonBody, secretKey, receivedSignature) {
const computedSignature = this.computeSha1(jsonBody, secretKey);
const cleanReceivedSignature = receivedSignature.toLowerCase();
// Check if signatures have the same length before using timingSafeEqual
if (computedSignature.length !== cleanReceivedSignature.length) {
return false;
}
try {
return crypto.timingSafeEqual(
Buffer.from(computedSignature, 'hex'),
Buffer.from(cleanReceivedSignature, 'hex')
);
} catch (error) {
// Return false if there's any error (e.g., invalid hex characters)
return false;
}
}
}
Para confirmar o recebimento do webhook, o servidor deve retornar:
200
, 201
ou 204
em caso de resposta bem-sucedida.400
com uma descrição do problema se o
usuário especificado não for encontrado ou uma assinatura inválida for passada.
Seu manipulador de webhooks também pode retornar um código HTTP 5xx
em caso
de problemas temporários em seu servidor.Se o servidor Xsolla não recebeu uma resposta aos webhooks Pagamento bem-sucedido do
pedido e Cancelamento do
pedido, ou recebeu uma resposta com um código 5xx
, os webhooks serão
reenviados de acordo com o seguinte agendamento:
No máximo são feitas 20 tentativas de enviar webhooks dentro de 12 horas a partir da primeira tentativa.
Se o servidor Xsolla não recebeu uma resposta ao webhook Pagamento ou ao webhook Reembolso, ou recebeu uma resposta com um
código 5xx
, os webhooks também serão reenviados com um intervalo de tempo
maior. Um máximo de 12 tentativas são feitas dentro de 12 horas.
Observação
Se o reembolso do pagamento foi iniciado pela Xsolla e uma resposta com um código HTTP '5xx' veio em resposta ao webhook Reembolso, o pagamento ainda será reembolsado.
Se o servidor Xsolla não recebeu uma resposta ao webhook Validação de usuário ou recebeu
uma resposta com um código de 400
ou 5xx
, o webhook Validação de usuário não será
reenviado. Nesse caso, o usuário vê um erro e os webhooks Pagamento e Pagamento bem-sucedido do pedido não são
enviados.
Códigos de erro para o código HTTP 400:
Código | Mensagem |
---|---|
INVALID_USER | Usuário inválido |
INVALID_PARAMETER | Parâmetro inválido |
INVALID_SIGNATURE | Assinatura inválida |
INCORRECT_AMOUNT | Quantia incorreta |
INCORRECT_INVOICE | Invoice incorreto |
HTTP/1.1 400 Bad Request
{
"error":{
"code":"INVALID_USER",
"message":"Invalid user"
}
}
Observação
O tipo de notificação é enviado no parâmetro notification_type
.
Webhook | Tipo de notificação | Descrição |
---|---|---|
Validação de usuário | user_validation |
Enviado para verificar se um usuário existe no jogo. |
Pesquisa de usuário | user_search |
Enviado para obter as informações do usuário com base no ID de usuário público. |
Pagamento | payment |
Enviado quando um usuário conclui um pagamento. |
Reembolso | refund |
Enviado quando um pagamento precisa ser cancelado por qualquer motivo. |
Reembolso parcial | partial_refund |
Enviado quando um pagamento deve ser parcialmente cancelado por qualquer motivo. |
Transação rejeitada pelo AFS | afs_reject |
Enviado quando uma transação é recusada durante uma verificação AFS. |
Lista de bloqueios atualizada do AFS | afs_black_list |
Enviado quando a lista de bloqueio do AFS é atualizada. |
Assinatura criada | create_subscription |
Enviado quando um usuário cria uma assinatura. |
Assinatura atualizada | update_subscription |
Enviado quando uma assinatura é renovada ou alterada. |
Assinatura cancelada | cancel_subscription |
Enviado quando uma assinatura é cancelada. |
Assinatura não renovável | non_renewal_subscription |
Enviado quando o status é definido como não renovável. |
Adicionar conta de pagamento | payment_account_add |
Enviado quando um usuário adiciona ou salva uma conta de pagamento. |
Remover conta de pagamento | payment_account_remove |
Enviado quando um usuário remove a conta de pagamento das contas salvas. |
Validação de usuário na Web Shop | - |
Enviado de um site Web Shop para verificar se um usuário existe no jogo. |
Personalização de catálogo no lado do parceiro | partner_side_catalog |
Enviado quando um usuário interage com a loja. |
Pagamento bem-sucedido do pedido | order_paid |
Enviado quando um pedido é pago. |
Cancelamento do pedido | order_canceled |
Enviado quando um pedido é cancelado. |
Disputa | dispute |
Enviado quando uma nova disputa é aberta. |