Set up webhooks

Note
To work with the webhook server, you only need one callback function.

Using a pre-created class

Copy
Full screen
Small screen
<?php

use Xsolla\SDK\Webhook\WebhookServer;
use Xsolla\SDK\Webhook\Message\Message;
use Xsolla\SDK\Exception\Webhook\XsollaWebhookException;

$callback = function (Message $message) {
    switch ($message->getNotificationType()) {
        case Message::USER_VALIDATION:
            /** @var Xsolla\SDK\Webhook\Message\UserValidationMessage $message */
            // TODO if user not found, you should throw Xsolla\SDK\Exception\Webhook\InvalidUserException
            break;
        case Message::PAYMENT:
            /** @var Xsolla\SDK\Webhook\Message\PaymentMessage $message */
            // TODO if the payment delivery fails for some reason, you should throw Xsolla\SDK\Exception\Webhook\XsollaWebhookException
            break;
        case Message::REFUND:
            /** @var Xsolla\SDK\Webhook\Message\RefundMessage $message */
            // TODO if you cannot handle the refund, you should throw Xsolla\SDK\Exception\Webhook\XsollaWebhookException
            break;
        default:
            throw new XsollaWebhookException('Notification type not implemented');
    }
};

$webhookServer = WebhookServer::create($callback, PROJECT_KEY);
$webhookServer->start();

Creating a new class

Copy
Full screen
Small screen
<?php

use Xsolla\SDK\Webhook\WebhookRequest;
use Xsolla\SDK\Webhook\Message\Message;
use Xsolla\SDK\Webhook\WebhookAuthenticator;
use Xsolla\SDK\Webhook\WebhookResponse;
use Xsolla\SDK\Exception\Webhook\InvalidUserException;
use Xsolla\SDK\Exception\Webhook\XsollaWebhookException;

$httpHeaders = array();//TODO fetch HTTP request headers from $_SERVER or apache_request_headers()
$httpRequestBody = file_get_contents('php://input');
$clientIPv4 = $_SERVER['REMOTE_ADDR'];
$request = new WebhookRequest($httpHeaders, $httpRequestBody, $clientIPv4);
//or $request = WebhookRequest::fromGlobals();

$webhookAuthenticator = new WebhookAuthenticator(PROJECT_KEY);
$webhookAuthenticator->authenticate($request, $authenticateClientIp = true); // throws Xsolla\SDK\Exception\Webhook\XsollaWebhookException

$requestArray = $request->toArray();

$message = Message::fromArray($requestArray);
switch ($message->getNotificationType()) {
    case Message::USER_VALIDATION:
        /** @var Xsolla\SDK\Webhook\Message\UserValidationMessage $message */
        $userArray = $message->getUser();
        $userId = $message->getUserId();
        $messageArray = $message->toArray();
        // TODO if user not found, you should throw Xsolla\SDK\Exception\Webhook\InvalidUserException
// throw new InvalidUserException('User not found');
        break;
    case Message::PAYMENT:
        /** @var Xsolla\SDK\Webhook\Message\PaymentMessage $message */
        $userArray = $message->getUser();
        $paymentArray = $message->getTransaction();
        $paymentId = $message->getPaymentId();
        $externalPaymentId = $message->getExternalPaymentId();
        $paymentDetailsArray = $message->getPaymentDetails();
        $customParametersArray = $message->getCustomParameters();
        $isDryRun = $message->isDryRun();
        $messageArray = $message->toArray();
        // TODO if the payment delivery fails for some reason, you should throw Xsolla\SDK\Exception\Webhook\XsollaWebhookException
        break;
    case Message::REFUND:
        /** @var Xsolla\SDK\Webhook\Message\RefundMessage $message */
        $userArray = $message->getUser();
        $paymentArray = $message->getTransaction();
        $paymentId = $message->getPaymentId();
        $externalPaymentId = $message->getExternalPaymentId();
        $paymentDetailsArray = $message->getPaymentDetails();
        $customParametersArray = $message->getCustomParameters();
        $isDryRun = $message->isDryRun();
        $refundArray = $message->getRefundDetails();
        $messageArray = $message->toArray();
        // TODO if you cannot handle the refund, you should throw Xsolla\SDK\Exception\Webhook\XsollaWebhookException
        break;
    default:
        throw new XsollaWebhookException('Notification type not implemented');
}

