Naveed Ali
Naveed Ali

Reputation: 1045

Laravel Cashier - Lifetime Subscription

i am trying to do monthly, yearly and lifetime subscription in which monthly and yearly subscription is working fine. how can i do lifetime/forever subscription? whenever i pass the plan name and plan id to $user->newSubscription() i get an error:

You passed a non-recurring price but this field only accepts recurring prices.

below is my code for subscription:

$paymentMethod = $user->defaultPaymentMethod();

        if ($period == 'yearly') {
            $selectedPlan = $plan->plan_year;
        } elseif($period=='monthly') {
            $selectedPlan = $plan->plan_month;
        }
        else{
            $selectedPlan = $plan->plan_lifetime;
        }   

        $subscription = $user->newSubscription($plan->name, $selectedPlan);

Upvotes: 0

Views: 711

Answers (1)

sebdesign
sebdesign

Reputation: 838

Assuming you are using prices instead of plans, your should create an invoice instead of a subscription:

if ($period == 'yearly') {
    $subscription = $user->newSubscription($plan->name, $plan->plan_year);
} elseif($period=='monthly') {
    $subscription = $user->newSubscription($plan->name, $plan->plan_month);
} else {
    // Create an invoice item with the lifetime price
    StripeInvoiceItem::create([
        'customer' => $user->stripeId(),
        'price' => $plan->plan_lifetime,
    ], $user->stripeOptions());

    // create the invoice with the lifetime item and finalize it automatically after 1 hour
    $user->invoice(['auto_advance' => true]);
}

Next, add invoice.paid to your webhooks and your need to listen for this notification by extending the WebhookController. Here you will find the matching invoice and check if the invoice item has the same id as $plan->lifetime_plan. If so, you can update a column on your customer model to set that the have a lifetime subscription:

public function handleInvoicePaid(array $payload)
{
    if ($user = $this->getUserByStripeId($payload['data']['object']['customer'])) {
        $data = $payload['data']['object'];

        $invoice = $user->findInvoice($data['id']);

        if (isset($invoice)) {
            $plan = ...

            if ($invoice->invoiceItems()->contains(function (InvoiceLineItem $item) use ($plan) {
                return $item->price->id === $plan->lifetime_plan;
            })) {
                $user->update(['has_lifetime_subscription' => true]);
            }
        }
    }

    return $this->successMethod();
}

In your applications, you can check if the user has a lifetime subscription or a normal subscription:

if ($user->has_lifetime_subscription || $user->subscribed()) {
    // ...
}

Upvotes: 3

Related Questions