mollie / laravel-cashier-mollie

Official Mollie integration for Laravel Cashier
https://www.cashiermollie.com/
MIT License
137 stars 44 forks source link

Subscription with payment afterwards #259

Closed evertjanMlbrgn closed 3 months ago

evertjanMlbrgn commented 3 months ago

Our customer wants to use subscription based product delivery.

I’ve noticed that the so called “first payment amount” will only be used when a customer subscribes to a trial. That’s not really a problem in our case, since customers in my country have the legal right to cancel any subscription within 14 days of subscribing. Since products will be delivered as soon as a customer subscribes, I want to make sure that at least one order is paid should the customer decide that they don’t want the subscription within 14 days. How would I implement the described situation?

I also want the customers to get their first real bill (not the initial first payment amount payment) after a month. It’s custom in my country to pay afterwards.

Simply said: I subscribe today, I get my products within a few days and pay about a month after I initially subscribed. Then going forward this repeats, so first I get my products then afterwards i get my bill.

Maybe a tricky question, but maybe not.

Naoray commented 3 months ago

Hi again @evertjanMlbrgn,

I’ve noticed that the so called “first payment amount” will only be used when a customer subscribes to a trial.

Yes. I've it on my todo list to write some documentation regarding the "first payment amount".

Since products will be delivered as soon as a customer subscribes, I want to make sure that at least one order is paid should the customer decide that they don’t want the subscription within 14 days. How would I implement the described situation?

I am not sure if I understand the issue here. Why don't you just start a subscription without trial? Then the subscription's price will be due on the first payment and you don't have to check for a paid order.

I also want the customers to get their first real bill (not the initial first payment amount payment) after a month. It’s custom in my country to pay afterwards.

That sounds like you want to use 'metered billing' or at least a variant of it. Another user asked about metered billing already. Take a look at the answer I gave here.

You can implement metered billing by configuring the order_item_preprocessors in your cashier_plans config. A MeteredBillingPreprocessor could look something like the following:

use Laravel\Cashier\Order\BaseOrderItemPreprocessor;
use Laravel\Cashier\Order\OrderItem;
use Laravel\Cashier\Order\OrderItemCollection;

class MeteredBillingPreprocessor 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.

        // For metered billing, you typically:
        // 1. fetch metered data from within your app
        // 2. apply it to the order items
        // 3. if necessary, notify the meters that the costs were incurred/reset the meters

        $owner = $items->owners()->first();

        $meters = $owner->getMeters();
        $meterItems = $meters->map(function ($meter) {
            return OrderItem::make([
                'process_at' => now(),
                'description' => $meter->description,
                'currency' => $meter->currency,
                'unit_price' => $meter->unit_price,
                'quantity' => $meter->quantity,
                'tax_percentage' => $this->tax_percentage, 
            ]);
        });

        $items = $items->concat($meterItems);

        $owner->resetMeters(); // optionally put this in a separate ResetMetersPreprocessor right after the PersistOrderItemsPreprocessor

        return $items;
    }
}

Please keep in mind that, currently, adding preprocessors to the first payment is not supported. Therefore, you may still need to reimburse the user for any overpaid amount during the first billing cycle. Additionally, scheduling the payment at the end of a cycle is not mandatory for metered billing, and it's not currently possible with Laravel-Cashier-Mollie. Nonetheless, you can still use metered billing by asking users to pay a fixed upfront amount and adding the metered component to the invoice for the next billing cycle. We're actively working on ways to make these processes easier in the next versions of our package.

Originally posted by @Naoray in https://github.com/mollie/laravel-cashier-mollie/issues/151#issuecomment-1432726192

Note: You might be able to get away with not refunding but instead enable a one month trial.

evertjanMlbrgn commented 3 months ago

Thanks for your reply, my customer changed his mind and wants to bill immediately without a trial, just like you suggested.