/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *******************************************************************************/

package org.ofbiz.accounting.thirdparty.sagepay;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javolution.util.FastMap;

import org.ofbiz.accounting.payment.PaymentGatewayServices;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilDateTime;
import org.ofbiz.base.util.UtilFormatOut;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.condition.EntityCondition;
import org.ofbiz.entity.util.EntityUtil;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.GenericServiceException;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ServiceUtil;

public class SagePayPaymentServices {

    public static final String module = SagePayPaymentServices.class.getName();
    public final static String resource = "AccountingUiLabels";

    private static Map<String, String> buildCustomerBillingInfo(Map<String, Object> context) {
        Debug.logInfo("SagePay - Entered buildCustomerBillingInfo", module);
        Debug.logInfo("SagePay buildCustomerBillingInfo context : " + context, module);

        Map<String, String> billingInfo = FastMap.newInstance();

        String orderId = null;
        BigDecimal processAmount = null;
        String currency = null;
        String cardNumber = null;
        String cardType = null;
        String nameOnCard = null;
        String expireDate = null;
        String securityCode = null;
        String postalCode = null;
        String address = null;

        try {

            GenericValue opp = (GenericValue) context.get("orderPaymentPreference");
            if (opp != null) {
                if ("CREDIT_CARD".equals(opp.getString("paymentMethodTypeId"))) {

                    GenericValue creditCard = (GenericValue) context.get("creditCard");
                    if (creditCard == null || !(opp.get("paymentMethodId").equals(creditCard.get("paymentMethodId")))) {
                        creditCard = opp.getRelatedOne("CreditCard", false);
                    }

                    securityCode = opp.getString("securityCode");

                    //getting billing address
                    GenericValue billingAddress = (GenericValue) context.get("billingAddress");
                    postalCode = billingAddress.getString("postalCode");
                    String address2 = billingAddress.getString("address2");
                    if (address2 == null){
                        address2 = "";
                    }
                    address = billingAddress.getString("address1") + " " + address2;

                    //getting card details
                    cardNumber = creditCard.getString("cardNumber");
                    String firstName = creditCard.getString("firstNameOnCard");
                    String middleName = creditCard.getString("middleNameOnCard");
                    String lastName = creditCard.getString("lastNameOnCard");
                    if (middleName == null){
                        middleName = "";
                    }
                    nameOnCard = firstName + " " + middleName + " " + lastName;
                    cardType = creditCard.getString("cardType");
                    if (cardType != null) {
                        if ("CCT_MASTERCARD".equals(cardType)) {
                            cardType = "MC";
                        }
                        if ("CCT_VISAELECTRON".equals(cardType)) {
                            cardType = "UKE";
                        }
                        if ("CCT_DINERSCLUB".equals(cardType)) {
                            cardType = "DC";
                        }
                        if ("CCT_SWITCH".equals(cardType)) {
                            cardType = "MAESTRO";
                        }
                    }
                    expireDate = creditCard.getString("expireDate");
                    String month = expireDate.substring(0,2);
                    String year = expireDate.substring(5);
                    expireDate = month + year;

                    //getting order details
                    orderId = UtilFormatOut.checkNull((String) context.get("orderId"));
                    processAmount =  (BigDecimal) context.get("processAmount");
                    currency = (String) context.get("currency");

                } else {
                    Debug.logWarning("Payment preference " + opp + " is not a credit card", module);
                }
            }
        } catch (GenericEntityException ex) {
            Debug.logError("Cannot build customer information for " + context + " due to error: " + ex.getMessage(), module);
            return null;
        }

        billingInfo.put("orderId", orderId);
        billingInfo.put("amount", processAmount.toString());
        billingInfo.put("currency", currency);
        billingInfo.put("description", orderId);
        billingInfo.put("cardNumber", cardNumber);
        billingInfo.put("cardHolder",  nameOnCard);
        billingInfo.put("expiryDate", expireDate);
        billingInfo.put("cardType", cardType);
        billingInfo.put("cv2", securityCode);
        billingInfo.put("billingPostCode", postalCode);
        billingInfo.put("billingAddress", address);

        Debug.logInfo("SagePay billingInfo : " + billingInfo, module);
        Debug.logInfo("SagePay - Exiting buildCustomerBillingInfo", module);

        return billingInfo;
    }

