Coder Social home page Coder Social logo

cashier-mollie's Introduction

This package has moved

Both v1 and v2 are continued in the Mollie namespace: mollie/laravel-cashier-mollie.

This repository will be closed February 1st, 2022.

Read the announcement over at sandorian.com.

A dedicated Cashier Mollie v2 Documentation website can be found at cashiermollie.com.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

cashier-mollie's People

Contributors

ciungulete avatar crynobone avatar diyandev avatar eroelofsen avatar jelleroorda avatar larsjanssen6 avatar lexdewilligen avatar marijnbent avatar marvinlinthorst avatar mmachatschek avatar msnoeren avatar pascalbaljet avatar pascallieverse avatar perafan18 avatar raumar avatar robertboes avatar robindirksen1 avatar robindrost avatar rosiersrobin avatar sandervanhooft avatar stockhausen avatar taylorotwell avatar tobischulz avatar vernondegoede avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cashier-mollie's Issues

Implementing multiplan subscriptions

As explained in issue #397 from Laravel Cashier Stripe, multiplan subscription would be a very nice feature. Could you implement this for us or is this already available? Would you accept PR's on this?

This is useful because this way the customer will see only one debit on their bank account for every billing cycle instead of seeing one for every subscribed plan. Eg. if your customer is subscribed to a main service plus 4 features, they will get 5 debits every month. This is bad for service providers because (a) it is ugly (b) it is more expensive due to the fix fees.

Deprecate support for older Laravel versions

Right now this package's support goes back to Laravel 5.5, which is the latest LTS before 6.0

As stated in the Laravel support policy, only version 5.8 and up are supported currently.

So it's time for Cashier Mollie to drop support for Laravel versions prior to 5.8.

This includes:

  • Dropping support for Laravel versions prior to 5.8
  • replacing all helpers with their class equivalent (i.e. Str for string helpers)
  • removing the custom written helpers, which were introduced for backwards compatibility
  • updating the Travis file

User mandate id not updated on first payment

Hello there,

I'm testing out with the __invoke method provided in the docs:

class CreateSubscriptionController extends Controller
{
    /**
     * @param string $plan
     * @return \Illuminate\Http\RedirectResponse
     */
    public function __invoke(string $plan)
    {
        $user = Auth::user();

        if (!$user->subscribed($plan)) {

            $name = 'main';

            $result = $user->newSubscription($name, $plan)->create();

            if (is_a($result, RedirectResponse::class)) {
                return $result; // Redirect to Mollie checkout
            }

            return redirect()->view('feed.index')->with('success', 'Welcome to the ' . $plan . ' plan');
        }

        return redirect()->view('feed.index')->with('error', 'You are already on the ' . $plan . ' plan');
    }
}

When creating a new subscription it doesn't ever seem to hit the following line:
return redirect()->view('feed.index')->with('success', 'Welcome to the ' . $plan . ' plan');

Somewhere in the following lines:

if (is_a($result, RedirectResponse::class)) {
                return $result; // Redirect to Mollie checkout
            }

It seems to standard go to the 'redirect_url' => config(app.ur), provided in the config file. Which doesn't let me add a custom success message.

On another note, after doing a succesful subscription payment $user->subscribed($plan) keeps returning false. It seems a mollie_customer_id is created, but not a mandate, which I think is necessary for subscriptions?

https://i.gyazo.com/3d99c5b76ac4cfb054a1e7ae3bedbd26.png

Usage with Mollie Connect

I'm working on an application which uses Mollie Connect to setup subscriptions using Mollie accounts from third parties.

I would like to leverage this library to for example handle swapping plans on the next cycle and pausing or resuming the current subscription.

I'm trying to find out a way to make this work, I think I have an idea but I was wondering if you have an idea on how to make this work :).

Thanks a lot!

Readme example code - subscribed check always returns false

First of all: Thanks for this project.

I found that the example code in the readme which checks if a user is already subscribed always returns false as parameter "plan" should be the second argument instead of the first.

