feat: subscriptions
CI / 🧪 Tests Laravel (push) Successful in 2m48s
CI / 🐳 Build & Push Image (push) Successful in 3m0s

This commit is contained in:
2026-08-07 11:53:46 +02:00
parent 99cb0e63e6
commit 2ece4b6e3e
51 changed files with 1489 additions and 254 deletions
+12 -9
View File
@@ -2,7 +2,7 @@
namespace App\Services;
use App\Enums\CreditProductType;
use App\Enums\BillingProductPurpose;
use App\Models\CreditProduct;
use Laravel\Cashier\Cashier;
@@ -10,6 +10,12 @@ class StripeCreditProductSyncer
{
public function sync(CreditProduct $product): CreditProduct
{
throw_if(
$product->purpose === null,
\InvalidArgumentException::class,
'A billing product purpose is required before syncing with Stripe.',
);
$stripe = Cashier::stripe();
$stripeProductId = $product->stripe_product_id;
@@ -19,8 +25,7 @@ class StripeCreditProductSyncer
'description' => $product->description,
'metadata' => [
'credit_product_id' => $product->getKey(),
'credits' => (string) $product->credits,
'type' => $product->type->value,
'billing_product_purpose' => $product->purpose?->value,
],
]);
@@ -32,8 +37,7 @@ class StripeCreditProductSyncer
'active' => (bool) $product->is_active,
'metadata' => [
'credit_product_id' => $product->getKey(),
'credits' => (string) $product->credits,
'type' => $product->type->value,
'billing_product_purpose' => $product->purpose?->value,
],
]);
}
@@ -42,7 +46,7 @@ class StripeCreditProductSyncer
if (! $product->stripe_price_id) {
$needsNewPrice = true;
} elseif ($product->wasChanged(['amount', 'currency', 'type', 'credits'])) {
} elseif ($product->wasChanged(['amount', 'currency', 'purpose'])) {
$needsNewPrice = true;
}
@@ -55,12 +59,11 @@ class StripeCreditProductSyncer
'currency' => strtolower($product->currency),
'metadata' => [
'credit_product_id' => $product->getKey(),
'credits' => (string) $product->credits,
'type' => $product->type->value,
'billing_product_purpose' => $product->purpose?->value,
],
];
if ($product->type === CreditProductType::MONTHLY) {
if ($product->purpose === BillingProductPurpose::SUBSCRIPTION) {
$priceData['recurring'] = [
'interval' => 'month',
];