    public static Map<String, Object> ccAuth(DispatchContext dctx, Map<String, Object> context) {
        Debug.logInfo("SagePay - Entered ccAuth", module);
        Debug.logInfo("SagePay ccAuth context : " + context, module);
        Map<String, Object> response = null;
        String orderId = (String) context.get("orderId");
        Locale locale = (Locale) context.get("locale");
        GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference");
        
        if (orderPaymentPreference == null) {
            response = ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingSagePayOrderPaymenPreferenceIsNull", UtilMisc.toMap("orderId", orderId, "orderPaymentPreference", orderPaymentPreference), locale));
        } else {
            response = processCardAuthorisationPayment(dctx, context);
        }
        Debug.logInfo("SagePay ccAuth response : " + response, module);
        Debug.logInfo("SagePay - Exiting ccAuth", module);
        return response;
    }


    private static Map<String, Object> processCardAuthorisationPayment(DispatchContext ctx, Map<String, Object> context) {
        Map<String, Object> result = ServiceUtil.returnSuccess();
        LocalDispatcher dispatcher = ctx.getDispatcher();
        Locale locale = (Locale) context.get("locale");
        Map<String, String> billingInfo = buildCustomerBillingInfo(context);
        String paymentGatewayConfigId = (String) context.get("paymentGatewayConfigId");

        try {

            Map<String, Object> paymentResult = dispatcher.runSync("SagePayPaymentAuthentication",
                    UtilMisc.toMap(
                            "paymentGatewayConfigId", paymentGatewayConfigId,
                            "vendorTxCode", billingInfo.get("orderId"),
                            "cardHolder", billingInfo.get("cardHolder"),
                            "cardNumber", billingInfo.get("cardNumber"),
                            "expiryDate", billingInfo.get("expiryDate"),
                            "cardType", billingInfo.get("cardType"),
                            "cv2", billingInfo.get("cv2"),
                            "description", billingInfo.get("description"),
                            "amount", billingInfo.get("amount"),
                            "currency", billingInfo.get("currency"),
                            "billingAddress", billingInfo.get("billingAddress"),
                            "billingPostCode", billingInfo.get("billingPostCode")
                        )
                    );

            Debug.logInfo("SagePay - SagePayPaymentAuthentication result : " + paymentResult, module);

            String transactionType = (String) paymentResult.get("transactionType");
            String status = (String) paymentResult.get("status");
            String statusDetail = (String) paymentResult.get("statusDetail");
            String vpsTxId = (String) paymentResult.get("vpsTxId");
            String securityKey = (String) paymentResult.get("securityKey");
            String txAuthNo = (String) paymentResult.get("txAuthNo");
            String vendorTxCode = (String) paymentResult.get("vendorTxCode");
            String amount = (String) paymentResult.get("amount");

            if (status != null && "OK".equals(status)) {
                Debug.logInfo("SagePay - Payment authorized for order : " + vendorTxCode, module);
                result = SagePayUtil.buildCardAuthorisationPaymentResponse(Boolean.TRUE, txAuthNo, securityKey, new BigDecimal(amount), vpsTxId, vendorTxCode, statusDetail);
                if ("PAYMENT".equals(transactionType)) {
                    Map<String,Object> captureResult = SagePayUtil.buildCardCapturePaymentResponse(Boolean.TRUE, txAuthNo, securityKey, new BigDecimal(amount), vpsTxId, vendorTxCode, statusDetail);
                    result.putAll(captureResult);
                }
            } else if (status != null && "INVALID".equals(status)) {
                Debug.logInfo("SagePay - Invalid authorisation request for order : " + vendorTxCode, module);
                result = SagePayUtil.buildCardAuthorisationPaymentResponse(Boolean.FALSE, null, null, BigDecimal.ZERO, "INVALID", vendorTxCode, statusDetail);
            } else if (status != null && "MALFORMED".equals(status)) {
                Debug.logInfo("SagePay - Malformed authorisation request for order : " + vendorTxCode, module);
                result = SagePayUtil.buildCardAuthorisationPaymentResponse(Boolean.FALSE, null, null, BigDecimal.ZERO, "MALFORMED", vendorTxCode, statusDetail);
            } else if (status != null && "NOTAUTHED".equals(status)) {
                Debug.logInfo("SagePay - NotAuthed authorisation request for order : " + vendorTxCode, module);
                result = SagePayUtil.buildCardAuthorisationPaymentResponse(Boolean.FALSE, null, securityKey, BigDecimal.ZERO, vpsTxId, vendorTxCode, statusDetail);
            } else if (status != null && "REJECTED".equals(status)) {
                Debug.logInfo("SagePay - Rejected authorisation request for order : " + vendorTxCode, module);
                result = SagePayUtil.buildCardAuthorisationPaymentResponse(Boolean.FALSE, null, securityKey, new BigDecimal(amount), vpsTxId, vendorTxCode, statusDetail);
            } else {
                Debug.logInfo("SagePay - Invalid status " + status + " received for order : " + vendorTxCode, module);
                result = SagePayUtil.buildCardAuthorisationPaymentResponse(Boolean.FALSE, null, null, BigDecimal.ZERO, "ERROR", vendorTxCode, statusDetail);
            }
        } catch(GenericServiceException e) {
            Debug.logError(e, "Error in calling SagePayPaymentAuthentication", module);
            result = ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingSagePayPaymentAuthorisationException", UtilMisc.toMap("errorString", e.getMessage()), locale));
        }
        return result;
    }

