Skip to content

Commit 0f42518

Browse files
authored
[1.x] Ignore manual paylinks (#89)
* Ignore manual paylinks * Add message
1 parent ec6a740 commit 0f42518

File tree

3 files changed

+67
-5
lines changed

3 files changed

+67
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Laravel\Paddle\Exceptions;
4+
5+
use Exception;
6+
7+
class InvalidPassthroughPayload extends Exception
8+
{
9+
//
10+
}

src/Http/Controllers/WebhookController.php

+20-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Laravel\Paddle\Events\SubscriptionUpdated;
1616
use Laravel\Paddle\Events\WebhookHandled;
1717
use Laravel\Paddle\Events\WebhookReceived;
18+
use Laravel\Paddle\Exceptions\InvalidPassthroughPayload;
1819
use Laravel\Paddle\Http\Middleware\VerifyWebhookSignature;
1920
use Laravel\Paddle\Receipt;
2021
use Laravel\Paddle\Subscription;
@@ -53,7 +54,11 @@ public function __invoke(Request $request)
5354
WebhookReceived::dispatch($payload);
5455

5556
if (method_exists($this, $method)) {
56-
$this->{$method}($payload);
57+
try {
58+
$this->{$method}($payload);
59+
} catch (InvalidPassthroughPayload $e) {
60+
return new Response('Webhook Skipped');
61+
}
5762

5863
WebhookHandled::dispatch($payload);
5964

@@ -142,17 +147,23 @@ protected function handleSubscriptionPaymentFailed(array $payload)
142147
*
143148
* @param array $payload
144149
* @return void
150+
*
151+
* @throws \Laravel\Paddle\Exceptions\InvalidPassthroughPayload
145152
*/
146153
protected function handleSubscriptionCreated(array $payload)
147154
{
148155
$passthrough = json_decode($payload['passthrough'], true);
149156

157+
if (! is_array($passthrough) || ! isset($passthrough['subscription_name'])) {
158+
throw new InvalidPassthroughPayload;
159+
}
160+
161+
$customer = $this->findOrCreateCustomer($payload['passthrough']);
162+
150163
$trialEndsAt = $payload['status'] === Subscription::STATUS_TRIALING
151164
? Carbon::createFromFormat('Y-m-d', $payload['next_bill_date'], 'UTC')->startOfDay()
152165
: null;
153166

154-
$customer = $this->findOrCreateCustomer($payload['passthrough']);
155-
156167
$subscription = $customer->subscriptions()->create([
157168
'name' => $passthrough['subscription_name'],
158169
'paddle_id' => $payload['subscription_id'],
@@ -238,11 +249,17 @@ protected function handleSubscriptionCancelled(array $payload)
238249
*
239250
* @param string $passthrough
240251
* @return \Laravel\Paddle\Billable
252+
*
253+
* @throws \Laravel\Paddle\Exceptions\InvalidPassthroughPayload
241254
*/
242255
protected function findOrCreateCustomer(string $passthrough)
243256
{
244257
$passthrough = json_decode($passthrough, true);
245258

259+
if (! is_array($passthrough) || ! isset($passthrough['billable_id'], $passthrough['billable_type'])) {
260+
throw new InvalidPassthroughPayload;
261+
}
262+
246263
return Customer::firstOrCreate([
247264
'billable_id' => $passthrough['billable_id'],
248265
'billable_type' => $passthrough['billable_type'],

tests/Feature/WebhooksTest.php

+37-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ public function test_it_can_handle_a_payment_succeeded_event()
6666
});
6767
}
6868

69-
/** @test */
7069
public function test_it_can_handle_a_payment_succeeded_event_when_billable_already_exists()
7170
{
7271
Event::fake();
@@ -214,7 +213,6 @@ public function test_it_can_handle_a_subscription_created_event()
214213
});
215214
}
216215

217-
/** @test */
218216
public function test_it_can_handle_a_subscription_created_event_if_billable_already_exists()
219217
{
220218
Event::fake();
@@ -336,4 +334,41 @@ public function test_it_can_handle_a_subscription_cancelled_event()
336334
return $event->subscription->paddle_plan === 2323;
337335
});
338336
}
337+
338+
/** @group Foo */
339+
public function test_manual_created_paylinks_without_passthrough_values_are_ignored()
340+
{
341+
Event::fake();
342+
343+
$user = $this->createUser();
344+
345+
$this->postJson('paddle/webhook', [
346+
'alert_name' => 'subscription_created',
347+
'user_id' => 'foo',
348+
'email' => $user->paddleEmail(),
349+
'passthrough' => '',
350+
'quantity' => 1,
351+
'status' => Subscription::STATUS_ACTIVE,
352+
'subscription_id' => 'bar',
353+
'subscription_plan_id' => 1234,
354+
])->assertOk();
355+
356+
$this->assertDatabaseMissing('customers', [
357+
'billable_id' => $user->id,
358+
'billable_type' => $user->getMorphClass(),
359+
]);
360+
361+
$this->assertDatabaseMissing('subscriptions', [
362+
'billable_id' => $user->id,
363+
'billable_type' => $user->getMorphClass(),
364+
'name' => 'main',
365+
'paddle_id' => 'bar',
366+
'paddle_plan' => 1234,
367+
'paddle_status' => Subscription::STATUS_ACTIVE,
368+
'quantity' => 1,
369+
'trial_ends_at' => null,
370+
]);
371+
372+
Event::assertNotDispatched(SubscriptionCreated::class);
373+
}
339374
}

0 commit comments

Comments
 (0)