public function complete($data = array(), $isNotification = false)
    {
        $flags = $isNotification ? ServiceResponse::SERVICE_NOTIFICATION : 0;
        // The payment is already captured
        if ($this->payment->Status === 'Captured') {
            return $this->generateServiceResponse($flags);
        }

        if ($this->payment->Status !== 'PendingPurchase') {
            throw new InvalidStateException('Cannot complete this payment. Status is not "PendingPurchase"');
        }

        $gateway = $this->oGateway();
        if (!$gateway->supportsCompletePurchase()) {
            throw new InvalidConfigurationException(
                sprintf('The gateway "%s" doesn\'t support completePurchase', $this->payment->Gateway)
            );
        }

        // purchase and completePurchase should use the same data
        $gatewayData = $this->gatherGatewayData($data);

        $this->extend('onBeforeCompletePurchase', $gatewayData);
        $request = $gateway->completePurchase($gatewayData);
        $this->extend('onAfterCompletePurchase', $request);

        $this->createMessage(Message\CompletePurchaseRequest::class, $request);
        $response = null;
        try {
            $response = $this->response = $request->send();
        } catch (\Omnipay\Common\Exception\OmnipayException $e) {
            $this->createMessage(Message\CompletePurchaseError::class, $e);
            return $this->generateServiceResponse($flags | ServiceResponse::SERVICE_ERROR);
        }

        $serviceResponse = $this->wrapOmnipayResponse($response, $isNotification);
        if ($serviceResponse->isError()) {
            $this->createMessage(Message\CompletePurchaseError::class, $response);
            return $serviceResponse;
        }

        // only update payment status if we're not waiting for a notification
        if (!$serviceResponse->isAwaitingNotification()) {
            $this->markCompleted('Captured', $serviceResponse, $response);
        } else {
            ErrorHandling::safeExtend($this->payment, 'onAwaitingCaptured', $serviceResponse);
        }


        return $serviceResponse;
    }