Skip to main content

Proration

When a subscriber changes plans mid-cycle, Subscribd calculates the appropriate billing adjustment using one of three proration strategies. The strategy can be set globally in config or overridden per swap.

Strategies

StrategyBehaviour
nowCharge or credit immediately at the moment of the swap. This is the default.
renewalApply the price difference at the next renewal. No immediate charge or credit.
noneNo proration — the new plan price takes effect at the next renewal with no adjustment.

Setting the default strategy

// config/subscribd.php
'proration' => [
    'default_strategy' => env('SUBSCRIBD_PRORATION_STRATEGY', 'now'),
],

Overriding per swap

Pass a prorate option to SwapPlan to override the default for a single swap:
use Pixelworxio\Subscribd\Actions\SwapPlan;

// Immediate charge/credit
app(SwapPlan::class)->execute($subscription, $newPlan, ['prorate' => 'now']);

// Apply at next renewal
app(SwapPlan::class)->execute($subscription, $newPlan, ['prorate' => 'renewal']);

// No adjustment
app(SwapPlan::class)->execute($subscription, $newPlan, ['prorate' => 'none']);

Native vs. Subscribd proration

Some gateways support native proration — the provider calculates and bills the adjustment directly. Others rely on Subscribd’s built-in ProrationEngine to compute and apply the credit or charge locally.
GatewayProration
StripeNative
PayPalSubscribd ProrationEngine
BraintreeSubscribd ProrationEngine
PaddleSubscribd ProrationEngine
FastSpringSubscribd ProrationEngine
SquareSubscribd ProrationEngine
FakeSubscribd ProrationEngine
When a gateway uses native proration, Subscribd passes the prorate strategy to the gateway’s API call and respects the gateway’s calculated amounts. When using the ProrationEngine, Subscribd calculates the adjustment locally and creates a credit or debit line item on the next invoice.

How the ProrationEngine calculates adjustments

For a now swap mid-cycle, the engine:
  1. Calculates remaining days in the current billing cycle
  2. Computes the per-day rate of the old plan: old_amount / days_in_cycle
  3. Computes the per-day rate of the new plan: new_amount / days_in_cycle
  4. The credit for unused time = old_rate × remaining_days
  5. The charge for the new plan = new_rate × remaining_days
  6. Net = charge − credit; positive values are billed immediately, negative values become credits on the next invoice
For a renewal swap, no calculation is performed at swap time. The new plan amount is billed in full at the next renewal date.

Previewing a proration

Calculate what a plan swap will cost before executing it:
use Pixelworxio\Subscribd\Actions\PreviewProration;

$preview = app(PreviewProration::class)->execute($subscription, $newPlan, 'now');

$preview->credit();      // Money — unused time on current plan
$preview->charge();      // Money — time on new plan
$preview->net();         // Money — net amount (positive = owed, negative = credit)
$preview->effectiveAt(); // Carbon — when the change takes effect
This is useful for building upgrade/downgrade confirmation UIs that show the customer exactly what they will be charged or credited.

Proration and coupons

Active coupons are applied to the prorated amount when Subscribd calculates the adjustment. If the subscription has a 100% off coupon active, the upgrade charge is zero regardless of proration strategy.

Multi-currency

All proration calculations are performed in the plan’s configured currency using the Money library. Currency conversion is not performed — both plans must use the same currency for a swap with proration to succeed. Swapping between plans in different currencies requires a none proration strategy.

Next steps