Skip to content

Commit 75e9501

Browse files
authored
Improve Stripe event handling (#358)
1 parent 94aaf76 commit 75e9501

File tree

12 files changed

+386
-7
lines changed

12 files changed

+386
-7
lines changed
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
<?php
2+
3+
namespace HiEvents\DomainObjects\Generated;
4+
5+
/**
6+
* THIS FILE IS AUTOGENERATED - DO NOT EDIT IT DIRECTLY.
7+
* @package HiEvents\DomainObjects\Generated
8+
*/
9+
abstract class OrderRefundDomainObjectAbstract extends \HiEvents\DomainObjects\AbstractDomainObject
10+
{
11+
final public const SINGULAR_NAME = 'order_refund';
12+
final public const PLURAL_NAME = 'order_refunds';
13+
final public const ID = 'id';
14+
final public const ORDER_ID = 'order_id';
15+
final public const PAYMENT_PROVIDER = 'payment_provider';
16+
final public const REFUND_ID = 'refund_id';
17+
final public const AMOUNT = 'amount';
18+
final public const CURRENCY = 'currency';
19+
final public const STATUS = 'status';
20+
final public const REASON = 'reason';
21+
final public const METADATA = 'metadata';
22+
final public const CREATED_AT = 'created_at';
23+
final public const UPDATED_AT = 'updated_at';
24+
final public const DELETED_AT = 'deleted_at';
25+
26+
protected int $id;
27+
protected int $order_id;
28+
protected string $payment_provider;
29+
protected string $refund_id;
30+
protected float $amount;
31+
protected string $currency;
32+
protected ?string $status = null;
33+
protected ?string $reason = null;
34+
protected array|string|null $metadata = null;
35+
protected ?string $created_at = null;
36+
protected ?string $updated_at = null;
37+
protected ?string $deleted_at = null;
38+
39+
public function toArray(): array
40+
{
41+
return [
42+
'id' => $this->id ?? null,
43+
'order_id' => $this->order_id ?? null,
44+
'payment_provider' => $this->payment_provider ?? null,
45+
'refund_id' => $this->refund_id ?? null,
46+
'amount' => $this->amount ?? null,
47+
'currency' => $this->currency ?? null,
48+
'status' => $this->status ?? null,
49+
'reason' => $this->reason ?? null,
50+
'metadata' => $this->metadata ?? null,
51+
'created_at' => $this->created_at ?? null,
52+
'updated_at' => $this->updated_at ?? null,
53+
'deleted_at' => $this->deleted_at ?? null,
54+
];
55+
}
56+
57+
public function setId(int $id): self
58+
{
59+
$this->id = $id;
60+
return $this;
61+
}
62+
63+
public function getId(): int
64+
{
65+
return $this->id;
66+
}
67+
68+
public function setOrderId(int $order_id): self
69+
{
70+
$this->order_id = $order_id;
71+
return $this;
72+
}
73+
74+
public function getOrderId(): int
75+
{
76+
return $this->order_id;
77+
}
78+
79+
public function setPaymentProvider(string $payment_provider): self
80+
{
81+
$this->payment_provider = $payment_provider;
82+
return $this;
83+
}
84+
85+
public function getPaymentProvider(): string
86+
{
87+
return $this->payment_provider;
88+
}
89+
90+
public function setRefundId(string $refund_id): self
91+
{
92+
$this->refund_id = $refund_id;
93+
return $this;
94+
}
95+
96+
public function getRefundId(): string
97+
{
98+
return $this->refund_id;
99+
}
100+
101+
public function setAmount(float $amount): self
102+
{
103+
$this->amount = $amount;
104+
return $this;
105+
}
106+
107+
public function getAmount(): float
108+
{
109+
return $this->amount;
110+
}
111+
112+
public function setCurrency(string $currency): self
113+
{
114+
$this->currency = $currency;
115+
return $this;
116+
}
117+
118+
public function getCurrency(): string
119+
{
120+
return $this->currency;
121+
}
122+
123+
public function setStatus(?string $status): self
124+
{
125+
$this->status = $status;
126+
return $this;
127+
}
128+
129+
public function getStatus(): ?string
130+
{
131+
return $this->status;
132+
}
133+
134+
public function setReason(?string $reason): self
135+
{
136+
$this->reason = $reason;
137+
return $this;
138+
}
139+
140+
public function getReason(): ?string
141+
{
142+
return $this->reason;
143+
}
144+
145+
public function setMetadata(array|string|null $metadata): self
146+
{
147+
$this->metadata = $metadata;
148+
return $this;
149+
}
150+
151+
public function getMetadata(): array|string|null
152+
{
153+
return $this->metadata;
154+
}
155+
156+
public function setCreatedAt(?string $created_at): self
157+
{
158+
$this->created_at = $created_at;
159+
return $this;
160+
}
161+
162+
public function getCreatedAt(): ?string
163+
{
164+
return $this->created_at;
165+
}
166+
167+
public function setUpdatedAt(?string $updated_at): self
168+
{
169+
$this->updated_at = $updated_at;
170+
return $this;
171+
}
172+
173+
public function getUpdatedAt(): ?string
174+
{
175+
return $this->updated_at;
176+
}
177+
178+
public function setDeletedAt(?string $deleted_at): self
179+
{
180+
$this->deleted_at = $deleted_at;
181+
return $this;
182+
}
183+
184+
public function getDeletedAt(): ?string
185+
{
186+
return $this->deleted_at;
187+
}
188+
}

backend/app/DomainObjects/Generated/PersonalAccessTokenDomainObjectAbstract.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ abstract class PersonalAccessTokenDomainObjectAbstract extends \HiEvents\DomainO
1111
final public const SINGULAR_NAME = 'personal_access_token';
1212
final public const PLURAL_NAME = 'personal_access_tokens';
1313
final public const ID = 'id';
14+
final public const ACCOUNT_ID = 'account_id';
1415
final public const TOKENABLE_TYPE = 'tokenable_type';
1516
final public const TOKENABLE_ID = 'tokenable_id';
1617
final public const NAME = 'name';
@@ -22,6 +23,7 @@ abstract class PersonalAccessTokenDomainObjectAbstract extends \HiEvents\DomainO
2223
final public const UPDATED_AT = 'updated_at';
2324

2425
protected int $id;
26+
protected int $account_id;
2527
protected string $tokenable_type;
2628
protected int $tokenable_id;
2729
protected string $name;
@@ -36,6 +38,7 @@ public function toArray(): array
3638
{
3739
return [
3840
'id' => $this->id ?? null,
41+
'account_id' => $this->account_id ?? null,
3942
'tokenable_type' => $this->tokenable_type ?? null,
4043
'tokenable_id' => $this->tokenable_id ?? null,
4144
'name' => $this->name ?? null,
@@ -59,6 +62,17 @@ public function getId(): int
5962
return $this->id;
6063
}
6164

65+
public function setAccountId(int $account_id): self
66+
{
67+
$this->account_id = $account_id;
68+
return $this;
69+
}
70+
71+
public function getAccountId(): int
72+
{
73+
return $this->account_id;
74+
}
75+
6276
public function setTokenableType(string $tokenable_type): self
6377
{
6478
$this->tokenable_type = $tokenable_type;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace HiEvents\DomainObjects;
4+
5+
class OrderRefundDomainObject extends Generated\OrderRefundDomainObjectAbstract
6+
{
7+
}

backend/app/Models/OrderRefund.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace HiEvents\Models;
4+
5+
class OrderRefund extends BaseModel
6+
{
7+
protected function getCastMap(): array
8+
{
9+
return [
10+
'metadata' => 'array',
11+
];
12+
}
13+
14+
protected function getFillableFields(): array
15+
{
16+
return [];
17+
}
18+
}

backend/app/Providers/RepositoryServiceProvider.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use HiEvents\Repository\Eloquent\InvoiceRepository;
1919
use HiEvents\Repository\Eloquent\MessageRepository;
2020
use HiEvents\Repository\Eloquent\OrderItemRepository;
21+
use HiEvents\Repository\Eloquent\OrderRefundRepository;
2122
use HiEvents\Repository\Eloquent\OrderRepository;
2223
use HiEvents\Repository\Eloquent\OrganizerRepository;
2324
use HiEvents\Repository\Eloquent\PasswordResetRepository;
@@ -46,6 +47,7 @@
4647
use HiEvents\Repository\Interfaces\InvoiceRepositoryInterface;
4748
use HiEvents\Repository\Interfaces\MessageRepositoryInterface;
4849
use HiEvents\Repository\Interfaces\OrderItemRepositoryInterface;
50+
use HiEvents\Repository\Interfaces\OrderRefundRepositoryInterface;
4951
use HiEvents\Repository\Interfaces\OrderRepositoryInterface;
5052
use HiEvents\Repository\Interfaces\OrganizerRepositoryInterface;
5153
use HiEvents\Repository\Interfaces\PasswordResetRepositoryInterface;
@@ -96,6 +98,7 @@ class RepositoryServiceProvider extends ServiceProvider
9698
AttendeeCheckInRepositoryInterface::class => AttendeeCheckInRepository::class,
9799
ProductCategoryRepositoryInterface::class => ProductCategoryRepository::class,
98100
InvoiceRepositoryInterface::class => InvoiceRepository::class,
101+
OrderRefundRepositoryInterface::class => OrderRefundRepository::class,
99102
];
100103

101104
public function register(): void
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace HiEvents\Repository\Eloquent;
4+
5+
use HiEvents\DomainObjects\OrderRefundDomainObject;
6+
use HiEvents\Models\OrderRefund;
7+
use HiEvents\Repository\Interfaces\OrderRefundRepositoryInterface;
8+
9+
class OrderRefundRepository extends BaseRepository implements OrderRefundRepositoryInterface
10+
{
11+
protected function getModel(): string
12+
{
13+
return OrderRefund::class;
14+
}
15+
16+
public function getDomainObject(): string
17+
{
18+
return OrderRefundDomainObject::class;
19+
}
20+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace HiEvents\Repository\Interfaces;
4+
5+
use HiEvents\DomainObjects\OrderRefundDomainObject;
6+
7+
/**
8+
* @extends RepositoryInterface<OrderRefundDomainObject>
9+
*/
10+
interface OrderRefundRepositoryInterface extends RepositoryInterface
11+
{
12+
13+
}

backend/app/Services/Application/Handlers/Order/Payment/Stripe/GetPaymentIntentHandler.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
use Stripe\StripeClient;
1414
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
1515

16-
readonly class GetPaymentIntentHandler
16+
class GetPaymentIntentHandler
1717
{
1818
public function __construct(
19-
private StripeClient $stripeClient,
20-
private OrderRepositoryInterface $orderRepository,
21-
private LoggerInterface $logger,
22-
private PaymentIntentSucceededHandler $paymentIntentSucceededHandler,
19+
private readonly StripeClient $stripeClient,
20+
private readonly OrderRepositoryInterface $orderRepository,
21+
private readonly LoggerInterface $logger,
22+
private readonly PaymentIntentSucceededHandler $paymentIntentSucceededHandler,
2323
)
2424
{
2525
}

backend/app/Services/Application/Handlers/Order/Payment/Stripe/IncomingWebhookHandler.php

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919

2020
class IncomingWebhookHandler
2121
{
22+
private static array $validEvents = [
23+
Event::PAYMENT_INTENT_SUCCEEDED,
24+
Event::PAYMENT_INTENT_PAYMENT_FAILED,
25+
Event::CHARGE_REFUND_UPDATED,
26+
Event::ACCOUNT_UPDATED,
27+
];
28+
2229
public function __construct(
2330
private readonly ChargeRefundUpdatedHandler $refundEventHandlerService,
2431
private readonly PaymentIntentSucceededHandler $paymentIntentSucceededHandler,
@@ -44,6 +51,17 @@ public function handle(StripeWebhookDTO $webhookDTO): void
4451
config('services.stripe.webhook_secret'),
4552
);
4653

54+
if (!in_array($event->type, self::$validEvents, true)) {
55+
$this->logger->debug(__('Received a :event Stripe event, which has no handler', [
56+
'event' => $event->type,
57+
]), [
58+
'event_id' => $event->id,
59+
'event_type' => $event->type,
60+
]);
61+
62+
return;
63+
}
64+
4765
if ($this->hasEventBeenHandled($event)) {
4866
$this->logger->debug('Stripe event already handled', [
4967
'event_id' => $event->id,
@@ -69,8 +87,6 @@ public function handle(StripeWebhookDTO $webhookDTO): void
6987
case Event::ACCOUNT_UPDATED:
7088
$this->accountUpdateHandler->handleEvent($event->data->object);
7189
break;
72-
default:
73-
$this->logger->debug(sprintf('Unhandled Stripe webhook: %s', $event->type));
7490
}
7591

7692
$this->markEventAsHandled($event);
@@ -110,6 +126,10 @@ private function hasEventBeenHandled(Event $event): bool
110126

111127
private function markEventAsHandled(Event $event): void
112128
{
129+
$this->logger->info('Marking Stripe event as handled', [
130+
'event_id' => $event->id,
131+
'type' => $event->type,
132+
]);
113133
$this->cache->put('stripe_event_' . $event->id, true, now()->addMinutes(60));
114134
}
115135
}

0 commit comments

Comments
 (0)