Create billing plans

You use billing plans and billing agreements to create an agreement for a recurring PayPal payment for goods or services.

A billing plan includes payment definitions and other details. A plan must include at least one regular payment definition and, optionally, a trial payment definition. Each definition determines how often and for how long a customer is charged.

A plan can specify a type, which indicates whether the payment definitions in the plan have a fixed or infinite number of payment cycles. The plan also defines merchant preferences including how much it costs to set up the agreement, the URLs where a customer can approve or cancel the agreement, and the action if the customer's initial payment fails.

By default, a plan is not active when you create it. To activate it, you update its state to ACTIVE.

For more information, see Billing Plans and Agreements.

To create a billing plan, complete these steps:

1. Define the billing plan object.
2. Create and activate the billing plan.

Define the billing plan object

The billing plan object defines the subscription plan, including the number of cycles, frequency of payment, any setup fees, and so on.

var billingPlanAttribs = {
  name: 'Food of the World Club Membership: Standard',
  description: 'Monthly plan for getting the t-shirt of the month.',
  type: 'fixed',
  payment_definitions: [{
    name: 'Standard Plan',
    type: 'REGULAR',
    frequency_interval: '1',
    frequency: 'MONTH',
    cycles: '11',
    amount: {
      currency: 'USD',
      value: '19.99'
    }
  }],
  merchant_preferences: {
    setup_fee: {
      currency: 'USD',
      value: '1'
    },
    cancel_url: 'http://localhost:3000/cancel',
    return_url: 'http://localhost:3000/processagreement',
    max_fail_attempts: '0',
    auto_bill_amount: 'YES',
    initial_fail_amount_action: 'CONTINUE'
  }
};
use PayPal\Api\ChargeModel;
use PayPal\Api\Currency;
use PayPal\Api\MerchantPreferences;
use PayPal\Api\PaymentDefinition;
use PayPal\Api\Plan;
use PayPal\Api\Patch;
use PayPal\Api\PatchRequest;
use PayPal\Common\PayPalModel;

// Create a new billing plan
$plan = new Plan();
$plan->setName('T-Shirt of the Month Club Plan')
  ->setDescription('Template creation.')
  ->setType('fixed');

// Set billing plan definitions
$paymentDefinition = new PaymentDefinition();
$paymentDefinition->setName('Regular Payments')
  ->setType('REGULAR')
  ->setFrequency('Month')
  ->setFrequencyInterval('2')
  ->setCycles('12')
  ->setAmount(new Currency(array('value' => 100, 'currency' => 'USD')));

// Set charge models
$chargeModel = new ChargeModel();
$chargeModel->setType('SHIPPING')
  ->setAmount(new Currency(array('value' => 10, 'currency' => 'USD')));
$paymentDefinition->setChargeModels(array($chargeModel));

// Set merchant preferences
$merchantPreferences = new MerchantPreferences();
$merchantPreferences->setReturnUrl('http://localhost:3000/processagreement')
  ->setCancelUrl('http://localhost:3000/cancel')
  ->setAutoBillAmount('yes')
  ->setInitialFailAmountAction('CONTINUE')
  ->setMaxFailAttempts('0')
  ->setSetupFee(new Currency(array('value' => 1, 'currency' => 'USD')));

$plan->setPaymentDefinitions(array($paymentDefinition));
$plan->setMerchantPreferences($merchantPreferences);
from paypalrestsdk import BillingPlan

