public CapitaInvokeResponse InvokeRequest(CapitaInvokeRequest request)
        {
            scpSimpleInvokeRequest scpInvokeRequest = CreateCapitaInvokeRequest(request);
            CapitaInvokeResponse   response         = new CapitaInvokeResponse();

            using (scpClient capitaClient = new scpClient("CapitaScpSoap", Shared.Capita.Default.CapitaWebServiceUrl))
            {
                try
                {
                    scpInvokeResponse scpResponse  = capitaClient.scpSimpleInvoke(scpInvokeRequest);
                    string            errorMessage = string.Empty;
                    if (scpResponse?.invokeResult != null)
                    {
                        if (scpResponse.requestId == request.UniqueReference)
                        {
                            if (scpResponse.transactionState == transactionState.INVALID_REFERENCE)
                            {
                                errorMessage = "Transaction aborted! It may be because of session time out or some other technical glitch from Capita";
                            }
                            else
                            {
                                response.ScpReference = scpResponse.scpReference;
                                if (scpResponse.invokeResult.status == status.SUCCESS)
                                {
                                    response.RedirectUrl = (string)scpResponse.invokeResult.Item;
                                }
                                else
                                {
                                    errorDetails item = scpResponse.invokeResult.Item as errorDetails;
                                    errorMessage = item != null ? $"ErrorId: {item.errorId}, Message: {item.errorMessage}" : "Transaction failed for some unknown reason.";
                                }
                            }
                        }
                        else
                        {
                            errorMessage = "Transaction is being invalidated b/c the unique reference returned from Capita is wrong.";
                        }
                    }

                    if (!string.IsNullOrEmpty(errorMessage))
                    {
                        response.Error        = true;
                        response.ErrorMessage = errorMessage;
                    }
                }
                catch (Exception ex)
                {
                    response.Error        = true;
                    response.ErrorMessage = "Fatal error";
                }

                return(response);
            }
        }
        private PaymentAuthorizationResponse ParseResponseFromCapitaResponse(scpSimpleQueryResponse1 capitaResponse)
        {
            if (null == capitaResponse?.scpSimpleQueryResponse)
            {
                return(new PaymentAuthorizationResponse(true, PaymentAuthorizationResult.ErrorUnknownStatus, 0, "null response", null));
            }

            switch (capitaResponse.scpSimpleQueryResponse.transactionState)
            {
            case transactionState.COMPLETE:
                // continue processing
                break;

            case transactionState.IN_PROGRESS:
                return(new PaymentAuthorizationResponse(true, PaymentAuthorizationResult.Unknown, 0, "Transaction is still in progress", null));

            case transactionState.INVALID_REFERENCE:
                return(new PaymentAuthorizationResponse(true, PaymentAuthorizationResult.Unknown, 0, "Transaction has been in validated", null));
            }


            string       errorMessage = string.Empty;
            decimal      amount       = 0;
            errorDetails item         = capitaResponse.scpSimpleQueryResponse.paymentResult.Item as errorDetails;

            if (item != null)
            {
                errorMessage = $"Response code = {capitaResponse.scpSimpleQueryResponse.paymentResult.status}, ErrorId: {item.errorId}, ErrorMsg: {item.errorMessage}";
            }
            else
            {
                string responseDetails = $"Capita Query Response for RequestId {capitaResponse.scpSimpleQueryResponse.requestId}: ScpReference = {capitaResponse.scpSimpleQueryResponse.scpReference} ";

                simplePayment paymentDetails = capitaResponse.scpSimpleQueryResponse.paymentResult.Item as simplePayment;
                if (paymentDetails != null)
                {
                    if (paymentDetails.paymentHeader != null)
                    {
                        responseDetails += $", TransactionDateUtc: {paymentDetails.paymentHeader.transactionDate.ToUniversalTime()}, MachineCode: {paymentDetails.paymentHeader.machineCode}, TransactionId: {paymentDetails.paymentHeader.uniqueTranId}";
                    }


                    authDetails authInfo = paymentDetails.Item as authDetails;
                    if (authInfo != null)
                    {
                        amount = authInfo.amountInMinorUnits;
                        //Convert minor unit amount value into larger unit. For example from pennies to pounds
                        amount           = amount / 100m;
                        responseDetails += $", Amount (Minor Units): {authInfo.amountInMinorUnits}, AuthCode: {authInfo.authCode}, MerchantNumber: {authInfo.merchantNumber}";
                    }
                }

                this.Logger.CreateEntry(typeof(CapitaApiProvider), LogLevel.Info, responseDetails);
            }

            switch (capitaResponse.scpSimpleQueryResponse.paymentResult.status)
            {
            case status.SUCCESS:

                CapitaSavedCardResponse cardResponse  = null;
                string storeCardDetailsFailureMessage = string.Empty;
                if (capitaResponse.scpSimpleQueryResponse.storeCardResult != null)
                {
                    if (capitaResponse.scpSimpleQueryResponse.storeCardResult.status != status.SUCCESS &&
                        capitaResponse.scpSimpleQueryResponse.storeCardResult.status != status.NOT_ATTEMPTED)
                    {
                        errorDetails storeCardErrorDetails =
                            capitaResponse.scpSimpleQueryResponse.storeCardResult.Item as errorDetails;

                        if (storeCardErrorDetails != null)
                        {
                            storeCardDetailsFailureMessage = $"ErrorId: {storeCardErrorDetails.errorId}, ErrorMessage: {storeCardErrorDetails.errorMessage}";
                        }
                        else
                        {
                            storeCardDetailsFailureMessage = "Error: Card details could not be stored. ";
                        }

                        cardResponse = new CapitaSavedCardResponse()
                        {
                            CardSaved      = false,
                            CardSaveStatus = storeCardDetailsFailureMessage
                        };
                    }
                    else
                    {
                        storedCardDetails cardDetails = capitaResponse.scpSimpleQueryResponse.storeCardResult.Item as storedCardDetails;
                        if (cardDetails != null)
                        {
                            cardResponse = new CapitaSavedCardResponse()
                            {
                                CardSaved       = true,
                                CardReference   = cardDetails.storedCardKey.token,
                                CardDigits      = cardDetails.storedCardKey.lastFourDigits,
                                CardDescription = cardDetails.cardDescription.ToString(),
                                CardType        = cardDetails.cardType.ToString(),
                                ExpiryDate      = Utility.ParseExpiryDate(cardDetails.expiryDate)
                            };
                        }
                    }
                }

                string description =
                    $"{storeCardDetailsFailureMessage} ScpReference = {capitaResponse.scpSimpleQueryResponse.scpReference} and RequestId = {capitaResponse.scpSimpleQueryResponse.requestId}.";

                var authorizationResponse = new PaymentAuthorizationResponse(true, PaymentAuthorizationResult.Authorized, amount, description, capitaResponse.scpSimpleQueryResponse.requestId);

                if (cardResponse != null)
                {
                    authorizationResponse.SavedCard = cardResponse;
                }

                return(authorizationResponse);

            case status.INVALID_REQUEST:
            case status.CARD_DETAILS_REJECTED:
            case status.CANCELLED:
            case status.LOGGED_OUT:
            case status.NOT_ATTEMPTED:
                // record not found : either user is still in the GUI or abandonded the process
                return(new PaymentAuthorizationResponse(true, PaymentAuthorizationResult.Declined, 0, errorMessage, capitaResponse.scpSimpleQueryResponse.requestId));

            default:
                return(new PaymentAuthorizationResponse(true, PaymentAuthorizationResult.ErrorUnknownStatus, 0, errorMessage, capitaResponse.scpSimpleQueryResponse.requestId));
            }
        }