Bravi
Bravi

Reputation: 773

Temporary subscriptions in Paddle and Laravel Cashier

I have a Laravel + Cashier (Paddle) app that will be taking one-off payments, as well as monthly subscriptions. One-off payment needs to activate a membership/subscription for only certain period of time, for example 2 weeks (please bare in mind, this is not a trial period).

I have setup a single product with three different prices (2 one-off payments and 1 monthly subscription).

I am having trouble properly setting up a temporary subscription. My first approach was to listen to TransactionCompleted event and do:

    /**
     * Handle the event.
     */
    public function handle(TransactionCompleted $event): void
    {
        $three_week_plan = '1234'; // copied from Paddle
        $four_week_plan  = '4566';
        $monthly_plan    = '4893';

        if ($event->transaction->product_id === $three_week_plan) {
            $this->createOrUpdateSubscription($event, 3);
        }

        if ($event->transaction->product_id === $four_week_plan) {
            $this->createOrUpdateSubscription($event, 4);
        }

        // default subscription creation behaviour
        if ($event->transaction->product_id === $monthly_plan) {
            $event->billable->newSubscription(SubscriptionType::Default, $monthly_plan);
        }
    }

    /**
     * Create or update the subscription.
     *
     * @param  TransactionCompleted $event
     * @param  int                  $weeks
     *
     * @return void
     */
    private function createOrUpdateSubscription(TransactionCompleted $event, int $weeks): void
    {
        $attributes = [
            'billable_id'   => $event->billable->id,
            'billable_type' => get_class($event->billable),
            'type'          => SubscriptionType::Default,
        ];

        // either extend the existing subscription or create a new one
        $subscription = Subscription::firstOrNew($attributes);

        $subscription->updateOrCreate($attributes, [
            'paddle_id' => $event->transaction->paddle_id,
            'status'    => 'active',
            'ends_at'   => now()->max($subscription->ends_at)
                ->addWeeks($weeks),
        ]);
    }

As you can see, I was thinking of making a use of ends_at field, which I then use in my queries to determine the end of subscription.

Because this is not an actual subscription, I will not be getting any Webhook calls from Paddle regarding the status changes or pastDue and etc events.

I was wondering what would be a better and more scalable approach to this?

Upvotes: 0

Views: 27

Answers (0)

Related Questions