File tree Expand file tree Collapse file tree 2 files changed +31
-1
lines changed Expand file tree Collapse file tree 2 files changed +31
-1
lines changed Original file line number Diff line number Diff line change @@ -137,7 +137,22 @@ defmodule Plausible.Billing do
137
137
defp handle_subscription_updated ( params ) do
138
138
subscription = Repo . get_by ( Subscription , paddle_subscription_id: params [ "subscription_id" ] )
139
139
140
- if subscription do
140
+ # In a situation where the subscription is paused and a payment succeeds, we
141
+ # get notified of two "subscription_updated" webhook alerts from Paddle at the
142
+ # same time.
143
+ #
144
+ # * one with an `old_status` of "paused", and a `status` of "past_due"
145
+ # * the other with an `old_status` of "past_due", and a `status` of "active"
146
+ #
147
+ # https://developer.paddle.com/classic/guides/zg9joji1mzu0mduy-payment-failures
148
+ #
149
+ # Relying on the time when the webhooks are sent has caused issues where
150
+ # subscriptions have ended up `past_due` after a successful payment. Therefore,
151
+ # we're now explicitly ignoring the first webhook (with the update that's not
152
+ # relevant to us).
153
+ irrelevant? = params [ "old_status" ] == "paused" && params [ "status" ] == "past_due"
154
+
155
+ if subscription && not irrelevant? do
141
156
subscription
142
157
|> Subscription . changeset ( format_subscription ( params ) )
143
158
|> Repo . update! ( )
Original file line number Diff line number Diff line change @@ -212,6 +212,21 @@ defmodule Plausible.BillingTest do
212
212
assert subscription . next_bill_amount == "12.00"
213
213
end
214
214
215
+ test "status update from 'paused' to 'past_due' is ignored" do
216
+ user = insert ( :user )
217
+ subscription = insert ( :subscription , user: user , status: Subscription.Status . paused ( ) )
218
+
219
+ % { @ subscription_updated_params | "old_status" => "paused" , "status" => "past_due" }
220
+ |> Map . merge ( % {
221
+ "subscription_id" => subscription . paddle_subscription_id ,
222
+ "passthrough" => user . id
223
+ } )
224
+ |> Billing . subscription_updated ( )
225
+
226
+ subscription = Repo . get_by ( Subscription , user_id: user . id )
227
+ assert subscription . status == Subscription.Status . paused ( )
228
+ end
229
+
215
230
test "unlocks sites if subscription is changed from past_due to active" do
216
231
user = insert ( :user )
217
232
subscription = insert ( :subscription , user: user , status: Subscription.Status . past_due ( ) )
You can’t perform that action at this time.
0 commit comments