Add PayPal support for add-on and gift voucher checkout

This commit is contained in:
Codex Agent
2026-02-04 14:54:40 +01:00
parent 7025418d9e
commit 17025df47b
24 changed files with 1599 additions and 34 deletions

View File

@@ -81,6 +81,48 @@ class GiftVoucherService
return $voucher;
}
/**
* Create or finalize a voucher from a PayPal capture payload.
*
* @param array<string, mixed> $payload
*/
public function issueFromPayPal(GiftVoucher $voucher, array $payload, ?string $orderId = null): GiftVoucher
{
if (in_array($voucher->status, [GiftVoucher::STATUS_ISSUED, GiftVoucher::STATUS_REDEEMED], true)) {
return $voucher;
}
$captureId = Arr::get($payload, 'purchase_units.0.payments.captures.0.id')
?? Arr::get($payload, 'id');
$locale = Arr::get($voucher->metadata ?? [], 'app_locale') ?? app()->getLocale();
$voucher->forceFill([
'status' => GiftVoucher::STATUS_ISSUED,
'paypal_order_id' => $orderId ?? $voucher->paypal_order_id,
'paypal_capture_id' => is_string($captureId) ? $captureId : $voucher->paypal_capture_id,
'metadata' => array_merge($voucher->metadata ?? [], array_filter([
'paypal_order_id' => $orderId,
'paypal_capture_id' => is_string($captureId) ? $captureId : null,
'paypal_status' => $payload['status'] ?? null,
'paypal_captured_at' => now()->toIso8601String(),
])),
])->save();
if (! $voucher->coupon_id) {
$coupon = $this->createCouponForVoucher($voucher);
$voucher->forceFill(['coupon_id' => $coupon->id])->save();
}
$notificationsSent = (bool) Arr::get($voucher->metadata ?? [], 'notifications_sent', false);
if (! $notificationsSent) {
$this->sendNotifications($voucher, locale: $locale);
}
return $voucher;
}
public function resend(GiftVoucher $voucher, ?string $locale = null, ?bool $recipientOnly = null): void
{
$this->sendNotifications($voucher, force: true, locale: $locale, recipientOnly: $recipientOnly);
@@ -152,6 +194,31 @@ class GiftVoucherService
return $response;
}
/**
* @param array<string, mixed> $payload
*/
public function markRefundedFromPayPal(GiftVoucher $voucher, array $payload = []): void
{
if ($voucher->isRefunded()) {
return;
}
$voucher->forceFill([
'status' => GiftVoucher::STATUS_REFUNDED,
'refunded_at' => now(),
'metadata' => array_merge($voucher->metadata ?? [], array_filter([
'paypal_refund_payload' => $payload ?: null,
])),
])->save();
if ($voucher->coupon) {
$voucher->coupon->forceFill([
'status' => CouponStatus::ARCHIVED,
'enabled_for_checkout' => false,
])->save();
}
}
protected function createCouponForVoucher(GiftVoucher $voucher): Coupon
{
$packages = $this->eligiblePackages();