简体   繁体   中英

PayPal .net REST API - Recurring billing agreements with additional one time payments

I am new to PayPal's REST API through .Net but i am stuck with the following problem: I can set up a recurring billing agreement and that all works fine. I can set up a simple payment and that works fine.

But how do you combine both in one step? As soon as you add a payment to a billing agreement (or the other way around) you get an invalid token.

Ideally we want to only direct the user to paypal once to authenticate. Setup a new billing agreement and do one admin charge payment at the same time. Any ideas?

Here is my code if it helps:

public string CreateOrder(MarketingFramework mf, HttpContext httpContext, User user, int packageid)
    {

        Group topgroup = user.RootGroup;

        //get the package
        var package = mf.Core.GetById<Package>(packageid);
        var admincharge =
            mf.Core.GetAll<SystemSettings>()
                .FirstOrDefault(s => s.Name == "Admin Charge" && s.Type == user.ProfileType)
                .Value;
        var cancelUrl = ConfigurationManager.AppSettings["Domain"] + "/Basket/Cancel.aspx";
        var confirmationUrl = ConfigurationManager.AppSettings["Domain"] + "/Basket/Confirm.aspx";


        //set the new purchase history date, if you had a package before and its not free, take that date and move it on a month
        //the date is set on the group everytime the IPN gateway makes a payment, therefore should always only be one month behind
        var newdate = DateTime.Now;
        if (topgroup.CurrentPackage.Package.Cost != 0) newdate = topgroup.CurrentPackage.DateAdded.AddMonths(1);

        //Authenticate with paypal
        var apiContext = Configuration.GetAPIContext();

        //cancel any current recurring packages
        if (topgroup.CurrentPackage.PaymentStatus == "Active Profile")
        {
            var plan = Plan.Get(apiContext, topgroup.CurrentPackage.ProfileId);
            plan.Delete(apiContext);
        }

        //if the package costs money eg: you not coming from a free account, an admin charge will apply
        //there is different prices for corporate or public in the settings table
        if (topgroup.CurrentPackage.Package.Cost != 0)
        {
            //calc the upgrade cost
            var totalamount = package.Cost - user.RootGroup.CurrentPackage.Package.Cost;
            if (totalamount < 0) totalamount = 0;

            var guid = Convert.ToString((new Random()).Next(100000));

            var itemList = new ItemList()
            {
                items = new List<Item>() 
                {
                    new Item()
                    {
                        name = "Administration charge",
                        currency = "GBP",
                        price = admincharge,
                        quantity = "1",
                        description = "Administration charge for upgrading package",
                        sku = package.Id.ToString()
                    }                ,
                    new Item()
                    {
                        name = "Upgrade charge",
                        description = "Difference in price when upgrading to a new package",
                        currency = "GBP",
                        price = totalamount.ToString(),
                        quantity = "1",
                        sku = package.Id.ToString()
                    }
                }
            };



            var payer = new Payer() { payment_method = "paypal" };
            var redirUrls = new RedirectUrls()
            {
                cancel_url = cancelUrl,
                return_url = confirmationUrl
            };

            var details = new Details()
            {
                tax = "0",
                shipping = "0",
                subtotal = (Convert.ToDecimal(totalamount) + Convert.ToDecimal(admincharge)).ToString()
            };

            var amount = new Amount()
            {
                currency = "GBP",
                total = details.subtotal,
                details = details
            };

            var transactionList = new List<Transaction>();

            transactionList.Add(new Transaction()
            {
                description = "Proofanything transaction",
                invoice_number = "1", //TODO need to setup invoice numbering
                amount = amount,
                item_list = itemList
            });

            var payment = new Payment()
            {
                intent = "sale",
                payer = payer,
                transactions = transactionList,
                redirect_urls = redirUrls
            };

            ////setup the recurring payment
            var recurring = new Plan
            {
                name = "Payment plan",
                description = "Proofanything monthly package plan",
                type = "INFINITE",
                // Define the merchant preferences.
                // More Information: https://developer.paypal.com/webapps/developer/docs/api/#merchantpreferences-object
                merchant_preferences = new MerchantPreferences()
                {
                    setup_fee = GetCurrency(admincharge),
                    return_url = confirmationUrl,
                    cancel_url = cancelUrl,
                    auto_bill_amount = "YES",
                    initial_fail_amount_action = "CONTINUE",
                    max_fail_attempts = "0"
                },
                payment_definitions = new List<PaymentDefinition>
                {
                    new PaymentDefinition()
                    {
                        name = package.Name,
                        type = "REGULAR",
                        frequency = "MONTH",
                        frequency_interval = "1",
                        amount = GetCurrency(package.Cost.ToString()),
                        cycles = "0"
                    },

                }
            };


            ////create the payments and plan
            var createdPlan = recurring.Create(apiContext);
            var createdPayment = payment.Create(apiContext);


            //redirect to paypal for approval
            return createdPayment.GetApprovalUrl();

It sounds like you want setup_fee available in the merchant_preferences , which can be set directly on the billing plan , or through override_merchant_preferences on the billing agreement . The setup_fee is a one time payment processed at execution of the billing agreement.

Sorry I can't help you with any .net specifics for that. All of my PayPal work has been through php.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM