public static void PaymentStatusIsNotSettled(this Guard guard, SecureTradingTransactionQueryXmlResponse response)
 {
     if (response.SettleStatus != SecureTradingSettlementStatus.Settled)
     {
         throw new InvalidOperationException("cannot refund a payment that is not acquired.");
     }
 }
        protected override bool RefundPaymentInternal(Payment payment, out string status)
        {
            SecureTradingTransactionQueryXmlResponse transactionQueryResponse = _secureTradingXmlRequester.TransactionQuery(payment.TransactionId, payment.PaymentMethod);

            if (PaymentQualifiesForCancel(transactionQueryResponse))
            {
                return(CancelPaymentInternal(payment, out status));
            }

            Guard.Against.PaymentStatusIsNotSettled(transactionQueryResponse);

            SecureTradingRefundXmlResponse refundXmlResponse = _secureTradingXmlRequester.Refund(payment.TransactionId,
                                                                                                 payment.PurchaseOrder.OrderGuid.ToString(), payment.PaymentMethod);

            if (refundXmlResponse.ErrorCode == SecureTradingErrorCode.Success)
            {
                status = PaymentMessages.RefundSuccess;
                payment.PaymentStatus = _paymentStatusRepository.Get((int)PaymentStatusCode.Refunded);
                return(true);
            }

            _loggingService.Log <SecureTradingPaymentMethodService>(string.Format("failed to refund payment. Message: {0} Response was:\r\n {1}", refundXmlResponse.ErrorMessage, refundXmlResponse.XmlResponse));
            status = string.Format("{0} - {1}", PaymentMessages.RefundFailed, refundXmlResponse.ErrorMessage);
            payment.PaymentStatus = _paymentStatusRepository.Get((int)PaymentStatusCode.Declined);              //TODO: should payment status be changed in case request was declined / failed?
            return(false);
        }
        private bool HandleAuthRequest(Payment payment, NameValueCollection queryString)
        {
            bool instantCapture = payment.PaymentMethod.DynamicProperty <bool>().InstantCapture;

            SecureTradingTransactionQueryXmlResponse transactionQueryResponse = GetSecureTradingXmlResponse(queryString, payment.PaymentMethod);

            if (!transactionQueryResponse.TransactionFound)
            {
                payment.TransactionId = GetQueryStringParameter(queryString, SecureTradingConstants.Transactionreference);
                return(false);
            }

            Guard.Against.TransactionQueryRequestDoesNotMatchesAuthStatus(transactionQueryResponse);
            Guard.Against.TransactionRequestDoesNotMatchesOrder(payment, transactionQueryResponse);
            Guard.Against.NotPendingAuthorizationForPayment(payment, _paymentStatusRepository);

            payment.TransactionId = transactionQueryResponse.TransactionId;

            if (transactionQueryResponse.SettleStatus == SecureTradingSettlementStatus.Suspended && !instantCapture)
            {
                payment.PaymentStatus = _paymentStatusRepository.Get((int)PaymentStatusCode.Authorized);
            }
            else if (transactionQueryResponse.SettleStatus == (int)SecureTradingSettlementStatus.PendingSettlement && instantCapture)
            {
                payment.PaymentStatus = _paymentStatusRepository.Get((int)PaymentStatusCode.Acquired);
            }
            else
            {
                throw new InvalidOperationException(
                          string.Format("SettleStatus did not match InstantCapture configuration. Was: {0} Configuration for InstantCapture: {1}",
                                        transactionQueryResponse.SettleStatus,
                                        instantCapture));
            }
            return(true);
        }
 public static void PaymentStatusIsNotSuspended(this Guard guard, SecureTradingTransactionQueryXmlResponse response)
 {
     if (response.SettleStatus != SecureTradingSettlementStatus.Suspended)
     {
         throw new InvalidOperationException(string.Format("Cannot acquire payment. Status from payment was not suspended. Status was: {0}", response.SettleStatus.ToString()));
     }
 }
 /// <summary>
 /// Payment may in some cases qualify for cancelation instead of refund as acquiering money takes one day to process.
 /// </summary>
 /// <param name="transactionQueryResponse"></param>
 /// <returns></returns>
 private bool PaymentQualifiesForCancel(SecureTradingTransactionQueryXmlResponse transactionQueryResponse)
 {
     return
         (
         transactionQueryResponse.SettleStatus == SecureTradingSettlementStatus.PendingSettlement ||
         transactionQueryResponse.SettleStatus == SecureTradingSettlementStatus.PendingSettlementManuallyOverridden ||
         transactionQueryResponse.SettleStatus == SecureTradingSettlementStatus.Suspended
         );
 }
 public static void PaymentDoesNotQualifyForCancellation(this Guard guard,
                                                         SecureTradingTransactionQueryXmlResponse transactionQueryResponse)
 {
     if (transactionQueryResponse.SettleStatus != SecureTradingSettlementStatus.PendingSettlement &&
         transactionQueryResponse.SettleStatus != SecureTradingSettlementStatus.PendingSettlementManuallyOverridden &&
         transactionQueryResponse.SettleStatus != SecureTradingSettlementStatus.Suspended)
     {
         throw new InvalidOperationException(string.Format("Status was: {0}. Expected PendingSettlement,PendingSettlementManuallyOverridden or Suspended.", transactionQueryResponse.SettleStatus.ToString()));
     }
 }
        /// <summary>
        /// Acquires the payment if payment is authorized.
        /// </summary>
        /// <param name="payment"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        /// <remarks>http://www.securetrading.com/files/documentation/STPP-Transaction-Update.pdf
        /// page 9 describes the xml to be sent for updating the transaction.
        /// </remarks>
        protected override bool AcquirePaymentInternal(Payment payment, out string status)
        {
            SecureTradingTransactionQueryXmlResponse transactionQueryResponse = _secureTradingXmlRequester.TransactionQuery(payment.TransactionId, payment.PaymentMethod);

            Guard.Against.PaymentStatusIsNotSuspended(transactionQueryResponse);

            SecureTradingTransactionUpdateXmlResponse updateSettleMentStatusResponse =
                _secureTradingXmlRequester.UpdateSettleMentStatus(payment.TransactionId, SecureTradingSettlementStatus.PendingSettlement, payment.PaymentMethod);

            if (updateSettleMentStatusResponse.ErrorCode == SecureTradingErrorCode.Success)
            {
                status = PaymentMessages.AcquireSuccess;
                payment.PaymentStatus = _paymentStatusRepository.Get((int)PaymentStatusCode.Acquired);
                return(true);
            }

            _loggingService.Log <SecureTradingPaymentMethodService>(string.Format("failed to acquire payment. Message: {0} Response was:\r\n {1}", updateSettleMentStatusResponse.ErrorMessage, updateSettleMentStatusResponse.XmlResponse));
            payment.PaymentStatus = _paymentStatusRepository.Get((int)PaymentStatusCode.AcquireFailed);
            status = string.Format("{0} - {1}", PaymentMessages.AcquireFailed, updateSettleMentStatusResponse.ErrorMessage);
            return(false);
        }
        protected override bool CancelPaymentInternal(Payment payment, out string status)
        {
            SecureTradingTransactionQueryXmlResponse transactionQueryResponse = _secureTradingXmlRequester.TransactionQuery(payment.TransactionId, payment.PaymentMethod);

            Guard.Against.PaymentDoesNotQualifyForCancellation(transactionQueryResponse);

            SecureTradingTransactionUpdateXmlResponse cancelRequestResponse
                = _secureTradingXmlRequester.UpdateSettleMentStatus(payment.TransactionId, SecureTradingSettlementStatus.Cancelled, payment.PaymentMethod);

            if (cancelRequestResponse.ErrorCode == SecureTradingErrorCode.Success)
            {
                payment.PaymentStatus = _paymentStatusRepository.Get((int)PaymentStatusCode.Cancelled);
                status = PaymentMessages.CancelSuccess;
                return(true);
            }

            _loggingService.Log <SecureTradingPaymentMethodService>(string.Format("failed to cancel payment. Message: {0} Response was:\r\n {1}", cancelRequestResponse.ErrorMessage, cancelRequestResponse.XmlResponse));

            status = string.Format("{0} - {1}", PaymentMessages.CancelFailed, cancelRequestResponse.ErrorMessage);
            return(false);
        }
        private SecureTradingTransactionQueryXmlResponse GetSafeTransactionQuery(string transactionId, PaymentMethod paymentMethod)
        {
            SecureTradingTransactionQueryXmlResponse secureTradingTransactionQueryXmlResponse = _secureTradingXmlRequester.TransactionQuery(transactionId, paymentMethod);
            bool transactionFound = secureTradingTransactionQueryXmlResponse.TransactionFound;

            if (transactionFound)
            {
                return(secureTradingTransactionQueryXmlResponse);
            }

            _loggingService.Log <SecureTradingPaymentMethodService>(string.Format("Transaction with id: {0} not found. \r\n. Waiting {1} seconds for retry.", transactionId, _secondsToWaitOnRetryForQuery));
            int retries = 0;

            while (!transactionFound && retries < _numberOfRetriesForTransactionQuery)
            {
                Thread.Sleep(_secondsToWaitOnRetryForQuery * 1000);
                secureTradingTransactionQueryXmlResponse = _secureTradingXmlRequester.TransactionQuery(transactionId, paymentMethod);
                transactionFound = secureTradingTransactionQueryXmlResponse.TransactionFound;
                retries++;
                if (!transactionFound)
                {
                    _loggingService.Log <SecureTradingPaymentMethodService>(string.Format("Failed to find Transaction with id: {0}. Number of tries: {1} ", retries, transactionId));
                }
            }

            if (transactionFound)
            {
                _loggingService.Log <SecureTradingPaymentMethodService>(
                    string.Format("Transaction was found after {0} number of tries.", retries));
            }
            else
            {
                _loggingService.Log <SecureTradingPaymentMethodService>(
                    string.Format("Failed to find transaction after {0} attempts with timeout period: {1}", _numberOfRetriesForTransactionQuery, _numberOfRetriesForTransactionQuery * _secondsToWaitOnRetryForQuery));
            }

            return(secureTradingTransactionQueryXmlResponse);
        }
 public static void TransactionRequestDoesNotMatchesOrder(this Guard guard, Payment payment, SecureTradingTransactionQueryXmlResponse transactionQueryRequest)
 {
     if (transactionQueryRequest.OrderReference != payment.PurchaseOrder.OrderGuid.ToString())
     {
         throw new InvalidOperationException(
                   string.Format("Transactionquery orderreference: {0} did not match orderrefererence: {1}",
                                 transactionQueryRequest.OrderReference, payment.PurchaseOrder.OrderGuid));
     }
 }
 public static void TransactionQueryRequestDoesNotMatchesAuthStatus(this Guard guard, SecureTradingTransactionQueryXmlResponse transactionQueryRequest)
 {
     if (!transactionQueryRequest.Success)
     {
         throw new InvalidOperationException("QueryString parameter and transactionrequest did not match.");
     }
 }
 public static void TransactionQueryRequestDoesNotMatchesDeclinedStatus(this Guard guard, SecureTradingTransactionQueryXmlResponse transactionQueryRequest)
 {
     if (transactionQueryRequest.SettleStatus != SecureTradingSettlementStatus.Cancelled)
     {
         throw new InvalidOperationException("QueryString parameter and transactionrequest did not match.");
     }
 }