billing_plan = BillingPlan({
  "name": "Testing1-Regular1",
  "description": "Create Plan for Regular",
  "type": "INFINITE",
  "payment_definitions": [{
    "name": "Standard Plan",
    "type": "REGULAR",
    "frequency_interval": "1",
    "frequency": "MONTH",
    "cycles": "0",
    "amount": {
      "currency": "USD",
      "value": "20"
    }
  }],
  "merchant_preferences": {
    "auto_bill_amount": "yes",
    "cancel_url": "http://localhost:3000/cancel",
    "initial_fail_amount_action": "continue",
    "max_fail_attempts": "1",
    "return_url": "http://localhost:3000/processagreement",
    "setup_fee": {
      "currency": "USD",
      "value": "25"
    }
  }
})
# Plan definition
plan = Plan.new({
  :name => 'Food of the World Club Membership: Standard',
  :description => 'Monthly plan for getting the t-shirt of the month.',
  :type => 'fixed',
  :payment_definitions => [{
    :name => 'Standard Plan',
    :type => 'REGULAR',
    :frequency_interval => '1',
    :frequency => 'MONTH',
    :cycles => '11',
    :amount => {
      :currency => 'USD',
      :value => '19.99'
    }
  }],
  :merchant_preferences => {
    :setup_fee => {
      :currency => 'USD',
      :value => '1'
    },
    :cancel_url => 'http://localhost:3000/cancel',
    :return_url => 'http://localhost:3000/processagreement',
    :max_fail_attempts => '0',
    :auto_bill_amount => 'YES',
    :initial_fail_amount_action => 'CONTINUE'
  }
})
import java.util.ArrayList;
import java.util.List;

import com.paypal.api.payments.ChargeModels;
import com.paypal.api.payments.Currency;
import com.paypal.api.payments.MerchantPreferences;
import com.paypal.api.payments.PaymentDefinition;
import com.paypal.api.payments.Plan;
import com.paypal.base.rest.APIContext;
import com.paypal.base.rest.PayPalRESTException;

// Build Plan object
Plan plan = new Plan();
plan.setName("T-Shirt of the Month Club Plan");
plan.setDescription("Template creation.");
plan.setType("fixed");

// Payment_definitions
PaymentDefinition paymentDefinition = new PaymentDefinition();
paymentDefinition.setName("Regular Payments");
paymentDefinition.setType("REGULAR");
paymentDefinition.setFrequency("MONTH");
paymentDefinition.setFrequencyInterval("1");
paymentDefinition.setCycles("12");

// Currency
Currency currency = new Currency();
currency.setCurrency("USD");
currency.setValue("20");
paymentDefinition.setAmount(currency);

// Charge_models
ChargeModels chargeModels = new com.paypal.api.payments.ChargeModels();
chargeModels.setType("SHIPPING");
chargeModels.setAmount(currency);
ListChargeModels chargeModelsList = new ArrayListChargeModels();
chargeModelsList.add(chargeModels);
paymentDefinition.setChargeModels(chargeModelsList);

// Payment_definition
ListPaymentDefinition paymentDefinitionList = new ArrayListPaymentDefinition();
paymentDefinitionList.add(paymentDefinition);
plan.setPaymentDefinitions(paymentDefinitionList);

// Merchant_preferences
MerchantPreferences merchantPreferences = new MerchantPreferences();
merchantPreferences.setSetupFee(currency);
merchantPreferences.setCancelUrl("http://www.cancel.com");
merchantPreferences.setReturnUrl("http://www.return.com");
merchantPreferences.setMaxFailAttempts("0");
merchantPreferences.setAutoBillAmount("YES");
merchantPreferences.setInitialFailAmountAction("CONTINUE");
plan.setMerchantPreferences(merchantPreferences);
var plan = new Plan
{
  name = "T-Shirt of the Month Club Plan",
  description = "Monthly plan for getting the t-shirt of the month.",
  type = "fixed",

  payment_definitions = new List
  {
    new PaymentDefinition()
    {
      name = "Trial Plan",
      type = "TRIAL",
      frequency = "MONTH",
      frequency_interval = "1",
      amount = GetCurrency("9.99"),
      cycles = "1",
      charge_models = new List
      {
        new ChargeModel()
        {
          type = "TAX",
          amount = GetCurrency("1.65")
        },
        shippingChargeModel
      }
    },

    new PaymentDefinition
    {
      name = "Standard Plan",
      type = "REGULAR",
      frequency = "MONTH",
      frequency_interval = "1",
      amount = GetCurrency("19.99"),
      cycles = "11",
      charge_models = new List
      {
        new ChargeModel
        {
          type = "TAX",
          amount = GetCurrency("2.47")
        }
      }
    }
  },

  merchant_preferences = new MerchantPreferences()
  {
    setup_fee = GetCurrency("1"),
    return_url = httpContext.Request.Url.ToString(),
    cancel_url = httpContext.Request.Url.ToString() + "?cancel",
    auto_bill_amount = "YES",
    initial_fail_amount_action = "CONTINUE",
    max_fail_attempts = "0"
  }
};

