You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Feb 2, 2022. It is now read-only.
As I already suspected in #189. I believe there is something wrong with the current way of prorating/reimbursing. To give a small summary, we have the following requirements for our subscriptions:
One invoice (the day does not matter, may be a fixed date, may also be variable based on the day an organization subscribed)
Variable quantity (for every user that registers for an organization, we increment the subscription quantity)
Multiplan (currently we create a new subscription for every chosen module, so an organization would get multiple invoices if we were to run Cashier::run() everyday)
Variable quantity is something that's built into cashier, so no problems there. One invoice can be fixed by running Cashier::run() once per month (#65). All due order items will be processed into one invoice. However, the quantity does result in wrong reimbursement. More info on our situation can be found in #189, but I've also created a litte schema to further clarify what currently happens:
If I'm correct, we miss out on the red marked area which is never paid for since the organization does not pay at the start of this cycle, but on the end. I believe the problem should be tackled in these lines of code:
/**
* Wrap up the current billing cycle, apply modifications to this subscription and start a new cycle.
*
* @param \Closure $applyNewSettings
* @param \Carbon\Carbon|null $now
* @param bool $invoiceNow
* @return \Laravel\Cashier\Subscription
*/
public function restartCycleWithModifications(\Closure $applyNewSettings, ?Carbon $now = null, $invoiceNow = true)
{
$now = $now ?: now();
return DB::transaction(function () use ($applyNewSettings, $now, $invoiceNow) {
// Wrap up current billing cycle
$this->removeScheduledOrderItem();
$reimbursement = $this->reimburseUnusedTime($now);
$orderItems = (new OrderItemCollection([$reimbursement]))->filter();
// Apply new subscription settings
call_user_func($applyNewSettings);
if ($this->onTrial()) {
// Reschedule next cycle's OrderItem using the new subscription settings
$orderItems[] = $this->scheduleNewOrderItemAt($this->trial_ends_at);
} else { // Start a new billing cycle using the new subscription settings
// Reset the billing cycle
$this->cycle_started_at = $now;
$this->cycle_ends_at = $now;
// Create a new OrderItem, starting a new billing cycle
$orderItems[] = $this->scheduleNewOrderItemAt($now);
}
$this->save();
if ($invoiceNow) {
$order = Order::createFromItems($orderItems);
$order->processPayment();
}
return $this;
});
}
The $this->reimburseUnusedTime($now) should maybe check whether the 'used time' has already been charged and otherwise leave an orderItem for this short cycle instead of reimbursing the time left. What do you think @sandervanhooft?
The text was updated successfully, but these errors were encountered:
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
As I already suspected in #189. I believe there is something wrong with the current way of prorating/reimbursing. To give a small summary, we have the following requirements for our subscriptions:
Cashier::run()
everyday)Variable quantity is something that's built into cashier, so no problems there. One invoice can be fixed by running
Cashier::run()
once per month (#65). All due order items will be processed into one invoice. However, the quantity does result in wrong reimbursement. More info on our situation can be found in #189, but I've also created a litte schema to further clarify what currently happens:If I'm correct, we miss out on the red marked area which is never paid for since the organization does not pay at the start of this cycle, but on the end. I believe the problem should be tackled in these lines of code:
The
$this->reimburseUnusedTime($now)
should maybe check whether the 'used time' has already been charged and otherwise leave an orderItem for this short cycle instead of reimbursing the time left. What do you think @sandervanhooft?The text was updated successfully, but these errors were encountered: