Search code examples
braintree

Without proration enabled, any changes made to a customer’s subscription mid-cycle goes into effect immediately


During the implementation of recurring payments using Braintree I encountered a problem.

In documentation I can read: “Without proration enabled, any changes made to a customer’s subscription mid-cycle will go into effect at the beginning of the next cycle.” (https://articles.braintreepayments.com/guides/recurring-billing/recurring-advanced-settings#proration)

But if I edit the subscription to a lower dollar amount in the middle of a billing cycle (without proration on downgrades enabled) e.g. from $100 to $80 and then I edit the subscription to a higher dollar amount (with proration on upgrades enabled) e.g. to $90, the gateway will immediately charge me some amount.

In this situation, I would expect that gateway will not generate any transaction, because downgrade should be effective at the beginning of the next cycle and new subscription price ($90) is lower than initial subscription price (100$).

How can I then reach scenario when transaction on proration upgrade will be generated only if new subscription price is higher than maximum subscription price at the current billing cycle?


Solution

  • I'm a developer at Braintree.

    If you kept proration on for both price decreases and increases, in the example you give you would see a credit applied to the subscription balance for the decrease, and then a charge applied against the balance for the increase. If the charge exceeds the subscription balance credit, then your customer would be charged.

    A subscription will not be charged in the middle of a billing cycle unless you choose to prorate charges. You could create the scenario you want with logic similar to below. Code snippets are in Ruby since you didn't specify what client library you were using.

    First look up the subscription you want to update and find the start date of the current billing period:

    subscription = Braintree::Subscription.find("subscription_id")
    billing_period_start_date = Date.parse(subscription.billing_period_start_date) # convert String to Date
    

    Then iterate over the status_history events of the subscription, and update the billing_period_max_price if the history event took place after the beginning of this billing cycle and the billing_period_max_price is greater than the previous one:

    billing_period_max_price = 0.0
    
    subscription.status_history.each do |history_event|
       event_date = Date.parse(history_event.timestamp.strftime('%Y/%m/%d')) # convert Time to Date
       event_price = history_event.price.to_f
       if event_date >= billing_period_start_date && billing_period_max_price < event_price
           billing_period_max_price = event_price
       end
    end
    

    Finally, if the billing_period_max_price is less than what you want to change the subscription price to, prorate the charges:

    Subscription.update(
      "subscription_id", 
      :price => "yourHigherPrice",
      :options => { :prorate_charges => true }
    )
    

    If you have additional questions, feel free to reach out to Braintree support.