Create and activate billing plan

Use the billing plan object to create and activate the billing plan. Then, you can create billing agreements against the billing plan.

paypal.billingPlan.create(billingPlanAttribs, function (error, billingPlan){
  var billingPlanUpdateAttributes;

  if (error){
    console.error(JSON.stringify(error));
    throw error;
  } else {
    // Create billing plan patch object
    billingPlanUpdateAttributes = [{
      op: 'replace',
      path: '/',
      value: {
        state: 'ACTIVE'
      }
    }];

    // Activate the plan by changing status to active
    paypal.billingPlan.update(billingPlan.id, billingPlanUpdateAttributes, function(error, response){
      if (error){
        console.error(JSON.stringify(error));
        throw error;
      } else {
        console.log('Billing plan created under ID: ' + billingPlan.id);
      }
    });
  }
});
//create plan
try {
  $createdPlan = $plan->create($apiContext);

  try {
    $patch = new Patch();
    $value = new PayPalModel('{"state":"ACTIVE"}');
    $patch->setOp('replace')
      ->setPath('/')
      ->setValue($value);
    $patchRequest = new PatchRequest();
    $patchRequest->addPatch($patch);
    $createdPlan->update($patchRequest, $apiContext);
    $plan = Plan::get($createdPlan->getId(), $apiContext);

    // Output plan id
    echo $plan->getId();
  } catch (PayPal\Exception\PayPalConnectionException $ex) {
    echo $ex->getCode();
    echo $ex->getData();
    die($ex);
  } catch (Exception $ex) {
    die($ex);
  }
} catch (PayPal\Exception\PayPalConnectionException $ex) {
  echo $ex->getCode();
  echo $ex->getData();
  die($ex);
} catch (Exception $ex) {
  die($ex);
}
# Create billing plan
if billing_plan.create():
  print("Billing Plan [%s] created successfully" % billing_plan.id)

  # Activate billing plan
  if billing_plan.activate():
    billing_plan = BillingPlan.find(billing_plan.id)
    print("Billing Plan [%s] state changed to %s" % (billing_plan.id, billing_plan.state))
  else:
    print(billing_plan.error)
else:
  print(billing_plan.error)
# Create plan
if plan.create
  # Plan update activation object
  plan_update = {
    :op => 'replace',
    :path => '/',
    :value => {
      :state => 'ACTIVE'
    }
  }

  # Activate plan
  if plan.update(plan_update)
    puts("Billing plan activated with ID [#{plan.id}]")
  else
    logger.error payment.error.inspect
  end
else
  logger.error payment.error.inspect
end
try {
  // Create payment
  Plan createdPlan = plan.create(apiContext);
  System.out.println("Created plan with id = " + createdPlan.getId());
  System.out.println("Plan state = " + createdPlan.getState());

  // Set up plan activate PATCH request
  ListPatch patchRequestList = new ArrayListPatch();
  Map<String, String> value = new HashMap<String, String>();
  value.put("state", "ACTIVE");

  // Create update object to activate plan
  Patch patch = new Patch();
  patch.setPath("/");
  patch.setValue(value);
  patch.setOp("replace");
  patchRequestList.add(patch);

  // Activate plan
  createdPlan.update(apiContext, patchRequestList);
  System.out.println("Plan state = " + createdPlan.getState());
} catch (PayPalRESTException e) {
  System.err.println(e.getDetails());
}
var createdPlan = plan.Create(apiContext);

var patchRequest = new PatchRequest()
{
  new Patch()
  {
    op = "replace",
    path = "/",
    value = {
      "state": "ACTIVE"
    }
  }
};

createdPlan.Update(apiContext, patchRequest);

The first call creates the billing plan by passing in the definition object that was created in the first step.

Next, use a PATCH request to activate the plan. In the PATCH request, set the state of the billing plan to active. To update the billing plan, include the billing plan object in the PATCH request.

The billing plan is now active and ready to use. To create billing agreements from the plan, store and use the billing plan ID.

Next

Create billing agreements.

Additional information