private RecurringRequest InitializeAuthRecurringRequest(AuthorizeRecurringTransactionRequest authRequest, int payPeriod)
        {
            VerifyPaymentInstrument(authRequest.Payment);
            RecurringRequest request = new RecurringRequest();

            Payment payment = authRequest.Payment;
            Order   order   = payment.Order;
            User    user    = payment.Order.User;
            //Address address = user.PrimaryAddress;

            //credit card data
            AccountDataDictionary accountData = new AccountDataDictionary(payment.AccountData);
            string accountNumber   = accountData.GetValue("AccountNumber");
            string expirationMonth = accountData.GetValue("ExpirationMonth");

            if (expirationMonth.Length == 1)
            {
                expirationMonth.Insert(0, "0");
            }
            string expirationYear = accountData.GetValue("ExpirationYear");

            request.setCommand(RecurringRequest.COMMAND_ADD_CUSTOMER_ACCOUNT_AND_RECURRENCE);
            request.setAccountType(RecurringRequest.ACCOUNT_TYPE_CREDIT_CARD);
            request.setCreditCardNumber(accountNumber);
            request.setExpireMonth(expirationMonth);
            request.setExpireYear(expirationYear);

            request.setBillingAddress(order.BillToAddress1 + ", " + order.BillToAddress2 + "," + order.BillToCity);
            request.setZipOrPostalCode(order.BillToPostalCode);
            request.setCountryCode(order.BillToCountryCode);

            LSDecimal amount = authRequest.RecurringChargeSpecified ? authRequest.RecurringCharge : authRequest.Amount;

            request.setChargeTotal((double)amount);

            request.setCustomerId(user.UserId.ToString());
            if (accountData.ContainsKey("AccountName") && !string.IsNullOrEmpty(accountData["AccountName"]))
            {
                request.setCustomerName(accountData["AccountName"]);
            }
            else
            {
                request.setCustomerName(order.BillToFirstName + " " + order.BillToLastName);
            }
            request.setDescription(authRequest.SubscriptionName);

            string strEmail = string.IsNullOrEmpty(order.BillToEmail) ? user.Email : order.BillToEmail;

            request.setEmailAddress(user.Email);

            request.setNotifyCustomer(true);
            request.setNumberOfRetries(3);
            request.setRecurrenceId(authRequest.Payment.OrderId.ToString());
            request.setPeriod(payPeriod);

            DateTime startDt = LocaleHelper.LocalNow;

            if (authRequest.RecurringChargeSpecified)
            {
                startDt = GetNextPaymentDate(payPeriod);
            }
            request.setStartDay(startDt.Day);
            request.setStartMonth(startDt.Month);
            request.setStartYear(startDt.Year);

            DateTime endDt = GetEndDate(startDt, payPeriod, authRequest.NumberOfPayments);

            request.setEndDay(endDt.Day);
            request.setEndMonth(endDt.Month);
            request.setEndYear(endDt.Year);

            return(request);
        }
        public override AuthorizeRecurringTransactionResponse DoAuthorizeRecurring(AuthorizeRecurringTransactionRequest authorizeRequest)
        {
            VerifyStatus();
            Payment payment = authorizeRequest.Payment;

            if (payment == null)
            {
                throw new ArgumentNullException("request.Payment");
            }
            Order order = payment.Order;

            if (order == null)
            {
                throw new ArgumentNullException("request.Payment.Order");
            }
            User user = order.User;

            if (user == null)
            {
                throw new ArgumentNullException("request.Payment.Order.User");
            }

            AuthorizeRecurringTransactionResponse response = new AuthorizeRecurringTransactionResponse();
            AuthorizeTransactionRequest           authRequest;
            Transaction tr1, tr2, errTrans;

            //VALIDATE THE PAYMENT PERIOD
            int payPeriod = GetPayPeriod(authorizeRequest);

            if (payPeriod == int.MinValue)
            {
                errTrans = Transaction.CreateErrorTransaction(this.PaymentGatewayId, authorizeRequest, "E", "The specified payment interval is not valid for this processor.");
                return(new AuthorizeRecurringTransactionResponse(errTrans));
            }

            if (authorizeRequest.RecurringChargeSpecified)
            {
                //make a sale transaction first
                authRequest         = new AuthorizeTransactionRequest(authorizeRequest.Payment, authorizeRequest.RemoteIP);
                authRequest.Capture = true;
                authRequest.Amount  = authorizeRequest.Amount;
                tr1 = DoAuthorize(authRequest);
                if (tr1.TransactionStatus != TransactionStatus.Successful)
                {
                    errTrans = Transaction.CreateErrorTransaction(PaymentGatewayId, authorizeRequest, "E", "Authorization Failed.");
                    errTrans.TransactionType = TransactionType.AuthorizeRecurring;
                    response.AddTransaction(tr1);
                    response.AddTransaction(errTrans);
                    response.Status = TransactionStatus.Failed;
                    return(response);
                }
                response.AddTransaction(tr1);
            }

            RecurringRequest  request     = InitializeAuthRecurringRequest(authorizeRequest, payPeriod);
            RecurringResponse recResponse = null;

            //RECORD REQUEST : TODO

            /*if (this.UseDebugMode)
             * {
             *  string reqDebug = BuildRequestDebug(request);
             *  this.RecordCommunication(this.Name, CommunicationDirection.Send, reqDebug);
             * }*/

            //TODO : Test mode is not supported.
            if (this.UseTestMode)
            {
                recResponse = (RecurringResponse)TransactionClient.doTransaction(request, this.AccountToken);
            }
            else
            {
                recResponse = (RecurringResponse)TransactionClient.doTransaction(request, this.AccountToken);
            }

            if (recResponse != null)
            {
                //RECORD RESPONSE
                if (this.UseDebugMode)
                {
                    string respDebug = BuildRecurringResponseDebug(recResponse);
                    this.RecordCommunication(this.Name, CommunicationDirection.Receive, respDebug, null);
                }

                tr2 = ProcessRecurringResponse(authorizeRequest, recResponse);
                response.AddTransaction(tr2);
                response.Status = tr2.TransactionStatus;

                return(response);
            }
            else
            {
                throw new Exception("Operation Failed, Response is null.");
            }
        }