Open evertjanMlbrgn opened 1 month ago
Hi @evertjanMlbrgn,
It would be nice to have an option to say that tax is included in the one time charge.
That is similar to the feature requested in #214. I will note it down. However, atm it's not possible.
It would be nice to be able to get a list of all one time charges (processed, and unprocessed)
I'll note that down on the feature wishlist. As a workaround you can query all OrderItem
s that have no orderable
relationship OrderItem::whereNull(['orderable_type', 'orderable_id'])->get()
.
Would it be possible to add a one time charge to the next subscription invoice instead of creating a new invoice?
If you want the user to pay at the moment the one time charge is due, then you can't delay the invoice creation. Therefore it's not possible to just add the one time charge to another invoice.
Depending on your use case you could achieve such a functionality by not using the Charge functionality of this package, but rather store the charge that will be added to the order of the Subscription separately. Then you could add a Preprocessor
which checks if there are any pending charges and if so adds them to the order.
// create ChargeItem and mark it as process_at the end of the current subscription period
$item = new ChargeItem([
'description' => 'Monthly subscription',
'quantity' => 1,
'unit_price' => new Money(1000, new Currency('USD')),
'process_at' => $user->subscription('default')->ends_at,
]);
$item->ownable()->associate($user);
$item->save();
use Laravel\Cashier\Order\BaseOrderItemPreprocessor;
use Laravel\Cashier\Order\OrderItem;
use Laravel\Cashier\Order\OrderItemCollection;
class AddPendingChargesToOrder extends BaseOrderItemPreprocessor
{
/**
* @param \Laravel\Cashier\Order\OrderItemCollection $items
* @return \Laravel\Cashier\Order\OrderItemCollection
*/
public function handle(OrderItemCollection $items)
{
// You can add, remove or modify order items here.
// Each order item relates to 1 line on the invoice.
$owner = $items->owners()->first();
if ($owner->hasPendingCharges()) {
$chargeOrderItems = $owner
->pendingCharges
->map->toOrderItem();
$items = $items->merge($chargeOrderItems);
}
return $items;
}
}
class ChargeItem extends Model
{
public function ownable()
{
return $this->morphTo();
}
public function toOrderItem(array $overrides = []): OrderItem
{
return Cashier::$orderItemModel::make(array_merge([
'owner_type' => $this->ownable_type,
'owner_id' => $this->ownable_id,
'description' => $this->description,
'quantity' => $this->quantity,
'currency' => $this->unitPrice->getCurrency()->getCode(),
'unit_price' => $this->unitPrice->getAmount(),
'tax_percentage' => $this->taxPercentage,
'process_at' => $this->process_at,
], $overrides));
}
}
class User extends Model
{
public function pendingCharges(): HasMany
{
return $this->morphMany(ChargeItem::class, 'ownable')
->where('process_at', '>', Carbon::now());
}
}
If you have further questions, please let me know!
@Naoray Thank you very much i'm able to get the one time charges and i will try to implement the code you provided :-)
You are welcome @evertjanMlbrgn!
Don't forget to add your custom preprocessor class to the cashier_plans.defaults.order_item_preprocessors
and make sure it's before the PersistOrderItems
.
I saw: https://github.com/mollie/laravel-cashier-mollie/issues/122
Thank you very much.