101 lines
3.4 KiB
PHP
101 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services\GiftVouchers;
|
|
|
|
use App\Services\Paddle\PaddleClient;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Facades\App;
|
|
use Illuminate\Support\Str;
|
|
use Illuminate\Validation\ValidationException;
|
|
|
|
class GiftVoucherCheckoutService
|
|
{
|
|
public function __construct(private readonly PaddleClient $client) {}
|
|
|
|
/**
|
|
* @return array<int, array{key:string,label:string,amount:float,currency:string,paddle_price_id?:string|null,can_checkout:bool}>
|
|
*/
|
|
public function tiers(): array
|
|
{
|
|
return collect(config('gift-vouchers.tiers', []))
|
|
->map(function (array $tier): array {
|
|
$currency = Str::upper($tier['currency'] ?? 'EUR');
|
|
$priceId = $tier['paddle_price_id'] ?? null;
|
|
|
|
return [
|
|
'key' => $tier['key'],
|
|
'label' => $tier['label'],
|
|
'amount' => (float) $tier['amount'],
|
|
'currency' => $currency,
|
|
'paddle_price_id' => $priceId,
|
|
'can_checkout' => ! empty($priceId),
|
|
];
|
|
})
|
|
->values()
|
|
->all();
|
|
}
|
|
|
|
/**
|
|
* @param array{tier_key:string,purchaser_email:string,recipient_email?:string|null,recipient_name?:string|null,message?:string|null,success_url?:string|null,return_url?:string|null} $data
|
|
* @return array{checkout_url:?string,expires_at:?string,id:?string}
|
|
*/
|
|
public function create(array $data): array
|
|
{
|
|
$tier = $this->findTier($data['tier_key']);
|
|
|
|
if (! $tier || empty($tier['paddle_price_id'])) {
|
|
throw ValidationException::withMessages([
|
|
'tier_key' => __('Gift voucher is not available right now.'),
|
|
]);
|
|
}
|
|
|
|
$payload = [
|
|
'items' => [
|
|
[
|
|
'price_id' => $tier['paddle_price_id'],
|
|
'quantity' => 1,
|
|
],
|
|
],
|
|
'customer_email' => $data['purchaser_email'],
|
|
'metadata' => array_filter([
|
|
'type' => 'gift_voucher',
|
|
'tier_key' => $tier['key'],
|
|
'purchaser_email' => $data['purchaser_email'],
|
|
'recipient_email' => $data['recipient_email'] ?? null,
|
|
'recipient_name' => $data['recipient_name'] ?? null,
|
|
'message' => $data['message'] ?? null,
|
|
'app_locale' => App::getLocale(),
|
|
]),
|
|
'success_url' => $data['success_url'] ?? route('marketing.success', ['locale' => App::getLocale(), 'type' => 'gift']),
|
|
'cancel_url' => $data['return_url'] ?? route('packages', ['locale' => App::getLocale()]),
|
|
];
|
|
|
|
$response = $this->client->post('/checkout/links', $payload);
|
|
|
|
return [
|
|
'checkout_url' => Arr::get($response, 'data.url') ?? Arr::get($response, 'url'),
|
|
'expires_at' => Arr::get($response, 'data.expires_at') ?? Arr::get($response, 'expires_at'),
|
|
'id' => Arr::get($response, 'data.id') ?? Arr::get($response, 'id'),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>|null
|
|
*/
|
|
protected function findTier(string $key): ?array
|
|
{
|
|
$tiers = collect(config('gift-vouchers.tiers', []))
|
|
->keyBy('key');
|
|
|
|
$tier = $tiers->get($key);
|
|
|
|
if (! $tier) {
|
|
return null;
|
|
}
|
|
|
|
$tier['currency'] = Str::upper($tier['currency'] ?? 'EUR');
|
|
|
|
return $tier;
|
|
}
|
|
}
|