cacheRemember('system:marketplace', 86400, function () { $settings = app(MarketplaceSettings::class); return [ 'tiktok_shop_platform_commission' => $this->presentFeeRule($settings->tiktok_shop_platform_commission), 'tiktok_shop_logistics_service_fee' => $this->presentFeeRule($settings->tiktok_shop_logistics_service_fee), 'tiktok_shop_dynamic_commission' => $this->presentFeeRule($settings->tiktok_shop_dynamic_commission), 'tiktok_shop_order_processing_fee' => $this->presentFeeRule($settings->tiktok_shop_order_processing_fee), 'tiktok_shop_affiliate' => $this->presentFeeRule($settings->tiktok_shop_affiliate), 'tiktok_shop_pre_order_service_fee' => $this->presentFeeRule($settings->tiktok_shop_pre_order_service_fee), 'shopee_admin_fee' => $this->presentFeeRule($settings->shopee_admin_fee), 'shopee_program_fee' => $this->presentFeeRule($settings->shopee_program_fee), 'shopee_shipping_savings' => $this->presentFeeRule($settings->shopee_shipping_savings), 'shopee_premium' => $this->presentFeeRule($settings->shopee_premium), 'shopee_service_fee' => $this->presentFeeRule($settings->shopee_service_fee), 'shopee_order_processing_fee' => $this->presentFeeRule($settings->shopee_order_processing_fee), 'shopee_ams_commission_fee' => $this->presentFeeRule($settings->shopee_ams_commission_fee), 'shopee_pre_order' => $this->presentFeeRule($settings->shopee_pre_order), 'shopee_live_extra' => $this->presentFeeRule($settings->shopee_live_extra), ]; }); } public function updateMarketplace(array $validated, User $user): void { $this->runInTransaction( function () use ($validated, $user): void { $this->saveSettings($validated); if (! $user->can(Permission::OWNER_VERIFICATIONS_VERIFY->value)) { $this->pushNotificationService->sendToRoles( '⚙️ Pengaturan Marketplace Diubah', "Pengaturan marketplace telah diubah oleh '{$user->username}'.", ['owner', 'developer'], route('admin.system.settings.index'), ); } }, 'Gagal memperbarui pengaturan marketplace', ); } public function saveSettings(array $validated): void { $settings = app(MarketplaceSettings::class); foreach ($this->tiktokFeeKeys() as $key) { $settings->{$key} = $this->normalizeFeeRule($validated[$key]); } foreach ($this->shopeeFeeKeys() as $key) { $settings->{$key} = $this->normalizeFeeRule($validated[$key]); } $settings->save(); $this->cacheForget('system:marketplace'); } public function applyVerificationRequest(OwnerVerificationRequest $request): void { $this->runInTransaction( function () use ($request): void { $newPayload = $request->payload['new'] ?? []; $this->saveSettings($newPayload); $this->cacheForget('system:marketplace'); }, 'Gagal menerapkan pengajuan verifikasi owner', ); } public function buildOrderSnapshot(OrderChannel $channel, int $totalAmount, array $lineItems, bool $isAffiliate = false): ?array { $feeSnapshot = $this->feeRulesForChannel($channel); if ($feeSnapshot === null) { return null; } if (! $isAffiliate) { $feeSnapshot['fees'] = $this->excludeAffiliateFee($feeSnapshot['fees'], $channel); } $calculation = app(MarketplaceFeeCalculator::class)->calculate( $feeSnapshot['fees'], $totalAmount, $lineItems, ); return [ 'platform' => $feeSnapshot['platform'], 'is_affiliate' => $isAffiliate, 'fees' => $feeSnapshot['fees'], 'base_amount' => $totalAmount, 'base_amount_formatted' => 'Rp '.number_format($totalAmount, 0, ',', '.'), 'results' => $calculation['results'], 'total_fee_amount' => $calculation['total_fee_amount'], 'total_fee_amount_formatted' => 'Rp '.number_format($calculation['total_fee_amount'], 0, ',', '.'), 'net_amount' => $calculation['net_amount'], 'net_amount_formatted' => 'Rp '.number_format($calculation['net_amount'], 0, ',', '.'), ]; } private function excludeAffiliateFee(array $fees, OrderChannel $channel): array { $affiliateKey = match ($channel) { OrderChannel::TIKTOK => 'tiktok_shop_affiliate', OrderChannel::SHOPEE => 'ams_commission_fee', default => null, }; if ($affiliateKey !== null && isset($fees[$affiliateKey])) { $fees[$affiliateKey] = [ 'scope' => $fees[$affiliateKey]['scope'], 'value_type' => $fees[$affiliateKey]['value_type'], 'value' => 0, ]; } return $fees; } private function feeRulesForChannel(OrderChannel $channel): ?array { $settings = app(MarketplaceSettings::class); return match ($channel) { OrderChannel::TIKTOK => [ 'platform' => 'tiktok', 'fees' => [ 'platform_commission' => $this->presentFeeRule($settings->tiktok_shop_platform_commission), 'logistics_service_fee' => $this->presentFeeRule($settings->tiktok_shop_logistics_service_fee), 'dynamic_commission' => $this->presentFeeRule($settings->tiktok_shop_dynamic_commission), 'order_processing_fee' => $this->presentFeeRule($settings->tiktok_shop_order_processing_fee), 'affiliate' => $this->presentFeeRule($settings->tiktok_shop_affiliate), 'pre_order_service_fee' => $this->presentFeeRule($settings->tiktok_shop_pre_order_service_fee), ], ], OrderChannel::SHOPEE => [ 'platform' => 'shopee', 'fees' => [ 'admin_fee' => $this->presentFeeRule($settings->shopee_admin_fee), 'program_fee' => $this->presentFeeRule($settings->shopee_program_fee), 'shipping_savings' => $this->presentFeeRule($settings->shopee_shipping_savings), 'premium' => $this->presentFeeRule($settings->shopee_premium), 'service_fee' => $this->presentFeeRule($settings->shopee_service_fee), 'order_processing_fee' => $this->presentFeeRule($settings->shopee_order_processing_fee), 'ams_commission_fee' => $this->presentFeeRule($settings->shopee_ams_commission_fee), 'pre_order' => $this->presentFeeRule($settings->shopee_pre_order), 'live_extra' => $this->presentFeeRule($settings->shopee_live_extra), ], ], OrderChannel::STORE => null, }; } private function presentFeeRule(array $data): array { return MarketplaceFeeRule::fromArray($data)->toArray(); } private function normalizeFeeRule(array $data): array { return MarketplaceFeeRule::fromArray($data)->toArray(); } }