feat: clean credits users
CI / 🧪 Tests Laravel (push) Successful in 2m0s
CI / 🐳 Build & Push Image (push) Successful in 35s

This commit is contained in:
2026-08-07 15:32:40 +02:00
parent eac86afa53
commit 68560655f3
44 changed files with 417 additions and 661 deletions
+3 -17
View File
@@ -1,8 +1,7 @@
<?php
use App\Enums\BillingProductPurpose;
use App\Enums\CreditProductType;
use App\Models\CreditProduct;
use App\Models\BillingProduct;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
@@ -12,35 +11,22 @@ uses(RefreshDatabase::class);
it('lists the subscription and certification offers for the mobile app', function () {
Sanctum::actingAs(User::factory()->create());
CreditProduct::create([
BillingProduct::create([
'name' => 'Certification',
'type' => CreditProductType::ONE_TIME,
'purpose' => BillingProductPurpose::CERTIFICATION,
'credits' => 0,
'amount' => 1999,
'currency' => 'eur',
'stripe_price_id' => 'price_certification',
'sort_order' => 20,
]);
CreditProduct::create([
BillingProduct::create([
'name' => 'Bowli Plus',
'type' => CreditProductType::MONTHLY,
'purpose' => BillingProductPurpose::SUBSCRIPTION,
'credits' => 0,
'amount' => 999,
'currency' => 'eur',
'stripe_price_id' => 'price_subscription',
'sort_order' => 10,
]);
CreditProduct::create([
'name' => 'Ancien pack',
'type' => CreditProductType::ONE_TIME,
'credits' => 5,
'amount' => 299,
'currency' => 'eur',
'stripe_price_id' => 'price_legacy',
]);
$this
->getJson('/api/billing/products')
->assertOk()
+5 -8
View File
@@ -2,13 +2,12 @@
use App\Actions\ReviewIdentityVerification;
use App\Enums\BillingProductPurpose;
use App\Enums\CreditProductType;
use App\Enums\IdentityVerificationStatus;
use App\Enums\PaymentTransactionStatus;
use App\Enums\UserRole;
use App\Filament\Resources\IdentityVerificationRequests\Pages\ListIdentityVerificationRequests;
use App\Listeners\GrantCreditsFromStripeWebhook;
use App\Models\CreditProduct;
use App\Listeners\HandleStripeWebhook;
use App\Models\BillingProduct;
use App\Models\IdentityVerificationRequest;
use App\Models\PaymentTransaction;
use App\Models\User;
@@ -173,11 +172,9 @@ it('grants lifetime certification entitlement from the paid Stripe webhook once'
$user = User::factory()->create([
'stripe_id' => 'cus_certification',
]);
$product = CreditProduct::create([
$product = BillingProduct::create([
'name' => 'Certification',
'type' => CreditProductType::ONE_TIME,
'purpose' => BillingProductPurpose::CERTIFICATION,
'credits' => 0,
'amount' => 1999,
'currency' => 'eur',
'stripe_price_id' => 'price_certification',
@@ -196,7 +193,7 @@ it('grants lifetime certification entitlement from the paid Stripe webhook once'
'amount_total' => 1999,
'currency' => 'eur',
'metadata' => [
'credit_product_id' => $product->getKey(),
'billing_product_id' => $product->getKey(),
'billing_product_purpose' => BillingProductPurpose::CERTIFICATION->value,
],
],
@@ -204,7 +201,7 @@ it('grants lifetime certification entitlement from the paid Stripe webhook once'
],
];
$listener = app(GrantCreditsFromStripeWebhook::class);
$listener = app(HandleStripeWebhook::class);
$listener->handle($event);
$firstPurchaseDate = $user->fresh()->certification_purchased_at;
$listener->handle($event);
+45
View File
@@ -0,0 +1,45 @@
<?php
use App\Enums\BillingProductPurpose;
use App\Enums\PaymentTransactionStatus;
use App\Enums\PaymentTransactionType;
use App\Mail\PaymentInvoiceMail;
use App\Models\BillingProduct;
use App\Models\PaymentTransaction;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
it('renders invoice emails without the retired credit system', function () {
$user = User::factory()->create([
'locale' => 'fr',
]);
$product = BillingProduct::query()->create([
'name' => 'Bowli Plus',
'purpose' => BillingProductPurpose::SUBSCRIPTION,
'amount' => 999,
'currency' => 'eur',
]);
$transaction = PaymentTransaction::query()->create([
'user_id' => $user->getKey(),
'billing_product_id' => $product->getKey(),
'type' => PaymentTransactionType::SUBSCRIPTION_INVOICE,
'status' => PaymentTransactionStatus::PAID,
'amount' => 999,
'currency' => 'eur',
'stripe_invoice_id' => 'in_bowli',
'invoice_url' => 'https://invoice.stripe.test/in_bowli',
]);
$mail = new PaymentInvoiceMail(
$user,
$transaction->load('billingProduct'),
);
$mail
->assertSeeInHtml('Bowli Plus')
->assertSeeInHtml('9,99 EUR')
->assertDontSeeInHtml('Crédits')
->assertDontSeeInHtml('Credits');
});