Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the payment due date for banktransfers, when the order is changed #22

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions pretix_mollie/payment.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import json
import logging
import textwrap
import urllib.parse
from collections import OrderedDict
from datetime import timedelta

Expand Down Expand Up @@ -600,7 +599,7 @@ def execute_payment(self, request: HttpRequest, payment: OrderPayment, retry=Tru

def _get_payment_body(self, payment):
body = super()._get_payment_body(payment)
body['dueDate'] = (payment.order.expires.date() + timedelta(days=1)).isoformat()
body['dueDate'] = self.get_due_date(payment)
return body

def order_pending_mail_render(self, order, payment) -> str:
Expand Down Expand Up @@ -670,6 +669,44 @@ def payment_form_render(self, request) -> str:
ctx = {'request': request, 'event': self.event, 'settings': self.settings}
return template.render(ctx)

def get_due_date(self, payment):
# The due date is a little bit fuzzy, since we can (according to the Mollie API) only transmit YYYY-MM-DD,
# but internally they will convert it to UTC.
# An order.expiry of 05.07.2023 23:59 (GMT+02) would normally be communicated to Mollie as 2023-07-06. Upon
# an API-request, Mollie would however return "expiresAt": "2023-07-08T04:00:00+00:00"
# Takin into consideration GMT+2/UTC, this still gives an extra 2 hours - but we can't do anything about it.
return (payment.order.expires.date() + timedelta(days=1)).isoformat()

def update_payment_due(self, payment, retry=True):
payment_id = payment.info_data.get('id')
body = {
'dueDate': self.get_due_date(payment),
}

try:
req = requests.patch(
'https://api.mollie.com/v2/payments/{}'.format(payment_id),
json=body,
headers=self.request_headers
)
req.raise_for_status()
payment.info_data = req.json()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we create a log entry for this as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, can do.

except HTTPError:
logger.exception('Mollie error: %s' % req.text)
try:
payment.info_data = req.json()

if payment.info_data.get('status') == 401 and retry:
# Token might be expired, let's retry!
if refresh_mollie_token(self.event, False):
return self.update_payment_due(payment, retry=False)
except:
payment.info_data = {
'error': True,
'detail': req.text
}
raise PaymentException(_('Mollie reported an error: {}').format(payment.info_data.get('detail')))


class MollieBelfius(MollieMethod):
method = 'belfius'
Expand Down
20 changes: 15 additions & 5 deletions pretix_mollie/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@
import time
from collections import OrderedDict

import requests
from django import forms
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _
from django_scopes import scopes_disabled

from pretix.base.forms import SecretKeySettingsField
from pretix.base.models import Event_SettingsStore
from pretix.base.settings import GlobalSettingsObject, settings_hierarkey
from pretix.base.models import Event_SettingsStore, Order, OrderPayment
from pretix.base.settings import settings_hierarkey
from pretix.base.signals import (
logentry_display, periodic_task, register_global_settings,
register_payment_providers,
register_payment_providers, order_modified,
)
from pretix.helpers.urls import build_absolute_uri

from .forms import MollieKeyValidator
from .utils import refresh_mollie_token
from .tasks import extend_payment_deadline

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -101,3 +100,14 @@ def refresh_mollie_tokens(sender, **kwargs):
if rt not in seen:
refresh_mollie_token(es.object, True)
seen.add(rt)


@receiver(order_modified, dispatch_uid='mollie_order_modified')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pretix.base.services.orders.extend_order does not seem to trigger this signal

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, that kinda makes this whole thing obsolete...

I guess we could either introduce a new expiration_changed or emit the order_changed-signal from the service. Any preference?

def order_placed(order, **kwargs):
payment = order.payments.last()
if (
order.status == Order.STATUS_PENDING
and payment.provider == 'mollie_banktransfer'
and payment.state in (OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING)
):
extend_payment_deadline.apply_async(args=(payment.pk,))
13 changes: 13 additions & 0 deletions pretix_mollie/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from django_scopes import scopes_disabled

from pretix.base.models import OrderPayment
from pretix.celery_app import app


@app.task()
@scopes_disabled()
def extend_payment_deadline(payment):
payment = OrderPayment.objects.get(pk=payment)
pprov = payment.payment_provider

pprov.update_payment_due(payment)