*/ public function createProduct(PackageAddon $addon, array $overrides = []): array { $payload = $this->buildProductPayload($addon, $overrides); return $this->extractEntity($this->client->post('/products', $payload)); } /** * @return array */ public function updateProduct(string $productId, PackageAddon $addon, array $overrides = []): array { $payload = $this->buildProductPayload($addon, $overrides); return $this->extractEntity($this->client->patch("/products/{$productId}", $payload)); } /** * @return array */ public function createPrice(PackageAddon $addon, string $productId, array $overrides = []): array { $payload = $this->buildPricePayload($addon, $productId, $overrides); return $this->extractEntity($this->client->post('/prices', $payload)); } /** * @return array */ public function updatePrice(string $priceId, PackageAddon $addon, array $overrides = []): array { $payload = $this->buildPricePayload($addon, $overrides['product_id'] ?? '', $overrides); return $this->extractEntity($this->client->patch("/prices/{$priceId}", $payload)); } /** * @return array */ public function buildProductPayload(PackageAddon $addon, array $overrides = []): array { $payload = array_merge([ 'name' => $overrides['name'] ?? $addon->label, 'description' => $overrides['description'] ?? sprintf('Fotospiel Add-on: %s', $addon->label), 'tax_category' => $overrides['tax_category'] ?? 'standard', 'type' => $overrides['type'] ?? 'standard', 'custom_data' => array_merge([ 'addon_key' => $addon->key, 'increments' => $addon->increments, ], $overrides['custom_data'] ?? []), ], Arr::except($overrides, ['tax_category', 'type', 'custom_data', 'name', 'description'])); return $this->cleanPayload($payload); } /** * @return array */ public function buildPricePayload(PackageAddon $addon, string $productId, array $overrides = []): array { $unitPrice = $overrides['unit_price'] ?? $this->defaultUnitPrice($addon); $payload = array_merge([ 'product_id' => $productId, 'description' => $overrides['description'] ?? $addon->label, 'unit_price' => $unitPrice, 'custom_data' => array_merge([ 'addon_key' => $addon->key, ], $overrides['custom_data'] ?? []), ], Arr::except($overrides, ['unit_price', 'description', 'custom_data', 'product_id'])); return $this->cleanPayload($payload); } /** * @param array $payload * @return array */ protected function extractEntity(array $payload): array { return Arr::get($payload, 'data', $payload); } /** * @param array $payload * @return array */ protected function cleanPayload(array $payload): array { $filtered = collect($payload) ->reject(static fn ($value) => $value === null || $value === '' || $value === []) ->all(); if (array_key_exists('custom_data', $filtered)) { $filtered['custom_data'] = collect($filtered['custom_data']) ->reject(static fn ($value) => $value === null || $value === '' || $value === []) ->all(); } return $filtered; } /** * @return array */ protected function defaultUnitPrice(PackageAddon $addon): array { $metaPrice = $addon->metadata['price_eur'] ?? null; if (! is_numeric($metaPrice)) { throw new PaddleException('No unit price specified for addon. Provide metadata[price_eur] or overrides.unit_price.'); } $amountCents = (int) round(((float) $metaPrice) * 100); return [ 'amount' => (string) $amountCents, 'currency_code' => 'EUR', ]; } }