paddel setup new verifier

This commit is contained in:
Mark Gregory
2026-09-09 12:36:34 +01:00
parent 1540be5551
commit 7c8b5fabd6
5 changed files with 197 additions and 0 deletions
@@ -0,0 +1,38 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Contracts\View\View;
use RuntimeException;
final class CheckoutController extends Controller
{
public function __invoke(): View
{
$paddle = config('rsync-studio.paddle');
$token = trim((string) ($paddle['client_side_token'] ?? ''));
if ($token === '') {
throw new RuntimeException('PADDLE_CLIENT_SIDE_TOKEN is not configured.');
}
$plans = [
'personal-monthly' => ['name' => 'Personal', 'billing' => 'Monthly', 'display_price' => '£1.99 / month', 'price_id' => $paddle['personal_monthly_price_id'], 'activation_limit' => 1],
'personal-annual' => ['name' => 'Personal', 'billing' => 'Annual', 'display_price' => '£14.99 / year', 'price_id' => $paddle['personal_annual_price_id'], 'activation_limit' => 1],
'professional-monthly' => ['name' => 'Professional', 'billing' => 'Monthly', 'display_price' => '£3.99 / month', 'price_id' => $paddle['professional_monthly_price_id'], 'activation_limit' => 3],
'professional-annual' => ['name' => 'Professional', 'billing' => 'Annual', 'display_price' => '£29.99 / year', 'price_id' => $paddle['professional_annual_price_id'], 'activation_limit' => 3],
];
foreach ($plans as $plan) {
if (trim((string) $plan['price_id']) === '') {
throw new RuntimeException('One or more Paddle price IDs are not configured.');
}
}
return view('checkout.buy', [
'plans' => $plans,
'paddleToken' => $token,
'paddleEnvironment' => (string) ($paddle['environment'] ?? 'sandbox'),
]);
}
}
@@ -0,0 +1,38 @@
<?php
namespace App\Services\Licensing;
use App\Models\LicenseDeliveryOutbox;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Mail;
final class LicenseDeliveryService
{
public function deliverPending(int $limit = 20): int
{
$delivered = 0;
$pending = LicenseDeliveryOutbox::query()
->whereNull('delivered_at')
->whereNotNull('recipient_email')
->where('recipient_email', '!=', '')
->oldest()
->limit(max(1, min($limit, 100)))
->get();
foreach ($pending as $outbox) {
$plain = Crypt::decryptString($outbox->encrypted_license_key);
$recipient = strtolower(trim((string) $outbox->recipient_email));
if ($recipient === '') continue;
Mail::raw(
"Thank you for choosing Rsync Studio.\n\nYour licence key is:\n\n{$plain}\n\nOpen Rsync Studio → Settings → Licence and enter this key to activate your Mac.\n\nKeep this key private. You can manage activations from the Rsync Studio licence portal.",
fn ($message) => $message->to($recipient)->subject('Your Rsync Studio licence key')
);
$outbox->update(['delivered_at' => now()]);
$delivered++;
}
return $delivered;
}
}