    public static Map<String, Object> ccCapture(DispatchContext ctx, Map<String, Object> context) {
        Debug.logInfo("SagePay - Entered ccCapture", module);
        Debug.logInfo("SagePay ccCapture context : " + context, module);
        GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference");
        GenericValue authTransaction = PaymentGatewayServices.getAuthTransaction(orderPaymentPreference);
        context.put("authTransaction", authTransaction);
        Map<String, Object> response = processCardCapturePayment(ctx, context);

        Debug.logInfo("SagePay ccCapture response : " + response, module);
        Debug.logInfo("SagePay - Exiting ccCapture", module);

        return response;
    }

    private static Map<String, Object> processCardCapturePayment(DispatchContext ctx, Map<String, Object> context) {
        Map<String, Object> result = ServiceUtil.returnSuccess();
        LocalDispatcher dispatcher = ctx.getDispatcher();
        Locale locale = (Locale) context.get("locale");
        String paymentGatewayConfigId = (String) context.get("paymentGatewayConfigId");
        GenericValue authTransaction = (GenericValue) context.get("authTransaction");
        BigDecimal amount = (BigDecimal) context.get("captureAmount");
        String vendorTxCode = (String) authTransaction.get("altReference");
        String vpsTxId = (String) authTransaction.get("referenceNum");
        String securityKey = (String) authTransaction.get("gatewayFlag");
        String txAuthCode = (String) authTransaction.get("gatewayCode");

        try {

            Map<String, Object> paymentResult = dispatcher.runSync("SagePayPaymentAuthorisation",
                    UtilMisc.toMap(
                            "paymentGatewayConfigId", paymentGatewayConfigId,
                            "vendorTxCode", vendorTxCode,
                            "vpsTxId", vpsTxId,
                            "securityKey", securityKey,
                            "txAuthNo", txAuthCode,
                            "amount", amount.toString()
                        )
                    );
            Debug.logInfo("SagePay - SagePayPaymentAuthorisation result : " + paymentResult, module);
            String status = (String) paymentResult.get("status");
            String statusDetail = (String) paymentResult.get("statusDetail");
            if (status != null && "OK".equals(status)) {
                Debug.logInfo("SagePay Payment Released for Order : " + vendorTxCode, module);
                result = SagePayUtil.buildCardCapturePaymentResponse(Boolean.TRUE, txAuthCode, securityKey, amount, vpsTxId, vendorTxCode, statusDetail);
            } else {
                Debug.logInfo("SagePay - Invalid status " + status + " received for order : " + vendorTxCode, module);
                result = SagePayUtil.buildCardCapturePaymentResponse(Boolean.FALSE, txAuthCode, securityKey, amount, vpsTxId, vendorTxCode, statusDetail);
            }
        } catch(GenericServiceException e) {
            Debug.logError(e, "Error in calling SagePayPaymentAuthorisation", module);
            result = ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingSagePayPaymentAuthorisationException", UtilMisc.toMap("errorString", e.getMessage()), locale));
        }
        return result;
    }

