diff --git a/app/Services/Paddle/PaddleDiscountService.php b/app/Services/Paddle/PaddleDiscountService.php index 3820381..4a49927 100644 --- a/app/Services/Paddle/PaddleDiscountService.php +++ b/app/Services/Paddle/PaddleDiscountService.php @@ -88,19 +88,17 @@ class PaddleDiscountService protected function buildDiscountPayload(Coupon $coupon): array { $payload = [ - 'name' => $coupon->name, 'code' => $coupon->code, 'type' => $this->mapType($coupon->type), 'amount' => $this->formatAmount($coupon), - 'currency_code' => $coupon->currency ?? config('app.currency', 'EUR'), + 'currency_code' => Str::upper((string) ($coupon->currency ?? config('app.currency', 'EUR'))), 'enabled_for_checkout' => $coupon->enabled_for_checkout, - 'description' => $coupon->description, + 'description' => $this->resolveDescription($coupon), 'mode' => $coupon->paddle_mode ?? 'standard', 'usage_limit' => $coupon->usage_limit, 'maximum_recurring_intervals' => null, 'recur' => false, 'restrict_to' => $this->resolveRestrictions($coupon), - 'starts_at' => optional($coupon->starts_at)?->toIso8601String(), 'expires_at' => optional($coupon->ends_at)?->toIso8601String(), ]; @@ -146,4 +144,27 @@ class PaddleDiscountService return $prices->isEmpty() ? null : $prices->all(); } + + protected function resolveDescription(Coupon $coupon): string + { + $description = trim((string) ($coupon->description ?? '')); + + if ($description !== '') { + return $description; + } + + $name = trim((string) ($coupon->name ?? '')); + + if ($name !== '') { + return $name; + } + + $code = trim((string) ($coupon->code ?? '')); + + if ($code !== '') { + return sprintf('Coupon %s', $code); + } + + return sprintf('Coupon %d', $coupon->id); + } } diff --git a/tests/Unit/PaddleDiscountServiceTest.php b/tests/Unit/PaddleDiscountServiceTest.php new file mode 100644 index 0000000..a473b2a --- /dev/null +++ b/tests/Unit/PaddleDiscountServiceTest.php @@ -0,0 +1,88 @@ +create([ + 'name' => 'Launch Discount', + 'description' => null, + 'starts_at' => now()->subDay(), + 'ends_at' => now()->addWeek(), + 'type' => CouponType::PERCENTAGE, + 'amount' => 10, + ]); + + $service = new TestablePaddleDiscountService(Mockery::mock(PaddleClient::class)); + + $payload = $service->buildPayload($coupon); + + $this->assertSame('Launch Discount', $payload['description']); + $this->assertArrayNotHasKey('name', $payload); + $this->assertArrayNotHasKey('starts_at', $payload); + } + + public function test_build_payload_formats_flat_discount_amount_and_currency(): void + { + $coupon = Coupon::factory()->create([ + 'type' => CouponType::FLAT, + 'amount' => 25.50, + 'currency' => 'eur', + 'description' => 'Flat discount', + ]); + + $service = new TestablePaddleDiscountService(Mockery::mock(PaddleClient::class)); + + $payload = $service->buildPayload($coupon); + + $this->assertSame('2550', $payload['amount']); + $this->assertSame('EUR', $payload['currency_code']); + } + + public function test_build_payload_removes_currency_for_percentage_discounts(): void + { + $coupon = Coupon::factory()->create([ + 'type' => CouponType::PERCENTAGE, + 'amount' => 15, + 'currency' => 'EUR', + 'description' => 'Percent discount', + ]); + + $service = new TestablePaddleDiscountService(Mockery::mock(PaddleClient::class)); + + $payload = $service->buildPayload($coupon); + + $this->assertSame('15.00', $payload['amount']); + $this->assertArrayNotHasKey('currency_code', $payload); + } +} + +class TestablePaddleDiscountService extends PaddleDiscountService +{ + /** + * @return array + */ + public function buildPayload(Coupon $coupon): array + { + return $this->buildDiscountPayload($coupon); + } +}