switched to paddle inline checkout, removed paypal and most of stripe. added product sync between app and paddle.

This commit is contained in:
Codex Agent
2025-10-27 17:26:39 +01:00
parent ecf5a23b28
commit 5432456ffd
117 changed files with 4114 additions and 3639 deletions

View File

@@ -3,7 +3,11 @@
namespace App\Filament\Resources;
use App\Filament\Resources\PackageResource\Pages;
use App\Jobs\PullPackageFromPaddle;
use App\Jobs\SyncPackageToPaddle;
use App\Models\Package;
use BackedEnum;
use Filament\Actions;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteAction;
use Filament\Actions\DeleteBulkAction;
@@ -11,21 +15,23 @@ use Filament\Actions\EditAction;
use Filament\Actions\ViewAction;
use Filament\Forms\Components\CheckboxList;
use Filament\Forms\Components\MarkdownEditor;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Repeater;
use Filament\Schemas\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Schemas\Components\Tabs as SchemaTabs;
use Filament\Schemas\Components\Tabs\Tab as SchemaTab;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Tabs as SchemaTabs;
use Filament\Schemas\Components\Tabs\Tab as SchemaTab;
use Filament\Schemas\Schema;
use Filament\Tables;
use Filament\Tables\Columns\BadgeColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Illuminate\Support\Str;
use UnitEnum;
use BackedEnum;
class PackageResource extends Resource
{
@@ -150,6 +156,28 @@ class PackageResource extends Resource
->columnSpanFull()
->default([]),
]),
Section::make('Paddle Billing')
->columns(2)
->schema([
TextInput::make('paddle_product_id')
->label('Paddle Produkt-ID')
->maxLength(191)
->helperText('Produkt aus Paddle Billing. Leer lassen, wenn noch nicht synchronisiert.')
->placeholder('nicht verknüpft'),
TextInput::make('paddle_price_id')
->label('Paddle Preis-ID')
->maxLength(191)
->helperText('Preis-ID aus Paddle Billing, verknüpft mit diesem Paket.')
->placeholder('nicht verknüpft'),
Placeholder::make('paddle_sync_status')
->label('Sync-Status')
->content(fn (?Package $record) => $record?->paddle_sync_status ? Str::headline($record->paddle_sync_status) : '')
->columnSpanFull(),
Placeholder::make('paddle_synced_at')
->label('Zuletzt synchronisiert')
->content(fn (?Package $record) => $record?->paddle_synced_at ? $record->paddle_synced_at->diffForHumans() : '')
->columnSpanFull(),
]),
]);
}
@@ -214,6 +242,28 @@ class PackageResource extends Resource
->label('Features')
->wrap()
->formatStateUsing(fn ($state) => static::formatFeaturesForDisplay($state)),
TextColumn::make('paddle_product_id')
->label('Paddle Produkt')
->toggleable(isToggledHiddenByDefault: true)
->formatStateUsing(fn ($state) => $state ?: '-'),
TextColumn::make('paddle_price_id')
->label('Paddle Preis')
->toggleable(isToggledHiddenByDefault: true)
->formatStateUsing(fn ($state) => $state ?: '-'),
BadgeColumn::make('paddle_sync_status')
->label('Sync-Status')
->colors([
'success' => 'synced',
'warning' => 'syncing',
'info' => 'dry-run',
'danger' => ['failed', 'pull-failed'],
])
->formatStateUsing(fn ($state) => $state ? Str::headline($state) : null)
->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('paddle_synced_at')
->label('Sync am')
->dateTime()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
Tables\Filters\SelectFilter::make('type')
@@ -224,6 +274,35 @@ class PackageResource extends Resource
]),
])
->actions([
Actions\Action::make('syncPaddle')
->label('Mit Paddle abgleichen')
->icon('heroicon-o-cloud-arrow-up')
->color('success')
->requiresConfirmation()
->disabled(fn (Package $record) => $record->paddle_sync_status === 'syncing')
->action(function (Package $record) {
SyncPackageToPaddle::dispatch($record->id);
Notification::make()
->success()
->title('Paddle-Sync gestartet')
->body('Das Paket wird im Hintergrund mit Paddle abgeglichen.')
->send();
}),
Actions\Action::make('pullPaddle')
->label('Status von Paddle holen')
->icon('heroicon-o-cloud-arrow-down')
->disabled(fn (Package $record) => ! $record->paddle_product_id && ! $record->paddle_price_id)
->requiresConfirmation()
->action(function (Package $record) {
PullPackageFromPaddle::dispatch($record->id);
Notification::make()
->info()
->title('Paddle-Abgleich angefordert')
->body('Der aktuelle Stand aus Paddle wird geladen und hier hinterlegt.')
->send();
}),
ViewAction::make(),
EditAction::make(),
DeleteAction::make(),