    public static Map<String, Object> ccRefund(DispatchContext ctx, Map<String, Object> context) {
        Debug.logInfo("SagePay - Entered ccRefund", module);
        Debug.logInfo("SagePay ccRefund context : " + context, module);
        Locale locale = (Locale) context.get("locale");
        Delegator delegator = ctx.getDelegator();
        GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference");
        GenericValue captureTransaction = PaymentGatewayServices.getCaptureTransaction(orderPaymentPreference);
        if (captureTransaction == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingPaymentTransactionAuthorizationNotFoundCannotRefund", locale));
        }
        Debug.logInfo("SagePay ccRefund captureTransaction : " + captureTransaction, module);
        GenericValue creditCard = null;
        try {
            creditCard = orderPaymentPreference.getRelatedOne("CreditCard", false);
        } catch (GenericEntityException e) {
            Debug.logError(e, "Error getting CreditCard for OrderPaymentPreference : " + orderPaymentPreference, module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingPaymentUnableToGetCCInfo", locale) + " " + orderPaymentPreference);
        }
        context.put("creditCard",creditCard);
        context.put("captureTransaction", captureTransaction);

        List<GenericValue> authTransactions = PaymentGatewayServices.getAuthTransactions(orderPaymentPreference);

        EntityCondition authCondition = EntityCondition.makeCondition("paymentServiceTypeEnumId", "PRDS_PAY_AUTH");
        List<GenericValue> authTransactions1 = EntityUtil.filterByCondition(authTransactions, authCondition);

        GenericValue authTransaction = EntityUtil.getFirst(authTransactions1);

        Timestamp authTime = authTransaction.getTimestamp("transactionDate");
        Calendar authCal = Calendar.getInstance();
        authCal.setTimeInMillis(authTime.getTime());

        Timestamp nowTime = UtilDateTime.nowTimestamp();
        Calendar nowCal = Calendar.getInstance();
        nowCal.setTimeInMillis(nowTime.getTime());

        Calendar yesterday = Calendar.getInstance();
        yesterday.set(nowCal.get(Calendar.YEAR), nowCal.get(Calendar.MONTH), nowCal.get(Calendar.DATE), 23, 59, 59);
        yesterday.add(Calendar.DAY_OF_YEAR, -1);

        Map<String, Object> response = null;

        if (authCal.before(yesterday)) {
            Debug.logInfo("SagePay - Calling Refund for Refund", module);
            response = processCardRefundPayment(ctx, context);
        } else {

            Calendar cal = Calendar.getInstance();
            cal.set(nowCal.get(Calendar.YEAR), nowCal.get(Calendar.MONTH), nowCal.get(Calendar.DATE), 23, 49, 59);

            if (authCal.before(cal)) {
                Debug.logInfo("SagePay - Calling Void for Refund", module);
                response = processCardVoidPayment(ctx, context);
            } else {
                Debug.logInfo("SagePay - Calling Refund for Refund", module);
                response = processCardRefundPayment(ctx, context);
            }
        }

        Debug.logInfo("SagePay ccRefund response : " + response, module);
        return response;
    }

    private static Map<String, Object> processCardRefundPayment(DispatchContext ctx, Map<String, Object> context) {
        Map<String, Object> result = ServiceUtil.returnSuccess();
        LocalDispatcher dispatcher = ctx.getDispatcher();
        Locale locale = (Locale) context.get("locale");
        String paymentGatewayConfigId = (String) context.get("paymentGatewayConfigId");
        GenericValue captureTransaction = (GenericValue) context.get("captureTransaction");
        BigDecimal amount = (BigDecimal) context.get("refundAmount");

        String orderId = (String) captureTransaction.get("altReference");
        orderId = "R" + orderId;

        try {

            Map<String, Object> paymentResult = dispatcher.runSync("SagePayPaymentRefund",
                    UtilMisc.toMap(
                            "paymentGatewayConfigId", paymentGatewayConfigId,
                            "vendorTxCode", orderId,
                            "amount", amount.toString(),
                            "currency", "GBP",
                            "description", orderId,
                            "relatedVPSTxId", captureTransaction.get("referenceNum"),
                            "relatedVendorTxCode", captureTransaction.get("altReference"),
                            "relatedSecurityKey", captureTransaction.get("gatewayFlag"),
                            "relatedTxAuthNo", captureTransaction.get("gatewayCode")
                        )
                    );
            Debug.logInfo("SagePay - SagePayPaymentRefund result : " + paymentResult, module);

            String status = (String) paymentResult.get("status");
            String statusDetail = (String) paymentResult.get("statusDetail");
            String vpsTxId = (String) paymentResult.get("vpsTxId");
            String txAuthNo = (String) paymentResult.get("txAuthNo");

            if (status != null && "OK".equals(status)) {
                Debug.logInfo("SagePay Payment Refunded for Order : " + orderId, module);
                result = SagePayUtil.buildCardRefundPaymentResponse(Boolean.TRUE, txAuthNo, amount, vpsTxId, orderId, statusDetail);
            } else {
                Debug.logInfo("SagePay - Invalid status " + status + " received for order : " + orderId, module);
                result = SagePayUtil.buildCardRefundPaymentResponse(Boolean.FALSE, null, BigDecimal.ZERO, status, orderId, statusDetail);
            }

        } catch(GenericServiceException e) {
            Debug.logError(e, "Error in calling SagePayPaymentRefund", module);
            result = ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingSagePayPaymentRefundException", UtilMisc.toMap("errorString", e.getMessage()), locale));
        }

        return result;
    }

    private static Map<String, Object> processCardVoidPayment(DispatchContext ctx, Map<String, Object> context) {
        Map<String, Object> result = ServiceUtil.returnSuccess();
        LocalDispatcher dispatcher = ctx.getDispatcher();
        Locale locale = (Locale) context.get("locale");
        String paymentGatewayConfigId = (String) context.get("paymentGatewayConfigId");
        GenericValue captureTransaction = (GenericValue) context.get("captureTransaction");
        BigDecimal amount = (BigDecimal) context.get("refundAmount");
        String orderId = (String) captureTransaction.get("altReference");

        try {
            Map<String, Object> paymentResult = dispatcher.runSync("SagePayPaymentVoid",
                    UtilMisc.toMap(
                            "paymentGatewayConfigId", paymentGatewayConfigId,
                            "vendorTxCode", captureTransaction.get("altReference"),
                            "vpsTxId", captureTransaction.get("referenceNum"),
                            "securityKey", captureTransaction.get("gatewayFlag"),
                            "txAuthNo", captureTransaction.get("gatewayCode")
                        )
                    );

            Debug.logInfo("SagePay - SagePayPaymentVoid result : " + paymentResult, module);

            String status = (String) paymentResult.get("status");
            String statusDetail = (String) paymentResult.get("statusDetail");

            if (status != null && "OK".equals(status)) {
                Debug.logInfo("SagePay Payment Voided for Order : " + orderId, module);
                result = SagePayUtil.buildCardVoidPaymentResponse(Boolean.TRUE, amount, "SUCCESS", orderId, statusDetail);
            } else if (status != null && "MALFORMED".equals(status)) {
                Debug.logInfo("SagePay - Malformed void request for order : " + orderId, module);
                result = SagePayUtil.buildCardVoidPaymentResponse(Boolean.FALSE, BigDecimal.ZERO, "MALFORMED", orderId, statusDetail);
            } else if (status != null && "INVALID".equals(status)){
                Debug.logInfo("SagePay - Invalid void request for order : " + orderId, module);
                result = SagePayUtil.buildCardVoidPaymentResponse(Boolean.FALSE, BigDecimal.ZERO, "INVALID", orderId, statusDetail);
            } else if (status != null && "ERROR".equals(status)){
                Debug.logInfo("SagePay - Error in void request for order : " + orderId, module);
                result = SagePayUtil.buildCardVoidPaymentResponse(Boolean.FALSE, BigDecimal.ZERO, "ERROR", orderId, statusDetail);
            }

        } catch(GenericServiceException e) {
            Debug.logError(e, "Error in calling SagePayPaymentVoid", module);
            result = ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingSagePayPaymentVoidException", UtilMisc.toMap("errorString", e.getMessage()), locale));
        }
        return result;
    }

    public static Map<String, Object> ccRelease(DispatchContext ctx, Map<String, Object> context) {
        Debug.logInfo("SagePay - Entered ccRelease", module);
        Debug.logInfo("SagePay ccRelease context : " + context, module);
        Locale locale = (Locale) context.get("locale");
        GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference");

        GenericValue authTransaction = PaymentGatewayServices.getAuthTransaction(orderPaymentPreference);
        if (authTransaction == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingPaymentTransactionAuthorizationNotFoundCannotRelease", locale));
        }
        context.put("authTransaction", authTransaction);

        Map<String, Object> response = processCardReleasePayment(ctx, context);
        Debug.logInfo("SagePay ccRelease response : " + response, module);
        return response;
    }

    private static Map<String, Object> processCardReleasePayment(DispatchContext ctx, Map<String, Object> context) {
        Map<String, Object> result = ServiceUtil.returnSuccess();
        Locale locale = (Locale) context.get("locale");
        LocalDispatcher dispatcher = ctx.getDispatcher();

        String paymentGatewayConfigId = (String) context.get("paymentGatewayConfigId");
        BigDecimal amount = (BigDecimal) context.get("releaseAmount");

        GenericValue authTransaction = (GenericValue) context.get("authTransaction");
        String orderId = (String) authTransaction.get("altReference");
        String refNum = (String) authTransaction.get("referenceNum");

        try {
            Map<String, Object> paymentResult = dispatcher.runSync("SagePayPaymentRelease",
                    UtilMisc.toMap(
                            "paymentGatewayConfigId", paymentGatewayConfigId,
                            "vendorTxCode", orderId,
                            "releaseAmount", amount.toString(),
                            "vpsTxId", refNum,
                            "securityKey", authTransaction.get("gatewayFlag"),
                            "txAuthNo", authTransaction.get("gatewayCode")
                        )
                    );

            Debug.logInfo("SagePay - SagePayPaymentRelease result : " + paymentResult, module);

            String status = (String) paymentResult.get("status");
            String statusDetail = (String) paymentResult.get("statusDetail");

            if (status != null && "OK".equals(status)) {
                Debug.logInfo("SagePay Payment Released for Order : " + orderId, module);
                result = SagePayUtil.buildCardReleasePaymentResponse(Boolean.TRUE, null, amount, refNum, orderId, statusDetail);
            } else {
                Debug.logInfo("SagePay - Invalid status " + status + " received for order : " + orderId, module);
                result = SagePayUtil.buildCardReleasePaymentResponse(Boolean.FALSE, null, amount, refNum, orderId, statusDetail);
            }

        } catch(GenericServiceException e) {
            Debug.logError(e, "Error in calling SagePayPaymentRelease", module);
            result = ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingSagePayPaymentReleaseException", UtilMisc.toMap("errorString", e.getMessage()), locale));
        }

        return result;
    }

}
