Skip to content
This repository has been archived by the owner on Feb 2, 2022. It is now read-only.

Why is my preprocessor for variable prices not working correctly? #254

Open
zqstack opened this issue Sep 25, 2020 · 2 comments
Open

Why is my preprocessor for variable prices not working correctly? #254

zqstack opened this issue Sep 25, 2020 · 2 comments

Comments

@zqstack
Copy link

zqstack commented Sep 25, 2020

Dear Developer,

Do you know why my preprocessor for variable prices is not working correctly?

It seems to work for swapping plans, but for new subscriptions, it keeps asking for the original price. Am I missing something?

Here is my code:

cashier_plans.php:

'my_plan' => [
        'amount' => [
            'value' => '3.00',
            'currency' => 'EUR',
        ],

        'interval' => '1 month',
        'description' => 'My plan payment',

        'order_item_preprocessors' => [
            ProcessCoupons::class,

            MyPreprocessor::class,

            PersistOrderItems::class,
        ],
    ],

MyPreprocessor.php:

<?php

namespace App\PaymentPreprocessors;

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

use Laravel\Cashier\Order\Contracts\PreprocessesOrderItems;

class MyPreprocessor extends BaseOrderItemPreprocessor implements PreprocessesOrderItems
{
    /**
     * @param \Laravel\Cashier\Order\OrderItemCollection $items
     * @return \Laravel\Cashier\Order\OrderItemCollection
     */
    public function handle( OrderItemCollection $items )
    {
        \Log::info( 'HANDLE' );

        $result = new OrderItemCollection;

        $items->each( function( OrderItem $item ) use ( &$result )
        {
            if( $item->orderableIsSet() )
            {
                //$coupons = $this->getActiveCoupons( $item->orderable_type, $item->orderable_id );
                //$result = $result->concat( $coupons->applyTo( $item ) );

                \Log::info( 'item' );
                \Log::info( $item );

                if( !is_null( $item->unit_price ) )
                {
                    \Log::info( 'item->unit_price' );
                    \Log::info( $item->unit_price );

                    $item->unit_price = 500;
                    $item->save();

                    \Log::info( 'NEW item->unit_price' );
                    \Log::info( $item->unit_price );
                }

                $result->push( $item );
            }
            else
            {
                $result->push( $item );
            }
        });

        return $result;
    }

    public static function preprocessOrderItem( OrderItem $item )
    {
        \Log::info( 'PREPROCESSORDERITEM' );

        \Log::info( 'item' );
        \Log::info( $item );

        if( !is_null( $item->unit_price ) )
        {
            \Log::info( 'item->unit_price' );
            \Log::info( $item->unit_price );

            $item->unit_price = 500;
            $item->save();

            \Log::info( 'NEW item->unit_price' );
            \Log::info( $item->unit_price );
        }

        $result->push( $item );
    }
}

Thank you for your help!

zqstack

@zqstack zqstack changed the title Why is my preprocessor for variable prices not working? Why is my preprocessor for variable prices not working correctly? Sep 25, 2020
@lexdewilligen
Copy link
Contributor

First of all, it would help a lot if you remove all of your logs from the code. Second, I think you don't need to implement PreprocessesOrderItems. That's up to cashier. You just need to extend BaseOrderItemPreprocessor and write the logic for handle()to modify your OrderItems. And finally, to solve your isssue. Preprocessors are not invoked when creating a new subscription, as you can see in the create() method of a MandatedSubscriptionBuilder:

    /**
     * Create a new Cashier subscription.
     *
     * @return Subscription
     * \Laravel\Cashier\Exceptions\CouponException
     * @throws \Laravel\Cashier\Exceptions\InvalidMandateException
     */
    public function create()
    {
        $this->owner->guardMollieMandate();
        $now = now();

        return DB::transaction(function () use ($now) {
            $subscription = $this->makeSubscription($now);
            $subscription->save();

            if($this->coupon) {
                if($this->validateCoupon) {
                    $this->coupon->validateFor($subscription);

                    if($this->handleCoupon) {
                        $this->coupon->redeemFor($subscription);
                    }
                }
            }

            $subscription->scheduleNewOrderItemAt($this->nextPaymentAt);
            $subscription->save();

            $this->owner->cancelGenericTrial();

            return $subscription;
        });
    }

The preprocessors are only invoked when processing a subscription right before a mollie payment is created. You could therefore start a subscription with a price of your choice and always change the unit_price whenever such a subscription would be billed using the preprocessor you've created.

@temo87
Copy link

temo87 commented Oct 13, 2020

I have a similar situation and thanks @lexdewilligen you for the tips, I have the PaymentPreprocessors working now.

One question remains. How can I change the price of the firstPayment?
I have a custom plan in my cashier_plans.php but the price is dynamic and is per client different. So i would like to change the amount of the firstPayment per user.

I've found some more information in this thread #177
But i cannot find out how to use the FirstPaymentBuilder manually in a controller.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants