This section will guide you through some common subscription management scenarios.

Updating subscriptions

The following details can be updated for eligible Pending and Active subscriptions:

  • Subscription ID
  • Price
  • Plan*
  • Payment method, using either:
  • Add-on and discount details
  • Number of billing cycles
  • Merchant account
  • Descriptor

*If you update the subscription's plan, the subscription will not inherit the new plan's price. Additionally, you can only update to a plan with the same billing cycle (e.g. you can't update from a yearly plan to a monthly plan and vice versa).

important

Merchants operating in the European Union must give customers 7 business days’ notice before changing the price of their recurring billing plan; 7 business days’ notice is also required before billing customers if it has been 6+ months since their last payment. If you don’t operate in the EU, these notices aren't required (but they're still good practice).

Ruby
Copy
Copied
result = Braintree::Subscription.update(
  "m476", # id of subscription to update
  :id => "new_id",
  :payment_method_token => "new_payment_method_token",
  :price => "14.00",
  :plan_id => "new_plan",
  :merchant_account_id => "new_merchant_account"
)

If the subscription can't be found, it will raise a Braintree::NotFoundError.

Since merchant_account_id determines currency, updating the merchant account may change which currency the subscription is processed in.

note

Canceled and Expired subscriptions can't be changed. Select details can be updated for Past Due subscriptions.

Add-ons and discounts

When updating a subscription, you can modify the add-ons and discounts in 3 ways:

  • New add-ons/discounts can be added
  • Existing add-ons/discounts associated with the subscription can be updated
  • Existing add-ons/discounts associated with the subscription can be removed
Ruby
Copy
Copied
result = Braintree::Subscription.update(
  "the_subscription_id",
  :add_ons => {
    :add => [
      {
        :inherited_from_id => "add_on_id_1",
        :amount => BigDecimal.new("25.00")
      }
    ],
    :update => [
      {
        :existing_id => "the_add_on_id_2",
        :amount => BigDecimal.new("50.00")
      }
    ],
    :remove => ["the_add_on_id_3"]
  },
  :discounts => {
    :add => [
      {
        :inherited_from_id => "discount_id_1",
        :amount => BigDecimal.new("7.00")
      }
    ],
    :update => [
      {
        :existing_id => "discount_id_2",
        :amount => BigDecimal.new("15.00")
      }
    ],
    :remove => ["discount_id_3"]
  }
)
note

You can only add an add-on or discount to a subscription once. If you'd like to apply an add-on or discount to a subscription several times, you can pass quantity when creating or updating the add-on/discount.

See additional examples of how to update or remove add-ons and discounts on a subscription.

Proration

You can use proration to charge or credit a customer if a change is made to the subscription price in the middle of a billing cycle. Enabling proration adjusts the price based on when the change took place in the billing cycle, and it charges the customer the newly-calculated rate immediately. Without proration enabled, any changes made to a customer’s subscription mid-cycle will go into effect at the beginning of the next cycle.

Proration can be configured to run automatically on upgrades and/or downgrades in the Control Panel, or you can pass the option prorate_charges as true.

By default, if the transaction for the prorated amount fails, the update to the subscription no longer goes through. If you would like to continue with the update to the subscription and add the prorated amount to the balance even though the transaction failed, you can set this preference in the Control Panel or pass the option revert_subscription_on_proration_failure = false.

Past Due subscriptions

A subscription's balance represents the amount of outstanding charges associated with that subscription. If a customer’s payment method fails or is declined, their subscription status will change to Past Due, and the subscription's balance is incremented by the amount of the transaction that failed. This amount includes the subscription base price as well as any associated add-ons and/or discounts.

If the subscription has add-ons and discounts with a specified number of billing cycles, the number of billing cycles are also reflected in the subscription's balance. For example, let's say that a subscription was created with these settings:

Subscription price: $12 for 12 billing cycles
Add-on price: $10 for 2 billing cycles

The subscription and the first add-on were charged successfully when it was created, but it is now 2 billing cycles past due. The balance is $34.

2 failed billing cycles, $12 each = $24
1 failed billing cycle for the add-on charge for $10
Total balance = $34

Since the add-on was designated to apply for 2 billing cycles and we already had one successful billing cycle, it will only count one billing cycle for the add-on in the balance. This same logic also applies to discounts.

The balance on Past Due subscriptions will continue to increase every billing cycle—either indefinitely or until the number of cycles in the subscription is reached.

Updating Past Due subscriptions

When updating a subscription that is Past Due, you can only update fields that do not change the price:

*When you update a Past Due subscription's payment method and you have proration enabled, the subscription will be automatically retried.

Retry logic

We will automatically attempt to charge past due subscriptions at the beginning of each new billing cycle. You can also customize our retry logic in the Control Panel if you would like to charge past due subscriptions in-between billing cycles. Depending on the processor response code, some declines are not retried because they suggest that it's unlikely the transaction will ever be successful.

A subscription's balance will only be adjusted by our retry logic at the beginning of a new billing cycle. Automatic retry attempts within a billing cycle do not affect the subscription's balance.

You can also retry transactions manually, either on a one-off basis or as a part of your own recurring logic.

Negative balance

A negative balance indicates that credit is owed to the customer on that subscription. A subscription's balance can go into the negative if you have configured your processing options to allow proration on downgrades. If a subscription has a negative balance that is enough to cover the charge, the subscription will bill successfully without actually charging the payment method.

Retrying transactions manually

important

When handling declined transactions, keep in mind that there are rules around retrying recurring transactions.

By default, we will use the subscription balance when retrying the transaction. If you would like to use a different amount you can optionally specify the amount for the transaction.

A successful manual retry of a past due subscription will always reduce the balance of that subscription to $0, regardless of the amount of the retry.

Submitting for settlement

When retrying a declined transaction via the API, pass true in the argument to automatically submit the transaction for settlement if the retry request is successful:

Ruby
Copy
Copied
retry_result = Braintree::Subscription.retry_charge(
  subscription.id,
  "24.00",
  true
)
availability

Submitting transactions for settlement in the Braintree::Subscription.retry_charge() call is supported in the latest versions of our server SDKs. In older versions, you must submit for settlement separately.

When the transaction is authorized, the subscription status will return to Active unless the number of billing cycles in the subscription has been reached. If the subscription has no further billing cycles, it will become Expired.

Refunding a subscription

Refunds for subscriptions work the same as refunds for individual transactions. You can only issue a refund against an existing sale transaction, and that transaction must have a status of settled or settling.

However, if you do not want to refund the full amount of an existing sale transaction, you can specify the amount of the refund. For example, if your customer has an annual subscription and you wish to refund them for 6 months, you would issue a refund against the original transaction for half the sale amount.

To issue a refund via the API, use Braintree::Transaction.refund(). You can also issue a refund within the Control Panel. If you do not want to continue charging the customer for their subscription in the future, be sure to cancel the subscription as well.

See also

Next: Testing and Go Live →

Still have questions?

If you can’t find an answer, contact our Support team.