Current Readme.md

        public function __invoke(string $plan)
        {
            $user = Auth::user();
    
            if(!$user->subscribed($plan)) {
    
                $name = ucfirst($plan) . ' membership';

Suggested solution

        public function __invoke(string $plan)
        {
            $user = Auth::user();

            $name = ucfirst($plan) . ' membership';

            if(!$user->subscribed($name, $plan)) {
    

Billable.php

    /**
     * Determine if the billable model has a given subscription.
     *
     * @param  string  $subscription
     * @param  string|null  $plan
     * @return bool
     */
    public function subscribed($subscription = 'default', $plan = null)

Invalid API key after download

I just downloaded the latest version of cashier-mollie and was excited to use it. However, after downloading it gave the error Mollie\Api\Exceptions\ApiException : Invalid API key: . An API key must start with 'test_' or 'live_' and must be at least 30 characters long.', while I'm not using the API anywhere.

I also added the MOLLIE_KEY="***" key (with my real key, of course) to my .env file, but this doesn't seem to do anything. Every time I do try to execute a command through the console (even trying to clear the cache) the error appears. I can't even continue to step 1 of the installation (php artisan cashier:install) because this throws the same error.

I've pasted the whole error below:

Mollie\Api\Exceptions\ApiException  : Invalid API key: ''. An API key must start with 'test_' or 'live_' and must be at least 30 characters long.

  at D:\PHPStorm folders\WordQuest-4\vendor\mollie\mollie-api-php\src\MollieApiClient.php:339
    335|     {
    336|         $apiKey = trim($apiKey);
    337|
    338|         if (!preg_match('/^(live|test)_\w{30,}$/', $apiKey)) {
  > 339|             throw new ApiException("Invalid API key: '{$apiKey}'. An API key must start with 'test_' or 'live_' and must be at least 30 characters long.");
    340|         }
    341|
    342|         $this->apiKey = $apiKey;
    343|         $this->oauthAccess = false;

  Exception trace:

  1   Mollie\Api\MollieApiClient::setApiKey("")
      D:\PHPStorm folders\WordQuest-4\vendor\mollie\laravel-mollie\src\Wrappers\MollieApiWrapper.php:92

  2   Mollie\Laravel\Wrappers\MollieApiWrapper::setApiKey()
      D:\PHPStorm folders\WordQuest-4\vendor\mollie\laravel-mollie\src\Wrappers\MollieApiWrapper.php:67

  Please use the argument -v to see more details.
Script @php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 1

Does anyone have an idea how I can fix this issue?

PS: I'm using Laravel framework 6.0.3

Invoice filenames are month-based.

When downloading an invoice using $order->invoice()->download(), the filename is automatically generated. This filename assumes that an invoice will be created monthly, as its format is "month_year.pdf".

The line for this behavior is located at:

$filename = $this->date()->month.'_'.$this->date()->year.'.pdf';

I guess using the automatically generated ID as default filename, as found in the invoice itself, is better. However, allowing the name to be overridden is also a great addition. Thoughts?

Target [Laravel\Cashier\Coupon\Contracts\CouponRepository] is not instantiable.

Hi

I have made a project where users can subscribe to a plan. Its working as intended on my local server and today I pushed it to my testing server. When ever i want to go to the checkout it will give me this error.

image

Its before i get on the mollie checkout page. And it seems to break at StartSubscription.php at line 62
image

Im wondering what is wrong since its not giving me this error on my local server.

regards, Jabir

Can't upgrade to laravel 6.2

  • cashier-mollie: 1.2.3
  • Laravel Version: 6.0.3
  • PHP Version: 7.2.11

When upgrading Laravel from 6.0.3 to laravel 6.2 cashier gives the following error when running composer update

Problem 1 - Conclusion: remove laravel/cashier-mollie v1.2.3 - Installation request for laravel/cashier-mollie 1.2.3 -> satisfiable by laravel/cashier-mollie[v1.2.3]. - Conclusion: don't install laravel/framework v6.2.0 - laravel/cashier-mollie v1.2.3 requires illuminate/support ~5.8.0|~6.0.0 -> satisfiable by laravel/framework[v6.0.4, 5.8.x-dev], illuminate/sup port[5.8.x-dev, v5.8.0, v5.8.11, v5.8.12, v5.8.14, v5.8.15, v5.8.17, v5.8.18, v5.8.19, v5.8.2, v5.8.20, v5.8.22, v5.8.24, v5.8.27, v5.8.28, v5.8.29, v5.8.3, v5.8.30, v5.8.31, v5.8.32, v5.8.33, v5.8.34, v5.8.35, v5.8.4, v5.8.8, v5.8.9, v6.0.0, v6.0.1, v6.0.2, v6.0.3, v6.0.4]. - Can only install one of: laravel/framework[6.x-dev, 5.8.x-dev]. - Can only install one of: laravel/framework[6.x-dev, v6.0.4]. - don't install illuminate/support 5.8.x-dev|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.0|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.11|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.12|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.14|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.15|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.17|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.18|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.19|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.2|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.20|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.22|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.24|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.27|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.28|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.29|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.3|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.30|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.31|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.32|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.33|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.34|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.35|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.4|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.8|don't install laravel/framework 6.x-dev - don't install illuminate/support v5.8.9|don't install laravel/framework 6.x-dev - don't install illuminate/support v6.0.0|don't install laravel/framework 6.x-dev - don't install illuminate/support v6.0.1|don't install laravel/framework 6.x-dev - don't install illuminate/support v6.0.2|don't install laravel/framework 6.x-dev - don't install illuminate/support v6.0.3|don't install laravel/framework 6.x-dev - don't install illuminate/support v6.0.4|don't install laravel/framework 6.x-dev - Installation request for laravel/framework ^6.2 -> satisfiable by laravel/framework[6.x-dev, v6.2.0].

Orders table total_due is not updated when mollie_payment_status is "paid"

When a new user subscribes and executes the first payment the total_due column is not updated (I'm using Mollie test api key).

In my case the first payment amount is 1 and the tax is 21%, so total will be 1.21. After the mandate has been given I'd expect the total_due to be 0, but it remain on 1.21.

Ps. The same happens when without using tax.

Add metadata to plans.

I've noticed there currently is no way to add settings or metadata to plans. For example, a plan allows for 5 users and 20 emails. Currently, I have to use an array-map to retrieve how many users the team can create. It would be easier to add this to the plan itself and get it from the plan object afterwards.

Consider the following:

// config/cashier_plans.php
'plans' => [
    'basic' => [
        'amount' => [
            'value' => '5.00',
            'currency' => 'EUR',
        ],
        'metadata' => [
            'users' => 5,
            // Any other data.
        ],
    ],
    'pro' => [
        // Other plan
    ],
]
// ...

Think of the metadata as specifying the pricing table. The metadata should then be able to be retrieved using the Plan object.. I know this can also be archieved by using config('cashier_plans.plan')[<name of plan>]['metadata'], but its a bit nicer this way. Thoughts?

Edit: after thinking about it some more, features would be a better name for this as plans have features, not settings or metadata.

Please tag a new version

Hi,

Please tag a new version because right now it can't be installed
with Laravel 6.

Installation request for laravel/framework (locked at v6.2.0, required as ^6.2) -> satisfiable by laravel/framework[v6.2.0].

Thanks!

How does subscription per year per user work?

Hello,

Thank you for this great package.

I ask myself a question about the subscription per user per year.

I will integrate this package for teams. I will create a valid plan 12 months per user. When the administrator adds a user to the team, he will increment the amount.

If I understand correctly, it will only be charged for this additional user at the end of his current period? So, if he has 10 months of subscriptions left and he adds a new seat, this new seat will only be charged 10 months later. A little annoying.

Am I right?

FirstPayment amount seems to be ignored

Hello @sandervanhooft

Something came up when I was debugging the other issue. I have set the value of the firstpayment amount very low.

/**
         * The default amount for a first payment. Can be overridden per Plan.
         */
        'amount' => [

            /**
             * A string containing the exact amount you want to charge for the first payment, in the given currency.
             * Make sure to set the right amount of decimals. Non-string values are not accepted by Mollie.
             */
            'value' => '0.10',

            /**
             * An ISO 4217 currency code. The currencies supported depend on the payment methods that are enabled on
             * your Mollie account.
             */
            'currency' => 'EUR',
        ],

And this is the value of the plan I provide:

/**
     * The subscription plans.
     */
    'plans' => [

        /**
         * The plan reference.
         */
        'membership' => [

            /**
             * The amount to be billed each billing cycle.
             */
            'amount' => [

                /**
                 * A string containing the exact amount you want to charge each billing cycle, in the given currency.
                 * Make sure to set the right amount of decimals. Non-string values are not accepted by Mollie.
                 */
                'value' => '4.99',

                /**
                 * An ISO 4217 currency code. The currencies supported depend on the payment methods that are enabled on
                 * your Mollie account.
                 */
                'currency' => 'EUR',
            ],

https://i.gyazo.com/61dd25e5a9b7263c0fc337534c44a1a6.png (Visual aid)
When looking at these test payments I noticed that all these payments amounted to โ‚ฌ4.99 which is the plan amount. I'm wondering if these should be amounting to โ‚ฌ0.10 since they're all first payments (since a mandate wasn't generated).

Quantity instantly creates payments

I'm currently creating software that uses the quantity system. A user can create as many as they like and pay for each one of them monthly. Currently, a product is around 50 cents. When the customer adds 10 products, 10 payments will be created and I'll pay 10 times the transaction costs, which is around half the price of a product using SEPA.

Is there any way to queue these payments and send them in one big chunk daily (or any other interval), perhaps during the refresh of a subscription? I guess the software should keep track of the usage this way to calculate the time used of products.

A solution could be to let customers buy products in steps of 10 and chunk payments this way, although I prefer the precise quantity.

Thoughts?

Swapping a plan does not return an RedirectResponse

When swapping the plan of a user a Subscription (Laravel\Cashier\Subscription) object is returned, not a RedirectResponse, even though new payments showed up in the Mollie Dashboard (status: pending; method: sepa).

Payments generated:
Tier 2 to tier 1: 0,01 cents
Tier 1 back to tier 2: no payment generated
Tier 2 to tier 3: difference between plans

Laravel 6.0 Support

Doesn't seem to be any 6.0 support. I see there is a pull request. Any chance we could push this? ๐Ÿ‘

First payment is not affected by tax rule.

The first payment is not affected by tax and I can't seem to find out why. The first payment is 50 cents exactly (as configured) and all payments after (configured as 41 cents with 21% tax) are sometimes 50 cents but sometimes 49 cents as well.

Minimum payment should already include VAT

When starting a trial with a card upfront, a minimum amount is charged in order to establish a mandate.

Right now the VAT is applied on top of the configured minimum amount. Ideally, the configured amount should already include VAT.

So right now, a โ‚ฌ1.00 configured minimumAmount with 21% VAT results in a โ‚ฌ1.21 payment.

Ideally, it should result in a payment of โ‚ฌ1.00 including (โ‚ฌ1.00/121)*21 = โ‚ฌ0.17 VAT.

Extra description lines field doesn't work on shared hosting databases.

The description_extra_lines field on the order_items table is a JSON-field. I'm in favor of using native types, but unfortunately this field is not yet supported on my shared hosting. I know that's not the best environment to serve a Laravel application from, but I also know I won't be the first to do so ;)

Anyway, this can be fixed by changing the field into a text field as Laravel will cast it to a string format. This way all shared-hosting environments will be supported too.

FirstPayment minimum after coupon

How should the FirstPayment amount be increased to meet the minimum payment amount (config('cashier.first_payment.amount') requirement?

  • add the extra required amount as a service fee
  • add the extra required amount to the balance

What do you think?

Context: in some cases the first payment amount will drop below the required minimum. I.e. when a coupon was applied.

Anchoring a monthly billing cycle

Hi there!

I have a question about a particular requirement that I have and I'm struggling on how to implement it :).

What I would like is it the subscriptions always start at the first of the month. Doing that means that I would also like to charge the user for what is remaining of that month. Let's say that I start a subscription at the middle of the month of a 20 euro subscription. I would like to start the subscription at the first of the next month and I would like to charge 10 euros now.

Is that possible?

Thanks a lot!

Error executing API call (422: Unprocessable Entity): The payment method is invalid.

Second ticket!

First of all I've added my test_key to my .env file

I've implemented a plan like:

 /**
     * The subscription plans.
     */
    'plans' => [

        /**
         * The plan reference.
         */
        'membership' => [

            /**
             * The amount to be billed each billing cycle.
             */
            'amount' => [

                /**
                 * A string containing the exact amount you want to charge each billing cycle, in the given currency.
                 * Make sure to set the right amount of decimals. Non-string values are not accepted by Mollie.
                 */
                'value' => '10.00',

                /**
                 * An ISO 4217 currency code. The currencies supported depend on the payment methods that are enabled on
                 * your Mollie account.
                 */
                'currency' => 'EUR',
            ],

            /**
             * The length of the billing cycle.
             */
            'interval' => '1 month',

            /**
             * The text to appear on the invoice.
             */
            'description' => 'Monthly payment',

            /**
         * The chain of subscription OrderItem preprocessors. These are called right before the Subscription's
         * OrderItem is processed into an OrderItem. You can use this for calculating variable costs a.k.a. metered
         * billing. Make sure the preprocessors extend the BaseOrderItemProcessor.
         */
            //'order_item_preprocessors' => [
            //    ProcessCoupons::class,
            //    PersistOrderItems::class,
            //],
        ],
    ],

Then I created the controller:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;

class CreateSubscriptionController extends Controller
{
    /**
     * @param string $plan
     * @return \Illuminate\Http\RedirectResponse
     */
    public function __invoke(string $plan)
    {
        $user = Auth::user();

        if (!$user->subscribed($plan)) {

            $name = ucfirst($plan);
            $result = $user->newSubscriptionViaMollieCheckout($name, $plan)->create();

            if (is_a($result, RedirectResponse::class)) {
                return $result; // Redirect to Mollie checkout
            }

            return back()->with('status', 'Welcome to the ' . $plan . ' plan');
        }

        return back()->with('status', 'You are already on the ' . $plan . ' plan');
    }
}

Added a route to hit the controller, here's where I guess I have to use a wildcard to find the plan? (I think I might be making a mistake here somewhere)
Route::get('pay/{membership}', 'CreateSubscriptionController')->name('pay');

When I hit that route I receive the following error:
https://i.gyazo.com/952670975ddde5d304aa055ffb0dcf19.png

I also ran the following commands to make sure nothing is cached etc:

php artisan route:clear
php artisan config:clear
php artisan cache:clear
composer dump-autoload

The only change I made in the config files was to change the plan name from "Example-1" to "membership"

Installation Laravel.5.8

I tried to install the package and cannot run the install command after pulling in the package:

$ php artisan cashier:install

There are no commands defined in the "cashier" namespace.

Discussion - Adding preprocessors to the first payment

Preprocessors are currently not applied to the first payment. What I'm trying to do is adding extra items to the subscription, as a very basic test I've created the following preprocessor:

class Addon extends BaseOrderItemPreprocessor
{

    /**
     * @param \Laravel\Cashier\Order\OrderItemCollection $items
     * @return \Laravel\Cashier\Order\OrderItemCollection
     */
    public function handle(OrderItemCollection $items)
    {
        $addon = OrderItem::make([
            'process_at' => now(),
            'owner_type' => $items->first()->owner_type,
            'owner_id' => $items->first()->owner_id,
            'description' => 'Extra items',
            'currency' => 'EUR',
            'tax_percentage' => 0,
            'quantity' => 2,
            'unit_price' => 1500,
        ]);

        return $items->push($addon);
    }
}

This does add two items to subsequent payments, but not to the first payment.

After reading through the code, I'm want to try to create a PR, but I'm not sure if I'm on the right track. It seems like the coupons and PersistOrderItems are handled differently on the first payment, basically they're added "manually".

My idea is to add a property to ProcessCoupons and PersistOrderItems to indicate that those two preprocessors should not be handled on the first payment. Then in the create method of the FirstPaymentSubscriptionBuilder I can fetch all the preprocessors, filter out those which shouldn't be applied and then add them to the $actions array.

Now my question is, would this work and would this be the correct way to handle preprocessors on the first payment?

Can this be used with Paypal accounts?

I see Mollie has some support for Paypal. Does this package (when used with mollie) allow the use of Paying subscriptions via Paypal account balances?

Migration autoloading

Making use of Laravels loadMigrationsFrom() method would add the option to keep the migrations as they are without having to publish them. I'd like this feature since it would save me 6 migration files in my database folder.

I'll submit a PR to save you some work!

StartSubscription error concerning owner

The first payment webhook throws this error;

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'owner_id' cannot be null (SQL: insert into `order_items` (`owner_id`, `owner_type`, `process_at`, `currency`, `unit_price`, `quantity`, `tax_percentage`, `description`, `orderable_id`, `orderable_type`, `updated_at`, `created_at`) values (?, ?, 2019-06-29 14:16:40, EUR, 650, 1, 0, 6 Month Subscription, 6, Laravel\Spark\Subscription, 2019-06-29 14:30:34, 2019-06-29 14:30:34))

This data is filled in \Laravel\Cashier\SubscriptionBuilder\MandatedSubscriptionBuilder::create;

            $subscription = $this->owner->subscriptions()->create([
                'name' => $this->name,
                'plan' => $this->plan->name(),
                'quantity' => $this->quantity,
                'tax_percentage' => $this->owner->taxPercentage() ?: 0,
                'trial_ends_at' => $this->trialExpires,
                'cycle_started_at' => $now,
                'cycle_ends_at' => $this->nextPaymentAt,
            ]);

The fields owner_id and owner_type are missing here. When I add them, everything works;

            $subscription = $this->owner->subscriptions()->create([
                'name' => $this->name,
                'plan' => $this->plan->name(),
                'quantity' => $this->quantity,
                'owner_type' => get_class($this->owner),
                'owner_id' => $this->owner->id,
                'tax_percentage' => $this->owner->taxPercentage() ?: 0,
                'trial_ends_at' => $this->trialExpires,
                'cycle_started_at' => $now,
                'cycle_ends_at' => $this->nextPaymentAt,
            ]);

Ambigious class resolution & --ignore-platform-reqs

Hello there,

I'm installing this package on a windows enviroment running homestead and I had to use the --ignore-platform-reqs flag.

Do you think this could lead to any complications, or am I free to use this.

Also got the following yellow lines while installing:

Warning: Ambiguous class resolution, "Laravel\Cashier\Billable" was found in both "C:/Users/***/Desktop/***/vendor/laravel/cashier/src/Billable.php" and "C:/Users/***/Desktop/***/vendor/laravel/cashier-mollie/src\Billable.php", the first will be used.
Warning: Ambiguous class resolution, "Laravel\Cashier\Cashier" was found in both "C:/Users/***/Desktop/***/vendor/laravel/cashier/src/Cashier.php" and "C:/Users/***/Desktop/***/vendor/laravel/cashier-mollie/src\Cashier.php", the first will be used.
Warning: Ambiguous class resolution, "Laravel\Cashier\CashierServiceProvider" was found in both "C:/Users/***/Desktop/***/vendor/laravel/cashier/src/CashierServiceProvider.php"
and "C:/Users/***/Desktop/***/vendor/laravel/cashier-mollie/src\CashierServiceProvider.php", the first will be used.
Warning: Ambiguous class resolution, "Laravel\Cashier\Http\Controllers\WebhookController" was found in both "C:/Users/***/Desktop/***/vendor/laravel/cashier/src/Http/Controllers/WebhookController.php" and "C:/Users/***/Desktop/***/vendor/laravel/cashier-mollie/src\Http\Controllers\WebhookController.php", the first will be used.
Warning: Ambiguous class resolution, "Laravel\Cashier\Subscription" was found in both "C:/Users/***/Desktop/***/vendor/laravel/cashier/src/Subscription.php" and "C:/Users/***/Desktop/***/vendor/laravel/cashier-mollie/src\Subscription.php", the first will be used.

I have the normal cashier package installed and it seems to have some Ambigious class resolutions. As I'm not all to familiar with this I wanted to inform myself if this could lead to complications.
Is it possible to use Laravel Cashier aswell as Laravel Cashier Mollie in one project?

Kind Regards!

FirstPaymentPaid Event protected property $payment

I'm implementing the FirstPaymentPaid listener to only create an account when the first payment was successful.

In my EventServiceProvider.php I've add the listener.

protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
        'Laravel\Cashier\Events\FirstPaymentPaid' => [
            'App\Listeners\CreateAccountAfterPayment'
        ]
    ];

In my CreateAccountAfterPayment listener I try to access the payment details, but since the payment property is protected I cannot access the details.

namespace App\Listeners;

use Laravel\Cashier\Events\FirstPaymentPaid;

class CreateAccountAfterPayment
{
    public function handle(FirstPaymentPaid $event)
    {
        $event->payment; // <-- Cannot access payment details
    }

Am I doing something wrong here or should they payment property be public?

The times property of a coupon is not used

In the cashier_coupons.php cofig file, you can set the times property.
This property doesn't seem to be used. After applying a coupon with a times value higher than 1 the times_left column in the redeemed_coupons table is always 0 (or 1 before processing the order).

Interval calculation

So for this example I have a plan configured with an interval of 1 month and made a subscription.

What I expect:

When I start a subscription for a user on 2019-08-30, I want to bill them on the 30 off every month.

Here I made a example (the billing dates are marked with a green box):
calendar-view-expected

What the packages does:

The package billing-day is changing when the month doesn't have (in this case) 30 or more days in a month.

Here I made a example of what the package is doing (startdate = 2018-08-30) (the billing dates are marked with a green box):
calendar-view-actual

Proposal

I think we should make this as an optional item in the plan configuration, that way the enduser can decide when to use this option in their plans or use the default carbon behaviour.

Also, I've discussed this issue with @vernondegoede about how they handle this in their Subscription API.

Used code

When starting on 2019-08-30

//source how laravel/cashier-mollie handles: https://github.com/laravel/cashier-mollie/blob/b1256489456a5f1e71e3af1de150df7d4a9fb08a/src/Subscription.php#L423

$run_timer = 12;
$tmp = $now = Carbon::parse('2019-08-30');

for($x = 1; $x <= $run_timer; $x++) {
    $tmp = $tmp->copy();

    $tmp->modify('+ 1 month');

    dump($tmp);
}

image

When starting on 2018-08-30 (one year before)

//source how laravel/cashier-mollie handles: https://github.com/laravel/cashier-mollie/blob/b1256489456a5f1e71e3af1de150df7d4a9fb08a/src/Subscription.php#L423

$run_timer = 12;
$tmp = $now = Carbon::parse('2018-08-30');

for($x = 1; $x <= $run_timer; $x++) {
    $tmp = $tmp->copy();

    $tmp->modify('+ 1 month');

    dump($tmp);
}

image

Settings plans from database insted of cashier_plans config

I see in ConfigPlanRepository the plans array from the cashier_plans get's loaded though my plans are dynamicly loaded from the database based on which product_id is selected. Is there a way to set it up to load it from the DB instead of from the configs? Otherwise, what does this exactly do, what happens if i just leave that array blank? Or how would i go about extending the ConfigPlanRepository to allow loading these values from the database based on product_id?

Coupon first payment issues

I've tried to create my own coupon, but the documentation is very minimal, so I've basically copied the FixedDiscountHandler and changed a few things.

Now my own coupon didn't work, so I applied the default coupon (with the default plan etc.), and I think a lot of things are not working correctly:

  • The coupon is not applied during payment, the 10.00 EUR plan remains the same price during checkout.
  • After payment I get errors Trying to get property 'currency' of non-object at ...\\vendor\\laravel\\cashier-mollie\\src\\Order\\Order.php:75
  • There is no subscription created in the database, while the payment has succeeded (probably because of this error in a webhook)
  • There is only a payment in the Mollie dashboard with the original price, which is what I also saw during payment

The code I used is the same as in the "documentation" / readme, except I changed the part where I make a new subscription, like this:

$result = $user
            ->newSubscription($name, $plan)
            ->withCoupon('welcome')
            ->create();

This is the complete error log:

[2019-09-09 13:40:38] local.ERROR: Trying to get property 'currency' of non-object {"exception":"[object] (ErrorException(code: 0): Trying to get property 'currency' of non-object at D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\cashier-mollie\\src\\Order\\Order.php:75)
[stacktrace]
#0 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\cashier-mollie\\src\\Order\\Order.php(75): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(8, 'Trying to get p...', 'D:\\\\GitHub\\\\molli...', 75, Array)
#1 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Concerns\\ManagesTransactions.php(29): Laravel\\Cashier\\Order\\Order::Laravel\\Cashier\\Order\\{closure}(Object(Illuminate\\Database\\SQLiteConnection))
#2 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\DatabaseManager.php(349): Illuminate\\Database\\Connection->transaction(Object(Closure))
#3 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Support\\Facades\\Facade.php(239): Illuminate\\Database\\DatabaseManager->__call('transaction', Array)
#4 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\cashier-mollie\\src\\Order\\Order.php(102): Illuminate\\Support\\Facades\\Facade::__callStatic('transaction', Array)
#5 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\cashier-mollie\\src\\Order\\Order.php(119): Laravel\\Cashier\\Order\\Order::createFromItems(Object(Laravel\\Cashier\\Order\\OrderItemCollection), Array, false)
#6 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\cashier-mollie\\src\\FirstPayment\\FirstPaymentHandler.php(52): Laravel\\Cashier\\Order\\Order::createProcessedFromItems(Object(Laravel\\Cashier\\Order\\OrderItemCollection), Array)
#7 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Concerns\\ManagesTransactions.php(29): Laravel\\Cashier\\FirstPayment\\FirstPaymentHandler->Laravel\\Cashier\\FirstPayment\\{closure}(Object(Illuminate\\Database\\SQLiteConnection))
#8 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\DatabaseManager.php(349): Illuminate\\Database\\Connection->transaction(Object(Closure))
#9 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Support\\Facades\\Facade.php(239): Illuminate\\Database\\DatabaseManager->__call('transaction', Array)
#10 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\cashier-mollie\\src\\FirstPayment\\FirstPaymentHandler.php(54): Illuminate\\Support\\Facades\\Facade::__callStatic('transaction', Array)
#11 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\cashier-mollie\\src\\Http\\Controllers\\FirstPaymentWebhookController.php(27): Laravel\\Cashier\\FirstPayment\\FirstPaymentHandler->execute()
#12 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\ControllerDispatcher.php(48): Laravel\\Cashier\\Http\\Controllers\\FirstPaymentWebhookController->handleWebhook(Object(Illuminate\\Http\\Request))
#13 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php(219): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(Laravel\\Cashier\\Http\\Controllers\\FirstPaymentWebhookController), 'handleWebhook')
#14 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php(176): Illuminate\\Routing\\Route->runController()
#15 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(680): Illuminate\\Routing\\Route->run()
#16 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(30): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#17 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(104): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#18 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(682): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#19 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(657): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#20 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(623): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#21 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(612): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#22 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php(176): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#23 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(30): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#24 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\fideloper\\proxy\\src\\TrustProxies.php(57): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#25 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): Fideloper\\Proxy\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#26 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#27 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php(21): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#28 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#29 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#30 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php(21): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#31 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#32 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#33 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize.php(27): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#34 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#35 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#36 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode.php(62): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#37 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(163): Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#38 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#39 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(104): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#40 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php(151): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#41 D:\\GitHub\\mollie-subscriptions-5.8-poc\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php(116): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#42 D:\\GitHub\\mollie-subscriptions-5.8-poc\\public\\index.php(55): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#43 D:\\GitHub\\mollie-subscriptions-5.8-poc\\server.php(21): require_once('D:\\\\GitHub\\\\molli...')
#44 {main}

I think the subscriptions are not saved to my own DB because of this error, this kind of worries me, since we have no control over this and it's hard to debug if a user actually bought a product.

The coupon that's not applied also seems very strange, it might be applied during the next payment, but that's a weird flow, right?

StartSubscription error undefined index taxPercentage

I have successfully made a test payment, i get the welcome message so all seems fine. But when i check if have a valid subscription i get false and i see this error in my log:

[2019-06-03 13:01:41] local.ERROR: Undefined index: taxPercentage {"exception":"[object] (ErrorException(code: 0): Undefined index: taxPercentage at .../vendor/laravel/cashier-mollie/src/FirstPayment/Actions/StartSubscription.php:75)
[stacktrace]
#0 .../vendor/laravel/cashier-mollie/src/FirstPayment/Actions/StartSubscription.php(75): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(8, 'Undefined index...', '/Users/gerttimm...', 75, Array)
#1 .../vendor/laravel/cashier-mollie/src/FirstPayment/FirstPaymentHandler.php(84): Laravel\\Cashier\\FirstPayment\\Actions\\StartSubscription::createFromPayload(Array, Object(App\\Company))
#2 [internal function]: Laravel\\Cashier\\FirstPayment\\FirstPaymentHandler->Laravel\\Cashier\\FirstPayment\\{closure}(Object(stdClass), 0)
#3 /

It seems he cannot find taxPercentage in the payload, but in my Billable Model (for me it is App\Company) i have a function taxPercentage() and in the Molle app i can see this metadata:

{
  "owner": {
    "type": "App\\Company",
    "id": 2
  },
  "actions": [
    {
      "handler": "Laravel\\Cashier\\FirstPayment\\Actions\\StartSubscription",
      "description": "Monthly payment",
      "subtotal": {
        "currency": "EUR",
        "value": "10.00"
      },
      "taxPercentage": 21,
      "plan": "premium",
      "name": "Premium membership",
      "quantity": 1
    }
  ]
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.