public static async Task <Agreement> CreateBillingAgreement(string planId, SimplePostalAddress shippingAddress,
                                                                    string name, string description, DateTime startDate)
        {
            var client = PayPalConfiguration.GetClient();

            var agreement = new Agreement()
            {
                Name        = name,
                Description = description,
                StartDate   = startDate.ToString("yyyy-MM-ddTHH:mm:ss") + "Z",
                Payer       = new PayPal.v1.BillingAgreements.Payer()
                {
                    PaymentMethod = "paypal"
                },
                Plan = new PlanWithId()
                {
                    Id = planId
                },
                ShippingAddress = shippingAddress
            };

            AgreementCreateRequest request = new AgreementCreateRequest();

            request.RequestBody(agreement);
            request.Body = agreement;

            try
            {
                HttpResponse response = await client.Execute(request);

                var statusCode = response.StatusCode;
                return(response.Result <Agreement>());
            }
            catch (HttpException httpException)
            {
                var statusCode = httpException.StatusCode;
                var debugId    = httpException.Headers.GetValues("PayPal-Debug-Id").FirstOrDefault();

                throw httpException;
            }
        }
Example #2
0
        public async Task <IActionResult> Purchase(PurchaseVm model)
        {
            var plan    = _dbContext.BillingPlans.FirstOrDefault(x => x.PayPalPlanId == model.Product.PayPalPlanId);
            var product = _dbContext.Products.FirstOrDefault(x => x.PayPalPlanId == model.Product.PayPalPlanId);

            //check DUPLICATES
            ApplicationUser currentUser = await _userManager.GetUserAsync(User);

            var userhasAnySubscriptions = _dbContext.UserSubscriptions.Any(x => x.UserId == currentUser.Id && x.SubscriptionId != null);

            if (userhasAnySubscriptions)
            {
                List <UserSubscriptions> subscribedPlans = _dbContext.UserSubscriptions.Where(x => x.UserId == currentUser.Id && x.SubscriptionId != null).ToList();

                bool alreadySusbcribedToThisPlan = subscribedPlans.Any(x => x.PayPalPlanId == product.PayPalPlanId);

                if (alreadySusbcribedToThisPlan)
                {
                    return(RedirectToAction("DuplicateSubscriptionFound", product));
                }
            }


            if (ModelState.IsValid && plan != null)
            {
                // Since we take an Initial Payment (instant payment), the start date of the recurring payments will be next month.
                //var startDate = DateTime.UtcNow.AddMonths(1);

                //set subscription start date based on plan.
                var startDate = DateTime.UtcNow;
                if (plan.Name.Contains("Monthly"))
                {
                    startDate = DateTime.UtcNow.AddMonths(1);
                }

                if (plan.Name.Contains("3 Months"))
                {
                    startDate = DateTime.UtcNow.AddMonths(3);
                }


                //start_date string required
                //The date and time when this agreement begins, in Internet date and time format.
                //The start date must be no less than 24 hours after the current date as the agreement can take up to 24 hours to activate.
                //The start date and time in the create agreement request might not match the start date and time that the API returns
                //in the execute agreement response. When you execute an agreement, the API internally converts the start date and time to
                //the start of the day in the time zone of the merchant account.For example, the API converts a 2017 - 01 - 02T14: 36:21Z start date and time
                //for an account in the Berlin time zone(UTC + 1) to 2017 - 01 - 02T00:00:00.When the API returns this date and time in the
                //execute agreement response, it shows the converted date and time in the UTC time zone.So,
                //the internal 2017-01-02T00:00:00 start date and time becomes 2017-01-01T23:00:00 externally.
                string formatedStringDate = startDate.ToString("o", CultureInfo.InvariantCulture);
                var    formatedStartDate  = DateTime.Parse(formatedStringDate, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);

                //DateTime.UtcNow.ToString("o");


                var subscription = new Subscription()
                {
                    FirstName    = currentUser.FirstName,
                    LastName     = currentUser.LastName,
                    Email        = currentUser.Email,
                    StartDate    = formatedStartDate, //stat date has to be greator than now.
                    PayPalPlanId = plan.PayPalPlanId
                };
                _dbContext.Subscriptions.Add(subscription);


                var userNewSubscriptoin = new UserSubscriptions()
                {
                    PayPalPlanId = plan.PayPalPlanId,
                    Description  = plan.Description,
                    User         = currentUser,
                    UserId       = currentUser.Id
                };

                _dbContext.UserSubscriptions.Add(userNewSubscriptoin);

                _dbContext.SaveChanges();

                var agreement = new Agreement()
                {
                    Name        = plan.Name,
                    Description = plan.Description,
                    StartDate   = startDate.ToString("yyyy-MM-ddTHH:mm:ssZ"),
                    Plan        = new PlanWithId()
                    {
                        Id = Convert.ToString(plan.PayPalPlanId)
                    },
                    Payer = new Payer()
                    {
                        PaymentMethod = "paypal"
                    }
                };


                // Send the agreement to PayPal
                var client  = _clientFactory.GetClient();
                var request = new AgreementCreateRequest()
                              .RequestBody(agreement);
                var result = await client.Execute(request);

                Agreement createdAgreement = result.Result <Agreement>();

                // Find the Approval URL to send our user to (also contains the token)
                var approvalUrl =
                    createdAgreement.Links.FirstOrDefault(
                        x => x.Rel.Equals("approval_url", StringComparison.OrdinalIgnoreCase));

                var token = QueryHelpers.ParseQuery(approvalUrl?.Href)["token"].First();

                // Save the token so we can match the returned request to our subscription.
                subscription.PayPalAgreementToken = token;


                _dbContext.SaveChanges();

                // Send the user to PayPal to approve the payment
                return(Redirect(approvalUrl.Href));
            }

            model.Product = product;
            return(View(model));
        }