Fix Paddle coupon payload
This commit is contained in:
@@ -88,19 +88,17 @@ class PaddleDiscountService
|
|||||||
protected function buildDiscountPayload(Coupon $coupon): array
|
protected function buildDiscountPayload(Coupon $coupon): array
|
||||||
{
|
{
|
||||||
$payload = [
|
$payload = [
|
||||||
'name' => $coupon->name,
|
|
||||||
'code' => $coupon->code,
|
'code' => $coupon->code,
|
||||||
'type' => $this->mapType($coupon->type),
|
'type' => $this->mapType($coupon->type),
|
||||||
'amount' => $this->formatAmount($coupon),
|
'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,
|
'enabled_for_checkout' => $coupon->enabled_for_checkout,
|
||||||
'description' => $coupon->description,
|
'description' => $this->resolveDescription($coupon),
|
||||||
'mode' => $coupon->paddle_mode ?? 'standard',
|
'mode' => $coupon->paddle_mode ?? 'standard',
|
||||||
'usage_limit' => $coupon->usage_limit,
|
'usage_limit' => $coupon->usage_limit,
|
||||||
'maximum_recurring_intervals' => null,
|
'maximum_recurring_intervals' => null,
|
||||||
'recur' => false,
|
'recur' => false,
|
||||||
'restrict_to' => $this->resolveRestrictions($coupon),
|
'restrict_to' => $this->resolveRestrictions($coupon),
|
||||||
'starts_at' => optional($coupon->starts_at)?->toIso8601String(),
|
|
||||||
'expires_at' => optional($coupon->ends_at)?->toIso8601String(),
|
'expires_at' => optional($coupon->ends_at)?->toIso8601String(),
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -146,4 +144,27 @@ class PaddleDiscountService
|
|||||||
|
|
||||||
return $prices->isEmpty() ? null : $prices->all();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
88
tests/Unit/PaddleDiscountServiceTest.php
Normal file
88
tests/Unit/PaddleDiscountServiceTest.php
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Unit;
|
||||||
|
|
||||||
|
use App\Enums\CouponType;
|
||||||
|
use App\Models\Coupon;
|
||||||
|
use App\Services\Paddle\PaddleClient;
|
||||||
|
use App\Services\Paddle\PaddleDiscountService;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Mockery;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class PaddleDiscountServiceTest extends TestCase
|
||||||
|
{
|
||||||
|
use RefreshDatabase;
|
||||||
|
|
||||||
|
protected function tearDown(): void
|
||||||
|
{
|
||||||
|
parent::tearDown();
|
||||||
|
|
||||||
|
Mockery::close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_build_payload_uses_description_fallback_and_excludes_name_and_starts_at(): void
|
||||||
|
{
|
||||||
|
$coupon = Coupon::factory()->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<string, mixed>
|
||||||
|
*/
|
||||||
|
public function buildPayload(Coupon $coupon): array
|
||||||
|
{
|
||||||
|
return $this->buildDiscountPayload($coupon);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user