coupon code system eingeführt. coupons werden vom super admin gemanaged. coupons werden mit paddle synchronisiert und dort validiert. plus: einige mobil-optimierungen im tenant admin pwa.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
namespace App\Services\Checkout;
|
||||
|
||||
use App\Models\CheckoutSession;
|
||||
use App\Models\Coupon;
|
||||
use App\Models\Package;
|
||||
use App\Models\Tenant;
|
||||
use App\Models\User;
|
||||
@@ -64,6 +65,7 @@ class CheckoutSessionService
|
||||
$session->package_snapshot = $this->packageSnapshot($package);
|
||||
$session->amount_subtotal = Arr::get($session->package_snapshot, 'price', 0);
|
||||
$session->amount_total = Arr::get($session->package_snapshot, 'price', 0);
|
||||
$session->amount_discount = 0;
|
||||
$session->provider = CheckoutSession::PROVIDER_NONE;
|
||||
$session->status = CheckoutSession::STATUS_DRAFT;
|
||||
$session->stripe_payment_intent_id = null;
|
||||
@@ -73,6 +75,10 @@ class CheckoutSessionService
|
||||
$session->paddle_transaction_id = null;
|
||||
$session->provider_metadata = [];
|
||||
$session->failure_reason = null;
|
||||
$session->coupon()->dissociate();
|
||||
$session->coupon_code = null;
|
||||
$session->coupon_snapshot = [];
|
||||
$session->discount_breakdown = [];
|
||||
$session->expires_at = now()->addMinutes($this->sessionTtlMinutes);
|
||||
$this->appendStatus($session, CheckoutSession::STATUS_DRAFT, 'package_switched');
|
||||
$session->save();
|
||||
@@ -81,6 +87,31 @@ class CheckoutSessionService
|
||||
});
|
||||
}
|
||||
|
||||
public function applyCoupon(CheckoutSession $session, Coupon $coupon, array $pricing): CheckoutSession
|
||||
{
|
||||
$snapshot = [
|
||||
'coupon' => [
|
||||
'id' => $coupon->id,
|
||||
'code' => $coupon->code,
|
||||
'type' => $coupon->type?->value,
|
||||
],
|
||||
'pricing' => $pricing,
|
||||
];
|
||||
|
||||
$session->coupon()->associate($coupon);
|
||||
$session->coupon_code = $coupon->code;
|
||||
$session->coupon_snapshot = $snapshot;
|
||||
$session->amount_subtotal = $pricing['subtotal'] ?? $session->amount_subtotal;
|
||||
$session->amount_discount = $pricing['discount'] ?? 0;
|
||||
$session->amount_total = $pricing['total'] ?? $session->amount_total;
|
||||
$session->discount_breakdown = is_array($pricing['breakdown'] ?? null)
|
||||
? $pricing['breakdown']
|
||||
: [];
|
||||
$session->save();
|
||||
|
||||
return $session->refresh();
|
||||
}
|
||||
|
||||
public function selectProvider(CheckoutSession $session, string $provider): CheckoutSession
|
||||
{
|
||||
$provider = strtolower($provider);
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Models\CheckoutSession;
|
||||
use App\Models\Package;
|
||||
use App\Models\Tenant;
|
||||
use App\Models\TenantPackage;
|
||||
use App\Services\Coupons\CouponRedemptionService;
|
||||
use App\Services\Paddle\PaddleSubscriptionService;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Arr;
|
||||
@@ -19,6 +20,7 @@ class CheckoutWebhookService
|
||||
private readonly CheckoutSessionService $sessions,
|
||||
private readonly CheckoutAssignmentService $assignment,
|
||||
private readonly PaddleSubscriptionService $paddleSubscriptions,
|
||||
private readonly CouponRedemptionService $couponRedemptions,
|
||||
) {}
|
||||
|
||||
public function handleStripeEvent(array $event): bool
|
||||
@@ -216,6 +218,7 @@ class CheckoutWebhookService
|
||||
]);
|
||||
|
||||
$this->sessions->markCompleted($session, now());
|
||||
$this->couponRedemptions->recordSuccess($session, $data);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -224,6 +227,7 @@ class CheckoutWebhookService
|
||||
case 'transaction.cancelled':
|
||||
$reason = $status ?: ($eventType === 'transaction.failed' ? 'paddle_failed' : 'paddle_cancelled');
|
||||
$this->sessions->markFailed($session, $reason);
|
||||
$this->couponRedemptions->recordFailure($session, $reason);
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user