lmsqueezy / laravel

A package to easily integrate your Laravel application with Lemon Squeezy.
https://lemonsqueezy.com
MIT License
521 stars 51 forks source link

Duplicate customer ID #103

Closed emtiazzahid closed 2 months ago

emtiazzahid commented 2 months ago
    {
        $custom = $payload['meta']['custom_data'] ?? null;

        if (! isset($custom) || ! is_array($custom) || ! isset($custom['billable_id'], $custom['billable_type'])) {
            throw new InvalidCustomPayload;
        }

        return $this->findOrCreateCustomer(
            $custom['billable_id'],
            (string) $custom['billable_type'],
            (string) $payload['data']['attributes']['customer_id']
        );
    }

I am using the User model as billable, when I try to pay from the same lemon squeezy account but a different laravel user it does not let me create a customer as lemon_squeezy_id is unique in the lemon_squeezy_customers table. Maybe I am missing something, can you please give me a clue?

driesvints commented 2 months ago

What do you mean with "from the same lemon squeezy account"? Can you share some code?

emtiazzahid commented 2 months ago

when I tested my application I used different users, but as I logged in to lemonsqueezy I paid with the same account for test purposes which gave the same customer ID. In that case, when I try to purchase a subscription it gives integrity constraint violation: 1062 duplicate entry for key 'lemon_squeezy_customers that error.

driesvints commented 2 months ago

I really need code examples to reproduce this otherwise it's a shot in the dark at what you're trying to do.

emtiazzahid commented 2 months ago

Ok, steps to produce:

thats why i added the route in my web.php Route::post('/lemon-squeezy/webhook', WebhookController::class); and copied the controller WebhookController to my App/Http/Controllers folder with changing namespace

Here is my web.php full code


use Illuminate\Support\Facades\Route;
use App\Http\Controllers\WebhookController;
use Illuminate\Support\Facades\Auth;

Route::view('/', 'welcome');

Route::middleware(['auth', 'verified'])->get('/dashboard', function () {
    $checkout_link = 'https://ourtechbro.lemonsqueezy.com/buy/2*****b-93f9-48bd-****-******e029e?' . http_build_query([
        'checkout[custom][site_id]' => 1,
        'checkout[custom][billable_id]' => Auth::user()->id,
        'checkout[custom][billable_type]' => 'App\Models\User',
        'checkout[custom][redirect_back_url]' => 'https://horse-massive-indirectly.ngrok-free.app',
        'checkout[custom][subscription_type]' => 1
    ]);

    return view('dashboard', compact('checkout_link'));
})->name('dashboard');

Route::view('profile', 'profile')
    ->middleware(['auth'])
    ->name('profile');

require __DIR__.'/auth.php';

Route::post('/lemon-squeezy/webhook', WebhookController::class);

and added that button in dashboard.blade.php <a target="_blank" href="{{ $checkout_link }}" class="bg-blue text-black font-bold py-2 px-4 rounded mt-4">Buy</a>

note: I have prepared lemonsqueezy products for subscription and license, and added webhook URL. using ngrok to serve the site.

driesvints commented 2 months ago

You absolutely need webhooks for this to work. The package can't function without it. You can take the approach of production is the command isn't working for you: https://github.com/lmsqueezy/laravel?tab=readme-ov-file#webhooks-in-production.

thats why i added the route in my web.php

you don't need to do that. The package registers this for you.

and copied the controller WebhookController to my App/Http/Controllers folder with changing namespace

You don't need to do that either. What did you change in this controller?

Here is my web.php full code

You're building the checkout link manually without using the package's documented way of starting a checkout. This isn't supported and cannot work because of how the package works internally. Please only use the documented way to use this package and create checkouts.

I feel like you're doing too much manually and overriding things which is beyond what I can help with sorry.

emtiazzahid commented 2 months ago

Thanks for your reply and valuable time. the webhook was working fine with that custom route, It was just a copy of the controller without any modification.

Without webhook delivery, I think that database error wouldn't be produced. anyway, I removed that route and controller also.

and now I using the route from the documentation

Route::get('/buy', function (Request $request) {
    return $request->user()->checkout('variant-id');
});

so here is my web.php file in live


use Illuminate\Support\Facades\Route;
use Illuminate\Http\Request;

Route::view('/', 'welcome');

Route::middleware(['auth', 'verified'])->get('/dashboard', function () {
    return view('dashboard');
})->name('dashboard');

Route::view('profile', 'profile')
    ->middleware(['auth'])
    ->name('profile');

Route::get('/buy', function (Request $request) {
    return $request->user()->checkout('417893');
});

require __DIR__.'/auth.php';

here only variation ID is added, if I visit the site it redirects to the checkout of my product and stores the data successfully with webhook. but the problem remains the same for the second laravel user with the same lmsqueezy customer.

Local.ERROR: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2735709' for key

Thanks