Pre-created webhook server classes are available in the library’s repo on GitHub. You can use them as examples when creating your own classes.

See the detailed description of webhooks and their parameters in the API documentation.

It’s recommended that you set up processing of the following webhook types:

  • User validation:

Copy
Full screen
Small screen
<?php

case Message::USER_VALIDATION:
        /** @var Xsolla\SDK\Webhook\Message\UserValidationMessage $message */
        $userArray = $message->getUser();
        $userId = $message->getUserId();
        $messageArray = $message->toArray();
        // TODO if user not found, you should throw Xsolla\SDK\Exception\Webhook\InvalidUserException
        break;

Create a request to your app’s database with the help of the user ID. If a user with this ID exists, call the break method. Otherwise, throw the InvalidUserException exception.

Example:

Copy
Full screen
Small screen
<?php

DEFINE('DB_USER', 'root'); // specify
DEFINE('DB_PASSWORD', 'yourpasswordhere'); // specify
DEFINE('DB_HOST', '127.0.0.1'); // specify
DEFINE('DB_NAME','127.0.0.1'); //specify

$callback = function (Message $message) {
    $dbc = @mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME)
    OR die('Could not connect to MySQL '. mysqli_connect_error());

    switch ($message->getNotificationType()) {
        case Message::USER_VALIDATION:
            $userId = $message->getUserId();
            $query = "SELECT * FROM user_db.users u WHERE userID IN ('{$userId}') ";
            $response = @mysqli_query($dbc, $query);

            if (mysqli_num_rows($response) == 0){
                throw new InvalidUserException('User not found');   
            }
            break;

use Xsolla\SDK\Exception\Webhook\InvalidUserException;
use Xsolla\SDK\Webhook\Message\Message;

DEFINE('DB_USER', 'dbuser'); // specify
DEFINE('DB_PASSWORD', 'dbpassword'); // specify
DEFINE('DB_HOST', '127.0.0.1'); // specify
DEFINE('DB_NAME', 'dbname'); //specify

$callback = function (Message $message) {
    $dbc = @mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
    if (mysqli_connect_errno()) {
        printf("Connect failed: %s\n", mysqli_connect_error());
        exit;
    }

    switch ($message->getNotificationType()) {
        case Message::USER_VALIDATION:
            $userId = mysqli_real_escape_string($dbc, $message->getUserId());

            $query = "SELECT COUNT(user_id) FROM dbname.users WHERE user_id = '{$userId}'";
            $response = @mysqli_query($dbc, $query) or die(mysqli_error($dbc));

            if ((int)mysqli_fetch_row($response)[0] === 0) {
                throw new InvalidUserException('User not found');
            }
            break;
        default:
            break;
    }
};

  • Payment:

Copy
Full screen
Small screen
<?php

case Message::PAYMENT:
        /** @var Xsolla\SDK\Webhook\Message\PaymentMessage $message */
        $userArray = $message->getUser();
        $paymentArray = $message->getTransaction();
        $purchaseArray =$message->getPurchase();
        $paymentId = $message->getPaymentId();
        $externalPaymentId = $message->getExternalPaymentId();
        $paymentDetailsArray = $message->getPaymentDetails();
        $customParametersArray = $message->getCustomParameters();
        $isDryRun = $message->isDryRun();
        $messageArray = $message->toArray();
        // TODO if the payment delivery fails for some reason, you should throw Xsolla\SDK\Exception\Webhook\XsollaWebhookException
        break;

Note
A list of purchased items is passed in the purchaseArray array. Its content options are given in the description of the payment webhook parameters.
Was this article helpful?
Thank you!
Is there anything we can improve? Message
We're sorry to hear that
Please explain why this article wasn't helpful to you. Message
Thank you for your feedback!
We'll review your message and use it to help us improve your experience.