mirror of
https://github.com/simple-login/app.git
synced 2024-11-10 09:13:45 +08:00
Handle failed payments subscriptions in paddle (#1327)
* Handle failed payments subscriptions in paddle * Added tests * Remove unused import * Remove unused import Co-authored-by: Adrià Casajús <adria.casajus@proton.ch>
This commit is contained in:
parent
d415974e3b
commit
faaff7e9b9
3 changed files with 71 additions and 1 deletions
32
app/paddle_callback.py
Normal file
32
app/paddle_callback.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
import arrow
|
||||
|
||||
from app.db import Session
|
||||
from app.email_utils import send_email, render
|
||||
from app.log import LOG
|
||||
from app.models import Subscription
|
||||
from app import paddle_utils
|
||||
|
||||
|
||||
def failed_payment(sub: Subscription, subscription_id: str):
|
||||
LOG.w(
|
||||
"Subscription failed payment %s for %s (sub %s)",
|
||||
subscription_id,
|
||||
sub.user,
|
||||
sub.id,
|
||||
)
|
||||
|
||||
sub.cancelled = True
|
||||
Session.commit()
|
||||
|
||||
user = sub.user
|
||||
|
||||
paddle_utils.cancel_subscription(subscription_id)
|
||||
|
||||
send_email(
|
||||
user.email,
|
||||
"SimpleLogin - your subscription has failed to be renewed",
|
||||
render(
|
||||
"transactional/subscription-cancel.txt",
|
||||
end_date=arrow.arrow.datetime.utcnow(),
|
||||
),
|
||||
)
|
|
@ -29,7 +29,7 @@ from sentry_sdk.integrations.flask import FlaskIntegration
|
|||
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
|
||||
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||
|
||||
from app import paddle_utils, config
|
||||
from app import paddle_utils, config, paddle_callback
|
||||
from app.admin_model import (
|
||||
SLAdminIndexView,
|
||||
UserAdmin,
|
||||
|
@ -543,6 +543,11 @@ def setup_paddle_callback(app: Flask):
|
|||
|
||||
sub: Subscription = Subscription.get_by(subscription_id=subscription_id)
|
||||
if sub:
|
||||
next_bill_date = request.form.get("next_bill_date")
|
||||
if not next_bill_date:
|
||||
paddle_callback.failed_payment(sub, subscription_id)
|
||||
return "OK"
|
||||
|
||||
LOG.d(
|
||||
"Update subscription %s %s on %s, next bill date %s",
|
||||
subscription_id,
|
||||
|
|
33
tests/test_paddle_callback.py
Normal file
33
tests/test_paddle_callback.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
import arrow
|
||||
|
||||
from app import paddle_callback
|
||||
from app.db import Session
|
||||
from app.mail_sender import mail_sender
|
||||
from app.models import Subscription, PlanEnum
|
||||
from tests.utils import create_new_user, random_token
|
||||
|
||||
|
||||
@mail_sender.store_emails_test_decorator
|
||||
def test_failed_payments():
|
||||
user = create_new_user()
|
||||
paddle_sub_id = random_token()
|
||||
sub = Subscription.create(
|
||||
user_id=user.id,
|
||||
cancel_url="https://checkout.paddle.com/subscription/cancel?user=1234",
|
||||
update_url="https://checkout.paddle.com/subscription/update?user=1234",
|
||||
subscription_id=paddle_sub_id,
|
||||
event_time=arrow.now(),
|
||||
next_bill_date=arrow.now().shift(days=10).date(),
|
||||
plan=PlanEnum.monthly,
|
||||
commit=True,
|
||||
)
|
||||
Session.commit()
|
||||
|
||||
paddle_callback.failed_payment(sub, paddle_sub_id)
|
||||
|
||||
sub = Subscription.get_by(subscription_id=paddle_sub_id)
|
||||
assert sub.cancelled
|
||||
|
||||
assert 1 == len(mail_sender.get_stored_emails())
|
||||
mail_sent = mail_sender.get_stored_emails()[0]
|
||||
assert mail_sent.envelope_to == user.email
|
Loading…
Reference in a new issue