public static function placeOrder($cart = null)
    {
        try {
            if (empty(static::$gatewayKey))
                throw new ShopException('Payment gateway not selected.');
            if (empty($cart)) $cart = Auth::user()->cart;
            $order = $cart->placeOrder();
            $statusCode = $order->statusCode;
            \event(new OrderPlaced($order->id));
            static::$gateway->setCallbacks($order);
            if (static::$gateway->onCharge($order)) {
                $order->statusCode = static::$gateway->getTransactionStatusCode();
                $order->save();
                // 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 {
                $order->statusCode = 'failed';
                $order->save();
            }
        } catch (ShopException $e) {
            static::setException($e);
            if (isset($order)) {
                $order->statusCode = 'failed';
                $order->save();
                // Create failed transaction
                $order->placeTransaction(
                    static::$gatewayKey,
                    uniqid(),
                    static::$exception->getMessage(),
                    $order->statusCode
                );
            }
        } catch (GatewayException $e) {
            static::$exception = $e;
            if (isset($order)) {
                $order->statusCode = 'failed';
                $order->save();
                // Create failed transaction
                $order->placeTransaction(
                    static::$gatewayKey,
                    uniqid(),
                    static::$exception->getMessage(),
                    $order->statusCode
                );
            }
        }
        if ($order) {
            static::checkStatusChange($order, $statusCode);
            return $order;
        } else {
            return;
        }
    }