'datetime', 'last_webhook_at' => 'datetime', 'metadata' => 'array', 'webhook_secret' => 'encrypted', ]; protected static function booted(): void { static::creating(function (self $store) { if (! $store->public_id) { $store->public_id = (string) Str::uuid(); } if (! $store->webhook_secret) { $store->webhook_secret = Str::random(48); } }); } public function user(): BelongsTo { return $this->belongsTo(User::class); } public function orders(): HasMany { return $this->hasMany(WooOrder::class); } public function products(): HasMany { return $this->hasMany(WooProduct::class); } public function categories(): HasMany { return $this->hasMany(WooCategory::class); } public function webhookUrl(): string { return rtrim((string) config('app.url'), '/').'/webhooks/woocommerce/'.$this->public_id; } /** * WooCommerce store currency (ISO 4217), synced from the connected site. * Does not fall back to GHS — unknown currency is empty until the next sync. */ public function currency(): string { $meta = is_array($this->metadata) ? $this->metadata : []; $currency = strtoupper(trim((string) ($meta['currency'] ?? ''))); return preg_match('/^[A-Z]{3}$/', $currency) === 1 ? $currency : ''; } public function currencySymbol(): string { $meta = is_array($this->metadata) ? $this->metadata : []; $symbol = trim((string) ($meta['currency_symbol'] ?? '')); if ($symbol !== '') { return $symbol; } return $this->currency(); } public function formatMoney(int|float|null $minor): string { if ($minor === null) { return '—'; } $currency = $this->currency(); $amount = number_format(((int) $minor) / 100, 2); return $currency !== '' ? $currency.' '.$amount : $amount; } }