public void Can_update_standard_recurring_billing()
        {
            // ReferenceId is set here
            var create = CreateSubscription();

            Assert.IsNotNull(create.RecurringBillingId);

            var subscription = new Subscription("Test Subscription",
                                                DateTime.UtcNow,
                                                Period.Monthly,
                                                0.01);

            var card = new CreditCard("4111 1111 1111 1111",
                                      "John Q Customer",
                                      DateTime.Now.Month,
                                      DateTime.Now.Year);

            var beanstream = new BeanstreamProcessor(CredentialFirst,
                                                     CredentialSecond,
                                                     CredentialThird);

            var result = beanstream.UpdateRecurringBilling(subscription, card);

            Assert.IsNotNull(result);
        }
        /// <summary>
        /// Cancels the recurring billing.
        /// </summary>
        /// <param name="subscription">The subscription.</param>
        /// <returns></returns>
        public AuthorizeNetResult CancelRecurringBilling(Subscription subscription)
        {
            var document = BuildRecurringBillingRequest(RecurringBillingTransactionType.Cancel,
                                                        subscription,
                                                        null);

            return SendRecurringBillingRequest(document);
        }
        private AuthorizeNetResult CreateRecurringBilling(Subscription subscription)
        {
            var expiryMonth = DateTime.UtcNow.Month;
            var expiryYear = DateTime.UtcNow.Year;
            var creditCard = new CreditCard("4111 1111 1111 1111", "John Q Customer", expiryMonth, expiryYear);

            return CreateRecurringBilling(subscription, creditCard);
        }
        private AuthorizeNetResult CancelRecurringBilling(Subscription subscription)
        {
            var authDotNet = new AuthorizeNetProcessor(CredentialFirst, CredentialSecond);

            var result = authDotNet.CancelRecurringBilling(subscription);

            return result;
        }
        private AuthorizeNetResult CreateRecurringBilling(Subscription subscription, CreditCard card)
        {
            var authDotNet = new AuthorizeNetProcessor(CredentialFirst, CredentialSecond);
            var billTo = new Address {FirstName = "John", LastName = "Customer"};

            authDotNet.SetBillingAddress(billTo);

            var result = authDotNet.CreateRecurringBilling(subscription, card);
            return result;
        }
        /// <summary>
        /// Creates the recurring billing.
        /// </summary>
        /// <param name="subscription">The subscription.</param>
        /// <param name="card">The card.</param>
        /// <returns></returns>
        public AuthorizeNetResult CreateRecurringBilling(Subscription subscription, CreditCard card)
        {
            ValidateSubscription(subscription);
            ValidateAmountCard(subscription.PaymentAmount, card);
            ValidateBillingAddress();

            var document = BuildRecurringBillingRequest(RecurringBillingTransactionType.Create,
                                                        subscription,
                                                        card);

            var result = SendRecurringBillingRequest(document);
            if (!result.TransactionId.IsNullOrBlank())
            {
                subscription.ReferenceId = Convert.ToInt64(result.TransactionId);
            }

            return result;
        }
        public void Can_create_monthly_subscription_with_end_date()
        {
            var start = DateTime.UtcNow;
            var end = start.AddYears(1);

            var subscription = new Subscription
                (
                "Monthly Subscription",
                start,
                end,
                Period.Monthly,
                15
                );

            var payments = subscription.TotalPayments;
            var amount = subscription.TotalAmount;

            Assert.AreEqual(12, payments);
            Assert.AreEqual(12*15, amount);
        }
        public void Can_create_disparate_trial_and_subscription_periods()
        {
            var start = DateTime.UtcNow;
            var end = start.AddYears(5);

            // Every five days at the introductory price
            var trialPeriod = new Period(PeriodFrequency.Days, 5);

            var subscription = new Subscription("Monthly Subscription with Introductory Price",
                                                start, end,
                                                Period.Monthly, 30,
                                                trialPeriod, 1.00, 1);

            Assert.AreEqual(1771, subscription.TotalAmount);
            Assert.AreEqual(1770, subscription.TotalBillingAmount);
            Assert.AreEqual(1, subscription.TotalTrialAmount.Value);

            Assert.AreEqual(1, subscription.TrialAmount.Value);
            Assert.AreEqual(60, subscription.TotalPayments); // All occurrences are paid
            Assert.AreEqual(1, subscription.TrialPayments);
        }
        /// <summary>
        /// Updates the recurring billing.
        /// </summary>
        /// <param name="subscription">The subscription.</param>
        /// <param name="card">The card.</param>
        /// <returns></returns>
        public AuthorizeNetResult UpdateRecurringBilling(Subscription subscription, CreditCard card)
        {
            ValidateSubscription(subscription);
            ValidateAmountCard(subscription.PaymentAmount, card);
            ValidateBillingAddress();

            var document = BuildRecurringBillingRequest(RecurringBillingTransactionType.Update,
                                                        subscription,
                                                        card);

            return SendRecurringBillingRequest(document);
        }
        private XDocument BuildRecurringBillingRequest(RecurringBillingTransactionType type,
                                                       Subscription subscription,
                                                       CreditCard card)
        {
            XNamespace xmlns = "AnetApi/xml/v1/schema/AnetApiSchema.xsd";
            //var xml = new XmlWrapper(xmlns);

            var hasSubscription = subscription != null;

            var hasId = hasSubscription && subscription.Id != Identity.None;
            var hasRefId = hasSubscription && subscription.ReferenceId.HasValue;

            var refId = hasSubscription ? subscription.Id : Identity.None;
            var subscriptionId = hasSubscription
                                     ? subscription.ReferenceId.ValueOr(Identity.None)
                                     : Identity.None;

            if (type == RecurringBillingTransactionType.Cancel)
            {
                subscription = null;
            }

            // TODO Gateway
            return null;

            /*
            return new XDocument(
                XmlWrapper.Declare("1.0", "utf-8")
                , xml.Tag("ARB{0}SubscriptionRequest".FormatWith(type)
                          , xml.Tag("merchantAuthentication"
                                    , xml.Tag("name", Authenticator.First)
                                    , xml.Tag("transactionKey", Authenticator.Second))
                          , xml.If(hasId, xml.Tag("refId", refId))
                          , xml.If(hasRefId, xml.Tag("subscriptionId", subscriptionId))
                          , xml.If(hasSubscription, BuildSubscriptionNode(subscription, xml, card))
                      )
                );
            */
        }
        private BeanstreamResult CreateSubscription()
        {
            var subscription = new Subscription("Test Subscription",
                                                DateTime.UtcNow,
                                                Period.Monthly,
                                                0.01);

            var card = new CreditCard("4111 1111 1111 1111",
                                      "John Q Customer",
                                      DateTime.Now.Month,
                                      DateTime.Now.Year);

            var beanstream = new BeanstreamProcessor(CredentialFirst, CredentialSecond, CredentialThird);

            //  Billing address is required for card transactions
            beanstream.SetBillingAddress(new Address
                                             {
                                                 FirstName = "Paul Randal",
                                                 Email = "*****@*****.**",
                                                 Phone = "9999999",
                                                 AddressLine = "1045 Main Street",
                                                 City = "Vancouver",
                                                 State = "BC",
                                                 Zip = "V8R 1J6",
                                                 Country = "CA",
                                             });

            return beanstream.CreateRecurringBilling(subscription, card);
        }
        public void Can_create_monthly_subscription_with_indefinite_end_date()
        {
            var start = DateTime.UtcNow;

            var subscription = new Subscription
                (
                "Monthly Subscription",
                start,
                Period.Monthly,
                15
                );

            var payments = subscription.TotalPayments;
            var amount = subscription.TotalAmount;

            Assert.AreEqual(null, payments);
            Assert.AreEqual(double.PositiveInfinity, (double) amount);
        }
        public void Can_create_subscription_with_prorated_start_date()
        {
            var start = DateTime.UtcNow;
            var end = start.AddYears(5);

            var prorated = 10d/DateTime.DaysInMonth(start.Year, start.Month);
            Money expected = 30*prorated;

            var subscription = new Subscription("Monthly Subscription with Prorated Start Date",
                                                start, end, start.Subtract(TimeSpan.FromDays(10)),
                                                Period.Monthly, 30);

            Assert.AreEqual(expected, subscription.ProratedAmount.Value);
        }
        public void Can_create_monthly_subscription_with_paid_trial_period()
        {
            var start = DateTime.UtcNow;
            var end = start.AddYears(5);

            var trialPeriod = new Period(PeriodFrequency.Months, 1);

            var subscription = new Subscription("Monthly Subscription with Introductory Price",
                                                start, end,
                                                Period.Monthly, 30,
                                                trialPeriod, 15, 1);

            Assert.IsNotNull(subscription.TrialPayments);
            Assert.AreEqual(60, subscription.TotalPayments); // All occurrences are paid
            Assert.AreEqual(1, subscription.TrialPayments);
        }
        public void Can_create_monthly_subscription_with_one_month_free_trial()
        {
            var start = DateTime.UtcNow;
            var end = start.AddYears(5);

            var trialPeriod = new Period(PeriodFrequency.Months, 1);

            var subscription = new Subscription("Monthly Subscription with One Month Free",
                                                start, end, Period.Monthly, 15, trialPeriod);

            var payments = subscription.TotalPayments;
            var trialPayments = subscription.TrialPayments;
            var amount = subscription.TotalAmount;

            Assert.AreEqual(start.AddMonths(1), subscription.PaymentStartDate);
            Assert.IsNull(trialPayments, "This is a free trial");
            Assert.AreEqual(12*5 - 1, payments);
            Assert.AreEqual(5*12*15 - 15, amount);
        }
        public void Can_create_monthly_subscription_with_non_standard_trial_period()
        {
            var start = DateTime.UtcNow;
            var end = start.AddYears(5);

            var trialPeriod = new Period(PeriodFrequency.Days, 32);

            var subscription = new Subscription("Monthly Subscription with 31 Days Free",
                                                start, end, Period.Monthly, 15, trialPeriod);

            Assert.AreEqual(start.AddDays(32), subscription.PaymentStartDate);

            var payments = subscription.TotalPayments;
            var amount = subscription.TotalAmount;

            Assert.AreEqual(12*5 - 1, payments);
            Assert.AreEqual(5*12*15 - 15, amount);

            var next = subscription.NextPaymentDate;
            var prev = subscription.PreviousPaymentDate;

            Assert.AreEqual(subscription.PaymentStartDate, next);
            Assert.IsNull(prev);
            Assert.IsNull(subscription.TrialPayments);
            Assert.IsNull(subscription.TrialAmount);
        }