Migrate billing from Paddle to Lemon Squeezy
This commit is contained in:
@@ -4,7 +4,7 @@ namespace App\Filament\Resources\Coupons\Pages;
|
||||
|
||||
use App\Filament\Resources\Coupons\CouponResource;
|
||||
use App\Filament\Resources\Pages\AuditedCreateRecord;
|
||||
use App\Jobs\SyncCouponToPaddle;
|
||||
use App\Jobs\SyncCouponToLemonSqueezy;
|
||||
|
||||
class CreateCoupon extends AuditedCreateRecord
|
||||
{
|
||||
@@ -14,6 +14,6 @@ class CreateCoupon extends AuditedCreateRecord
|
||||
{
|
||||
parent::afterCreate();
|
||||
|
||||
SyncCouponToPaddle::dispatch($this->record);
|
||||
SyncCouponToLemonSqueezy::dispatch($this->record);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace App\Filament\Resources\Coupons\Pages;
|
||||
|
||||
use App\Filament\Resources\Coupons\CouponResource;
|
||||
use App\Filament\Resources\Pages\AuditedEditRecord;
|
||||
use App\Jobs\SyncCouponToPaddle;
|
||||
use App\Jobs\SyncCouponToLemonSqueezy;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\ForceDeleteAction;
|
||||
@@ -27,7 +27,7 @@ class EditCoupon extends AuditedEditRecord
|
||||
source: static::class
|
||||
);
|
||||
|
||||
SyncCouponToPaddle::dispatch($record, true);
|
||||
SyncCouponToLemonSqueezy::dispatch($record, true);
|
||||
}),
|
||||
ForceDeleteAction::make()
|
||||
->after(fn ($record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
@@ -48,6 +48,6 @@ class EditCoupon extends AuditedEditRecord
|
||||
{
|
||||
parent::afterSave();
|
||||
|
||||
SyncCouponToPaddle::dispatch($this->record);
|
||||
SyncCouponToLemonSqueezy::dispatch($this->record);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ class RedemptionsRelationManager extends RelationManager
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->recordTitleAttribute('paddle_transaction_id')
|
||||
->recordTitleAttribute('lemonsqueezy_order_id')
|
||||
->columns([
|
||||
TextColumn::make('tenant.name')
|
||||
->label(__('Tenant'))
|
||||
@@ -65,7 +65,7 @@ class RedemptionsRelationManager extends RelationManager
|
||||
'failed' => 'danger',
|
||||
default => 'warning',
|
||||
}),
|
||||
TextColumn::make('paddle_transaction_id')
|
||||
TextColumn::make('lemonsqueezy_order_id')
|
||||
->label(__('Transaction'))
|
||||
->copyable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
|
||||
@@ -123,22 +123,22 @@ class CouponForm
|
||||
->nullable()
|
||||
->columnSpanFull(),
|
||||
]),
|
||||
Section::make(__('Paddle sync'))
|
||||
Section::make(__('Lemon Squeezy sync'))
|
||||
->columns(2)
|
||||
->schema([
|
||||
Select::make('paddle_mode')
|
||||
->label(__('Paddle mode'))
|
||||
Select::make('lemonsqueezy_mode')
|
||||
->label(__('Lemon Squeezy mode'))
|
||||
->options([
|
||||
'standard' => __('Standard'),
|
||||
'custom' => __('Custom (one-off)'),
|
||||
])
|
||||
->default('standard'),
|
||||
Placeholder::make('paddle_discount_id')
|
||||
->label(__('Paddle Discount ID'))
|
||||
->content(fn ($record) => $record?->paddle_discount_id ?? '—'),
|
||||
Placeholder::make('paddle_last_synced_at')
|
||||
Placeholder::make('lemonsqueezy_discount_id')
|
||||
->label(__('Lemon Squeezy Discount ID'))
|
||||
->content(fn ($record) => $record?->lemonsqueezy_discount_id ?? '—'),
|
||||
Placeholder::make('lemonsqueezy_last_synced_at')
|
||||
->label(__('Last synced'))
|
||||
->content(fn ($record) => $record?->paddle_last_synced_at?->diffForHumans() ?? '—'),
|
||||
->content(fn ($record) => $record?->lemonsqueezy_last_synced_at?->diffForHumans() ?? '—'),
|
||||
Placeholder::make('redemptions_count')
|
||||
->label(__('Total redemptions'))
|
||||
->content(fn ($record) => number_format($record?->redemptions_count ?? 0)),
|
||||
|
||||
@@ -63,17 +63,17 @@ class CouponInfolist
|
||||
TextEntry::make('description')->label(__('Description'))->columnSpanFull(),
|
||||
KeyValueEntry::make('metadata')->label(__('Metadata'))->columnSpanFull(),
|
||||
]),
|
||||
Section::make(__('Paddle'))
|
||||
Section::make(__('Lemon Squeezy'))
|
||||
->columns(3)
|
||||
->schema([
|
||||
TextEntry::make('paddle_discount_id')
|
||||
TextEntry::make('lemonsqueezy_discount_id')
|
||||
->label(__('Discount ID'))
|
||||
->copyable()
|
||||
->placeholder('—'),
|
||||
TextEntry::make('paddle_last_synced_at')
|
||||
TextEntry::make('lemonsqueezy_last_synced_at')
|
||||
->label(__('Last synced'))
|
||||
->state(fn ($record) => $record?->paddle_last_synced_at?->diffForHumans() ?? '—'),
|
||||
TextEntry::make('paddle_mode')
|
||||
->state(fn ($record) => $record?->lemonsqueezy_last_synced_at?->diffForHumans() ?? '—'),
|
||||
TextEntry::make('lemonsqueezy_mode')
|
||||
->label(__('Mode'))
|
||||
->badge()
|
||||
->placeholder('standard'),
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace App\Filament\Resources\Coupons\Tables;
|
||||
|
||||
use App\Enums\CouponStatus;
|
||||
use App\Enums\CouponType;
|
||||
use App\Jobs\SyncCouponToPaddle;
|
||||
use App\Jobs\SyncCouponToLemonSqueezy;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
@@ -105,9 +105,9 @@ class CouponsTable
|
||||
static::class
|
||||
)),
|
||||
Action::make('sync')
|
||||
->label(__('Sync to Paddle'))
|
||||
->label(__('Sync to Lemon Squeezy'))
|
||||
->icon('heroicon-m-arrow-path')
|
||||
->action(fn ($record) => SyncCouponToPaddle::dispatch($record))
|
||||
->action(fn ($record) => SyncCouponToLemonSqueezy::dispatch($record))
|
||||
->requiresConfirmation(),
|
||||
])
|
||||
->toolbarActions([
|
||||
|
||||
@@ -63,8 +63,8 @@ class GiftVoucherResource extends Resource
|
||||
->label('Empfänger')
|
||||
->toggleable()
|
||||
->searchable(),
|
||||
TextColumn::make('paddle_transaction_id')
|
||||
->label('Paddle Tx')
|
||||
TextColumn::make('lemonsqueezy_order_id')
|
||||
->label('Lemon Squeezy Order')
|
||||
->toggleable()
|
||||
->copyable()
|
||||
->wrap(),
|
||||
|
||||
@@ -46,24 +46,27 @@ class ListGiftVouchers extends ListRecords
|
||||
])
|
||||
->action(function (array $data, GiftVoucherService $service): void {
|
||||
$payload = [
|
||||
'id' => null,
|
||||
'metadata' => [
|
||||
'type' => 'gift_voucher',
|
||||
'purchaser_email' => $data['purchaser_email'],
|
||||
'recipient_email' => $data['recipient_email'] ?? null,
|
||||
'recipient_name' => $data['recipient_name'] ?? null,
|
||||
'message' => $data['message'] ?? null,
|
||||
'gift_code' => $data['code'] ?? null,
|
||||
'meta' => [
|
||||
'custom_data' => [
|
||||
'type' => 'gift_voucher',
|
||||
'purchaser_email' => $data['purchaser_email'],
|
||||
'recipient_email' => $data['recipient_email'] ?? null,
|
||||
'recipient_name' => $data['recipient_name'] ?? null,
|
||||
'message' => $data['message'] ?? null,
|
||||
'gift_code' => $data['code'] ?? null,
|
||||
],
|
||||
],
|
||||
'currency_code' => $data['currency'] ?? 'EUR',
|
||||
'totals' => [
|
||||
'grand_total' => [
|
||||
'amount' => (float) $data['amount'],
|
||||
'data' => [
|
||||
'id' => 'manual_'.Str::uuid(),
|
||||
'attributes' => [
|
||||
'currency' => $data['currency'] ?? 'EUR',
|
||||
'total' => (float) $data['amount'] * 100,
|
||||
'user_email' => $data['purchaser_email'],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$voucher = $service->issueFromPaddle($payload);
|
||||
$voucher = $service->issueFromLemonSqueezy($payload);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'issued',
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
|
||||
use App\Filament\Resources\PackageAddonResource\Pages;
|
||||
use App\Jobs\SyncPackageAddonToPaddle;
|
||||
use App\Jobs\SyncPackageAddonToLemonSqueezy;
|
||||
use App\Models\PackageAddon;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use Filament\Actions;
|
||||
@@ -50,9 +50,9 @@ class PackageAddonResource extends Resource
|
||||
->required()
|
||||
->unique(ignoreRecord: true)
|
||||
->maxLength(191),
|
||||
TextInput::make('price_id')
|
||||
->label('Paddle Preis-ID')
|
||||
->helperText('Paddle Billing Preis-ID für dieses Add-on')
|
||||
TextInput::make('variant_id')
|
||||
->label('Lemon Squeezy Variant-ID')
|
||||
->helperText('Variant-ID aus Lemon Squeezy für dieses Add-on')
|
||||
->maxLength(191),
|
||||
TextInput::make('sort')
|
||||
->label('Sortierung')
|
||||
@@ -96,8 +96,8 @@ class PackageAddonResource extends Resource
|
||||
->label('Schlüssel')
|
||||
->copyable()
|
||||
->sortable(),
|
||||
TextColumn::make('price_id')
|
||||
->label('Paddle Preis-ID')
|
||||
TextColumn::make('variant_id')
|
||||
->label('Lemon Squeezy Variant-ID')
|
||||
->toggleable()
|
||||
->copyable(),
|
||||
TextColumn::make('extra_photos')->label('Fotos +'),
|
||||
@@ -120,16 +120,16 @@ class PackageAddonResource extends Resource
|
||||
->label('Aktiv'),
|
||||
])
|
||||
->actions([
|
||||
Actions\Action::make('syncPaddle')
|
||||
->label('Mit Paddle synchronisieren')
|
||||
Actions\Action::make('syncLemonSqueezy')
|
||||
->label('Mit Lemon Squeezy synchronisieren')
|
||||
->icon('heroicon-o-cloud-arrow-up')
|
||||
->action(function (PackageAddon $record) {
|
||||
SyncPackageAddonToPaddle::dispatch($record->id);
|
||||
SyncPackageAddonToLemonSqueezy::dispatch($record->id);
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Paddle-Sync gestartet')
|
||||
->body('Das Add-on wird im Hintergrund mit Paddle abgeglichen.')
|
||||
->title('Lemon Squeezy-Sync gestartet')
|
||||
->body('Das Add-on wird im Hintergrund mit Lemon Squeezy abgeglichen.')
|
||||
->send();
|
||||
}),
|
||||
Actions\EditAction::make()
|
||||
|
||||
@@ -4,8 +4,8 @@ namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Clusters\WeeklyOps\WeeklyOpsCluster;
|
||||
use App\Filament\Resources\PackageResource\Pages;
|
||||
use App\Jobs\PullPackageFromPaddle;
|
||||
use App\Jobs\SyncPackageToPaddle;
|
||||
use App\Jobs\PullPackageFromLemonSqueezy;
|
||||
use App\Jobs\SyncPackageToLemonSqueezy;
|
||||
use App\Models\Package;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use BackedEnum;
|
||||
@@ -172,31 +172,31 @@ class PackageResource extends Resource
|
||||
->columnSpanFull()
|
||||
->default([]),
|
||||
]),
|
||||
Section::make('Paddle Billing')
|
||||
Section::make('Lemon Squeezy Billing')
|
||||
->columns(2)
|
||||
->schema([
|
||||
TextInput::make('paddle_product_id')
|
||||
->label('Paddle Produkt-ID')
|
||||
TextInput::make('lemonsqueezy_product_id')
|
||||
->label('Lemon Squeezy Produkt-ID')
|
||||
->maxLength(191)
|
||||
->helperText('Produkt aus Paddle Billing. Leer lassen, wenn noch nicht synchronisiert.')
|
||||
->helperText('Produkt aus Lemon Squeezy. Leer lassen, wenn noch nicht synchronisiert.')
|
||||
->placeholder('nicht verknüpft'),
|
||||
TextInput::make('paddle_price_id')
|
||||
->label('Paddle Preis-ID')
|
||||
TextInput::make('lemonsqueezy_variant_id')
|
||||
->label('Lemon Squeezy Variant-ID')
|
||||
->maxLength(191)
|
||||
->helperText('Preis-ID aus Paddle Billing, verknüpft mit diesem Paket.')
|
||||
->helperText('Variant-ID aus Lemon Squeezy, verknüpft mit diesem Paket.')
|
||||
->placeholder('nicht verknüpft'),
|
||||
Placeholder::make('paddle_sync_status')
|
||||
Placeholder::make('lemonsqueezy_sync_status')
|
||||
->label('Sync-Status')
|
||||
->content(fn (?Package $record) => $record?->paddle_sync_status ? Str::headline($record->paddle_sync_status) : '–')
|
||||
->content(fn (?Package $record) => $record?->lemonsqueezy_sync_status ? Str::headline($record->lemonsqueezy_sync_status) : '–')
|
||||
->columnSpanFull(),
|
||||
Placeholder::make('paddle_synced_at')
|
||||
Placeholder::make('lemonsqueezy_synced_at')
|
||||
->label('Zuletzt synchronisiert')
|
||||
->content(fn (?Package $record) => $record?->paddle_synced_at ? $record->paddle_synced_at->diffForHumans() : '–')
|
||||
->content(fn (?Package $record) => $record?->lemonsqueezy_synced_at ? $record->lemonsqueezy_synced_at->diffForHumans() : '–')
|
||||
->columnSpanFull(),
|
||||
Placeholder::make('paddle_sync_error')
|
||||
Placeholder::make('lemonsqueezy_sync_error')
|
||||
->label('Letzter Fehler')
|
||||
->content(fn (?Package $record) => $record?->paddle_sync_error_message ?? '–')
|
||||
->visible(fn (?Package $record) => filled($record?->paddle_sync_error_message))
|
||||
->content(fn (?Package $record) => $record?->lemonsqueezy_sync_error_message ?? '–')
|
||||
->visible(fn (?Package $record) => filled($record?->lemonsqueezy_sync_error_message))
|
||||
->columnSpanFull(),
|
||||
]),
|
||||
]);
|
||||
@@ -263,15 +263,15 @@ class PackageResource extends Resource
|
||||
->label('Features')
|
||||
->wrap()
|
||||
->formatStateUsing(fn ($state) => static::formatFeaturesForDisplay($state)),
|
||||
TextColumn::make('paddle_product_id')
|
||||
->label('Paddle Produkt')
|
||||
TextColumn::make('lemonsqueezy_product_id')
|
||||
->label('Lemon Squeezy Produkt')
|
||||
->toggleable(isToggledHiddenByDefault: true)
|
||||
->formatStateUsing(fn ($state) => $state ?: '-'),
|
||||
TextColumn::make('paddle_price_id')
|
||||
->label('Paddle Preis')
|
||||
TextColumn::make('lemonsqueezy_variant_id')
|
||||
->label('Lemon Squeezy Variant')
|
||||
->toggleable(isToggledHiddenByDefault: true)
|
||||
->formatStateUsing(fn ($state) => $state ?: '-'),
|
||||
BadgeColumn::make('paddle_sync_status')
|
||||
BadgeColumn::make('lemonsqueezy_sync_status')
|
||||
->label('Sync-Status')
|
||||
->colors([
|
||||
'success' => 'synced',
|
||||
@@ -281,13 +281,13 @@ class PackageResource extends Resource
|
||||
])
|
||||
->formatStateUsing(fn ($state) => $state ? Str::headline($state) : null)
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
TextColumn::make('paddle_synced_at')
|
||||
TextColumn::make('lemonsqueezy_synced_at')
|
||||
->label('Sync am')
|
||||
->dateTime()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
TextColumn::make('paddle_sync_error_message')
|
||||
TextColumn::make('lemonsqueezy_sync_error_message')
|
||||
->label('Sync-Fehler')
|
||||
->getStateUsing(fn (Package $record) => $record->paddle_sync_error_message)
|
||||
->getStateUsing(fn (Package $record) => $record->lemonsqueezy_sync_error_message)
|
||||
->wrap()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
@@ -301,43 +301,43 @@ class PackageResource extends Resource
|
||||
TrashedFilter::make(),
|
||||
])
|
||||
->actions([
|
||||
Actions\Action::make('syncPaddle')
|
||||
->label('Mit Paddle abgleichen')
|
||||
Actions\Action::make('syncLemonSqueezy')
|
||||
->label('Mit Lemon Squeezy abgleichen')
|
||||
->icon('heroicon-o-cloud-arrow-up')
|
||||
->color('success')
|
||||
->requiresConfirmation()
|
||||
->disabled(fn (Package $record) => $record->paddle_sync_status === 'syncing')
|
||||
->disabled(fn (Package $record) => $record->lemonsqueezy_sync_status === 'syncing')
|
||||
->action(function (Package $record) {
|
||||
SyncPackageToPaddle::dispatch($record->id);
|
||||
SyncPackageToLemonSqueezy::dispatch($record->id);
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Paddle-Sync gestartet')
|
||||
->body('Das Paket wird im Hintergrund mit Paddle abgeglichen.')
|
||||
->title('Lemon Squeezy-Sync gestartet')
|
||||
->body('Das Paket wird im Hintergrund mit Lemon Squeezy abgeglichen.')
|
||||
->send();
|
||||
}),
|
||||
Actions\Action::make('linkPaddle')
|
||||
->label('Paddle verknüpfen')
|
||||
Actions\Action::make('linkLemonSqueezy')
|
||||
->label('Lemon Squeezy verknüpfen')
|
||||
->icon('heroicon-o-link')
|
||||
->color('info')
|
||||
->form([
|
||||
TextInput::make('paddle_product_id')
|
||||
->label('Paddle Produkt-ID')
|
||||
TextInput::make('lemonsqueezy_product_id')
|
||||
->label('Lemon Squeezy Produkt-ID')
|
||||
->required()
|
||||
->maxLength(191),
|
||||
TextInput::make('paddle_price_id')
|
||||
->label('Paddle Preis-ID')
|
||||
TextInput::make('lemonsqueezy_variant_id')
|
||||
->label('Lemon Squeezy Variant-ID')
|
||||
->required()
|
||||
->maxLength(191),
|
||||
])
|
||||
->fillForm(fn (Package $record) => [
|
||||
'paddle_product_id' => $record->paddle_product_id,
|
||||
'paddle_price_id' => $record->paddle_price_id,
|
||||
'lemonsqueezy_product_id' => $record->lemonsqueezy_product_id,
|
||||
'lemonsqueezy_variant_id' => $record->lemonsqueezy_variant_id,
|
||||
])
|
||||
->action(function (Package $record, array $data): void {
|
||||
$record->linkPaddleIds($data['paddle_product_id'], $data['paddle_price_id']);
|
||||
$record->linkLemonSqueezyIds($data['lemonsqueezy_product_id'], $data['lemonsqueezy_variant_id']);
|
||||
|
||||
PullPackageFromPaddle::dispatch($record->id);
|
||||
PullPackageFromLemonSqueezy::dispatch($record->id);
|
||||
|
||||
app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||
'linked',
|
||||
@@ -348,22 +348,22 @@ class PackageResource extends Resource
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Paddle-Verknüpfung gespeichert')
|
||||
->title('Lemon Squeezy-Verknüpfung gespeichert')
|
||||
->body('Die IDs wurden gespeichert und ein Pull wurde angestoßen.')
|
||||
->send();
|
||||
}),
|
||||
Actions\Action::make('pullPaddle')
|
||||
->label('Status von Paddle holen')
|
||||
Actions\Action::make('pullLemonSqueezy')
|
||||
->label('Status von Lemon Squeezy holen')
|
||||
->icon('heroicon-o-cloud-arrow-down')
|
||||
->disabled(fn (Package $record) => ! $record->paddle_product_id && ! $record->paddle_price_id)
|
||||
->disabled(fn (Package $record) => ! $record->lemonsqueezy_product_id && ! $record->lemonsqueezy_variant_id)
|
||||
->requiresConfirmation()
|
||||
->action(function (Package $record) {
|
||||
PullPackageFromPaddle::dispatch($record->id);
|
||||
PullPackageFromLemonSqueezy::dispatch($record->id);
|
||||
|
||||
Notification::make()
|
||||
->info()
|
||||
->title('Paddle-Abgleich angefordert')
|
||||
->body('Der aktuelle Stand aus Paddle wird geladen und hier hinterlegt.')
|
||||
->title('Lemon Squeezy-Abgleich angefordert')
|
||||
->body('Der aktuelle Stand aus Lemon Squeezy wird geladen und hier hinterlegt.')
|
||||
->send();
|
||||
}),
|
||||
ViewAction::make(),
|
||||
|
||||
@@ -8,7 +8,7 @@ use App\Models\PackagePurchase;
|
||||
use App\Notifications\Customer\RefundReceipt;
|
||||
use App\Notifications\Ops\RefundProcessed;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use App\Services\Paddle\PaddleTransactionService;
|
||||
use App\Services\LemonSqueezy\LemonSqueezyOrderService;
|
||||
use BackedEnum;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
@@ -203,15 +203,15 @@ class PurchaseResource extends Resource
|
||||
$refundSuccess = true;
|
||||
$errorMessage = null;
|
||||
|
||||
if ($record->provider === 'paddle' && $record->provider_id) {
|
||||
if ($record->provider === 'lemonsqueezy' && $record->provider_id) {
|
||||
try {
|
||||
/** @var PaddleTransactionService $paddle */
|
||||
$paddle = App::make(PaddleTransactionService::class);
|
||||
$paddle->refund($record->provider_id, ['reason' => $reason]);
|
||||
/** @var LemonSqueezyOrderService $lemonsqueezy */
|
||||
$lemonsqueezy = App::make(LemonSqueezyOrderService::class);
|
||||
$lemonsqueezy->refund($record->provider_id, ['reason' => $reason]);
|
||||
} catch (\Throwable $exception) {
|
||||
$refundSuccess = false;
|
||||
$errorMessage = $exception->getMessage();
|
||||
Log::warning('Paddle refund failed', [
|
||||
Log::warning('Lemon Squeezy refund failed', [
|
||||
'purchase_id' => $record->id,
|
||||
'provider_id' => $record->provider_id,
|
||||
'error' => $exception->getMessage(),
|
||||
|
||||
@@ -35,7 +35,7 @@ class ViewPurchase extends ViewRecord
|
||||
->visible(fn ($record): bool => ! $record->refunded)
|
||||
->action(function ($record) {
|
||||
$record->update(['refunded' => true]);
|
||||
// TODO: Call Paddle API for actual refund
|
||||
// TODO: Call Lemon Squeezy API for actual refund
|
||||
|
||||
app(SuperAdminAuditLogger::class)->record(
|
||||
'purchase.refunded',
|
||||
|
||||
@@ -73,10 +73,10 @@ class TenantResource extends Resource
|
||||
->email()
|
||||
->required()
|
||||
->maxLength(255),
|
||||
TextInput::make('paddle_customer_id')
|
||||
->label('Paddle Customer ID')
|
||||
TextInput::make('lemonsqueezy_customer_id')
|
||||
->label('Lemon Squeezy Customer ID')
|
||||
->maxLength(191)
|
||||
->helperText('Verknuepfung mit Paddle Billing Kundenkonto.')
|
||||
->helperText('Verknüpfung mit Lemon Squeezy Kundenkonto.')
|
||||
->nullable(),
|
||||
TextInput::make('total_revenue')
|
||||
->label(__('admin.tenants.fields.total_revenue'))
|
||||
@@ -135,8 +135,8 @@ class TenantResource extends Resource
|
||||
->getStateUsing(fn (Tenant $record) => $record->user?->full_name ?? 'Unbekannt'),
|
||||
Tables\Columns\TextColumn::make('slug')->searchable(),
|
||||
Tables\Columns\TextColumn::make('contact_email'),
|
||||
Tables\Columns\TextColumn::make('paddle_customer_id')
|
||||
->label('Paddle Customer')
|
||||
Tables\Columns\TextColumn::make('lemonsqueezy_customer_id')
|
||||
->label('Lemon Squeezy Customer')
|
||||
->toggleable(isToggledHiddenByDefault: true)
|
||||
->formatStateUsing(fn ($state) => $state ?: '-'),
|
||||
Tables\Columns\TextColumn::make('active_reseller_package_id')
|
||||
|
||||
@@ -44,7 +44,7 @@ class PackagePurchasesRelationManager extends RelationManager
|
||||
Select::make('provider')
|
||||
->label('Anbieter')
|
||||
->options([
|
||||
'paddle' => 'Paddle',
|
||||
'lemonsqueezy' => 'Lemon Squeezy',
|
||||
'manual' => 'Manuell',
|
||||
'free' => 'Kostenlos',
|
||||
])
|
||||
@@ -89,7 +89,7 @@ class PackagePurchasesRelationManager extends RelationManager
|
||||
TextColumn::make('provider')
|
||||
->badge()
|
||||
->color(fn (string $state): string => match ($state) {
|
||||
'paddle' => 'success',
|
||||
'lemonsqueezy' => 'success',
|
||||
'manual' => 'gray',
|
||||
'free' => 'success',
|
||||
default => 'gray',
|
||||
@@ -116,7 +116,7 @@ class PackagePurchasesRelationManager extends RelationManager
|
||||
]),
|
||||
SelectFilter::make('provider')
|
||||
->options([
|
||||
'paddle' => 'Paddle',
|
||||
'lemonsqueezy' => 'Lemon Squeezy',
|
||||
'manual' => 'Manuell',
|
||||
'free' => 'Kostenlos',
|
||||
]),
|
||||
|
||||
@@ -40,10 +40,10 @@ class TenantPackagesRelationManager extends RelationManager
|
||||
DateTimePicker::make('expires_at')
|
||||
->label('Ablaufdatum')
|
||||
->required(),
|
||||
TextInput::make('paddle_subscription_id')
|
||||
->label('Paddle Subscription ID')
|
||||
TextInput::make('lemonsqueezy_subscription_id')
|
||||
->label('Lemon Squeezy Subscription ID')
|
||||
->maxLength(191)
|
||||
->helperText('Abonnement-ID aus Paddle Billing.')
|
||||
->helperText('Abonnement-ID aus Lemon Squeezy.')
|
||||
->nullable(),
|
||||
Toggle::make('active')
|
||||
->label('Aktiv'),
|
||||
@@ -75,8 +75,8 @@ class TenantPackagesRelationManager extends RelationManager
|
||||
TextColumn::make('expires_at')
|
||||
->dateTime()
|
||||
->sortable(),
|
||||
TextColumn::make('paddle_subscription_id')
|
||||
->label('Paddle Subscription')
|
||||
TextColumn::make('lemonsqueezy_subscription_id')
|
||||
->label('Lemon Squeezy Subscription')
|
||||
->toggleable(isToggledHiddenByDefault: true)
|
||||
->formatStateUsing(fn ($state) => $state ?: '-'),
|
||||
IconColumn::make('active')
|
||||
|
||||
@@ -22,8 +22,8 @@ class TenantInfolist
|
||||
TextEntry::make('user.full_name')
|
||||
->label(__('admin.tenants.fields.owner'))
|
||||
->state(fn (Tenant $record) => $record->user?->full_name ?? '—'),
|
||||
TextEntry::make('paddle_customer_id')
|
||||
->label('Paddle Customer ID')
|
||||
TextEntry::make('lemonsqueezy_customer_id')
|
||||
->label('Lemon Squeezy Customer ID')
|
||||
->placeholder('—'),
|
||||
TextEntry::make('total_revenue')
|
||||
->label(__('admin.tenants.fields.total_revenue'))
|
||||
|
||||
Reference in New Issue
Block a user