Search code examples
phplaravellaravel-4laravel-cashier

L4.2 Extend/override Cashier to add Tax feature


I am using Laravel 4.2 with Cashier and I need to modify its protected function buildPayload() but I don't want to do it directly in the vendor file as I could break the code when I composer Update... How should I proceed to override this function with my own Logic ?

I currently use Cashier in one of my controller by doing:

$user->subscription('testplan')
                    ->create(Input::get('stripeToken'), [
                        'email' => 'email@email.com,
                    ]);

But I want to add a withTax() parameters... Like so:

$user->subscription('testplan')
                        ->withTax(10)
                        ->create(Input::get('stripeToken'), [
                            'email' => 'email@email.com,
                        ]);

I already know how to do it directly in the StripeGateway.php file but it's bad practice...

I know that I need to add:

protected $taxPercent = 0;

    public function withTax($tax)
    {
        $this->taxPercent = $tax;

        return $this;
    }

    protected function buildPayload()
    {
        $payload = [
            'plan' => $this->plan, 'prorate' => $this->prorate,
            'quantity' => $this->quantity, 'trial_end' => $this->getTrialEndForUpdate(),
            'tax_percent' => $this->taxPercent,
        ];

        return $payload;
    }

What I don't know is how to add this code not directly in the Cashier Original file.


Solution

  • I managed to find how to do it by myself, it's first time I do this kind of thing... Please correct me if my method is wrong!

    First:

    I created a Folder named Lib\Cashier like so: laravel/app/Lib/Cashier

    I then created 2 files: BillableTrait.php and NewStripeGateway.php

    BillableTrait.php code:

    <?php namespace Lib\Cashier;
    
    use Laravel\Cashier;
    use Lib\Cashier\NewStripeGateway as StripeGateway;
    
    trait BillableTrait {
        use Cashier\BillableTrait;
    
        /**
         * Get a new billing gateway instance for the given plan.
         *
         * @param  \Laravel\Cashier\PlanInterface|string|null  $plan
         * @return \Laravel\Cashier\StripeGateway
         */
        public function subscription($plan = null)
        {
            if ($plan instanceof PlanInterface) $plan = $plan->getStripeId();
    
            return new StripeGateway($this, $plan);
        }
    
    
    }
    

    For NewStripeGateway.php:

    <?php namespace Lib\Cashier;
    
    use Laravel\Cashier\StripeGateway;
    
    class NewStripeGateway extends StripeGateway {
    
        protected $taxPercent = 0;
    
        public function withTax($tax)
        {
            $this->taxPercent = $tax;
    
            return $this;
        }
    
        protected function buildPayload()
        {
            $payload = [
                'plan' => $this->plan, 'prorate' => $this->prorate,
                'quantity' => $this->quantity, 'trial_end' => $this->getTrialEndForUpdate(),
                'tax_percent' => $this->taxPercent,
            ];
    
            return $payload;
        }
    }
    

    And then I edited my Model that use Cashier like so (only changed the USE block):

    use Lib\Cashier\BillableTrait;
    use Laravel\Cashier\BillableInterface;
    

    I can now do this directly to set the tax on a subscription:

    $user->subscription('testplan')
                            ->withTax(10)
                            ->create(Input::get('stripeToken'), [
                                'email' => 'email@email.com',
                            ]);
    

    It's working perfectly!! If there is anything I did wrong, please notice me of the changes, it's first time I dig in PHP classes (traits, extends, etc) by myself..

    Thank you!

    Raphael