public static function callback($order, $transaction, $status, $data = null)
    {
        $statusCode = $order->statusCode;
        try {
            if (in_array($status, ['success', 'fail'])) {
                static::$gatewayKey = $transaction->gateway;
                static::$gateway = static::instanceGateway();
                if ($status == 'success') {
                    static::$gateway->onCallbackSuccess($order, $data);
                    $order->statusCode = static::$gateway->getTransactionStatusCode();
                    // Create transaction
                    $order->placeTransaction(
                        static::$gatewayKey,
                        static::$gateway->getTransactionId(),
                        static::$gateway->getTransactionDetail(),
                        static::$gateway->getTransactionToken()
                    );
                    // Fire event
                    if ($order->isCompleted)
                        \event(new OrderCompleted($order->id));
                } else if ($status == 'fail') {
                    static::$gateway->onCallbackFail($order, $data);
                    $order->statusCode = 'failed';
                }
                $order->save();
            }
        } catch (ShopException $e) {
            static::setException($e);
            $order->statusCode = 'failed';
            $order->save();
        } catch (GatewayException $e) {
            static::setException($e);
            $order->statusCode = 'failed';
            $order->save();
        }
        static::checkStatusChange($order, $statusCode);
    }