Bank transfer: Minimal implementation of Swiss QR-bill (#2767)

Co-authored-by: Richard Schreiber <schreiber@rami.io>
This commit is contained in:
Raphael Michel
2022-09-14 17:53:23 +02:00
committed by GitHub
parent 9cdb1a9258
commit e45c162b3d
3 changed files with 105 additions and 21 deletions

View File

@@ -47,6 +47,7 @@ from i18nfield.forms import I18nTextInput
from i18nfield.strings import LazyI18nString from i18nfield.strings import LazyI18nString
from localflavor.generic.forms import BICFormField, IBANFormField from localflavor.generic.forms import BICFormField, IBANFormField
from localflavor.generic.validators import IBANValidator from localflavor.generic.validators import IBANValidator
from text_unidecode import unidecode
from pretix.base.models import Order, OrderPayment, OrderRefund from pretix.base.models import Order, OrderPayment, OrderRefund
from pretix.base.payment import BasePaymentProvider from pretix.base.payment import BasePaymentProvider
@@ -261,6 +262,51 @@ class BankTransfer(BasePaymentProvider):
} }
return template.render(ctx) return template.render(ctx)
def swiss_qrbill(self, payment):
if not self.settings.get('bank_details_sepa_iban') or not self.settings.get('bank_details_sepa_iban')[:2] in ('CH', 'LI'):
return
if self.event.currency not in ('EUR', 'CHF'):
return
if not self.event.settings.invoice_address_from or not self.event.settings.invoice_address_from_country:
return
data_fields = [
'SPC',
'0200',
'1',
self.settings.get('bank_details_sepa_iban'),
'K',
self.settings.get('bank_details_sepa_name')[:70],
self.event.settings.invoice_address_from.replace('\n', ', ')[:70],
(self.event.settings.invoice_address_from_zipcode + ' ' + self.event.settings.invoice_address_from_city)[:70],
'',
'',
str(self.event.settings.invoice_address_from_country),
'', # rfu
'', # rfu
'', # rfu
'', # rfu
'', # rfu
'', # rfu
'', # rfu
str(payment.amount),
self.event.currency,
'', # debtor address
'', # debtor address
'', # debtor address
'', # debtor address
'', # debtor address
'', # debtor address
'', # debtor address
'NON',
'', # structured reference
self._code(payment.order),
'EPD',
]
data_fields = [unidecode(d or '') for d in data_fields]
return '\r\n'.join(data_fields)
def payment_pending_render(self, request: HttpRequest, payment: OrderPayment): def payment_pending_render(self, request: HttpRequest, payment: OrderPayment):
template = get_template('pretixplugins/banktransfer/pending.html') template = get_template('pretixplugins/banktransfer/pending.html')
ctx = { ctx = {
@@ -269,6 +315,7 @@ class BankTransfer(BasePaymentProvider):
'order': payment.order, 'order': payment.order,
'amount': payment.amount, 'amount': payment.amount,
'settings': self.settings, 'settings': self.settings,
'swiss_qrbill': self.swiss_qrbill(payment),
'pending_description': self.settings.get('pending_description', as_type=LazyI18nString), 'pending_description': self.settings.get('pending_description', as_type=LazyI18nString),
'details': self.settings.get('bank_details', as_type=LazyI18nString), 'details': self.settings.get('bank_details', as_type=LazyI18nString),
} }

View File

@@ -0,0 +1,15 @@
.banktransfer-swiss-cross-overlay {
position: relative;
width: 150px;
height: 150px;
margin: 0 auto 10px;
}
.banktransfer-swiss-cross {
position: absolute;
width: 15.217%;
height: 15.217%;
left: 50%;
top: 50%;
margin-left: -7.609%;
margin-top: -7.609%;
}

View File

@@ -1,6 +1,7 @@
{% load i18n %} {% load i18n %}
{% load l10n %} {% load l10n %}
{% load commadecimal %} {% load commadecimal %}
{% load static %}
{% load dotdecimal %} {% load dotdecimal %}
{% load ibanformat %} {% load ibanformat %}
{% load money %} {% load money %}
@@ -41,18 +42,32 @@
</p> </p>
</div> </div>
{% if settings.bank_details_type == "sepa" %} {% if settings.bank_details_type == "sepa" %}
<div class="col-md-3 col-sm-6 hidden-xs text-center js-only"> <div class="col-md-6 col-sm-6 hidden-xs text-center js-only blank-after">
<h4>BezahlCode</h4> <ul class="nav nav-tabs" id="banktransfer_qrcodes_tabs" role="tablist">
<p> {% if swiss_qrbill %}
<a aria-label="{% trans "Open BezahlCode in your banking app to start the payment process." %}" href="bank://singlepaymentsepa?name={{ settings.bank_details_sepa_name|urlencode }}&iban={{ settings.bank_details_sepa_iban }}&bic={{ settings.bank_details_sepa_bic }}&amount={{ amount|commadecimal }}&reason={{ code }}&currency={{ event.currency }}"> <li class="active"><a href="#banktransfer_qrcodes_qrbill" role="tab" id="banktransfer_qrcodes_qrbill_tab" data-toggle="tab" aria-controls="banktransfer_qrcodes_qrbill" aria-expanded="true">QR-bill</a></li>
<script type="text/plain" data-size="150" data-replace-with-qr data-desc="{% trans 'BezahlCode for your order. Scan this image with your banking apps QR-Reader to start the payment process.' %}">bank://singlepaymentsepa?name={{ settings.bank_details_sepa_name|urlencode }}&iban={{ settings.bank_details_sepa_iban }}&bic={{ settings.bank_details_sepa_bic }}&amount={{ amount|commadecimal }}&reason={{ code }}&currency={{ event.currency }}</script> {% endif %}
</a> <li {% if not swiss_qrbill %}class="active"{% endif %}><a href="#banktransfer_qrcodes_girocode" role="tab" id="banktransfer_qrcodes_girocode_tab" data-toggle="tab" aria-controls="banktransfer_qrcodes_girocode" aria-expanded="{% if swiss_qrbill %}false{% else %}true{% endif %}">EPC-QR</a></li>
</p> <li class=""><a href="#banktransfer_qrcodes_bezahlcode" role="tab" id="banktransfer_qrcodes_bezahlcode_tab" data-toggle="tab" aria-controls="banktransfer_qrcodes_bezahlcode" aria-expanded="false">BezahlCode</a></li>
</div> </ul>
<div class="col-md-3 col-sm-6 hidden-xs text-center js-only"> <div class="tab-content" id="banktransfer_qrcodes_tabs_content">
<h4>GiroCode / EPC-QR</h4> {% if swiss_qrbill %}
<p> <div id="banktransfer_qrcodes_qrbill" class="tab-pane fade active in" role="tabpanel" aria-labelledby="banktransfer_qrcodes_qrbill_tab">
<script type="text/plain" data-size="150" data-replace-with-qr data-desc="{% trans 'GiroCode / EPC-QR for your order. Scan this image with your banking apps QR-Reader to start the payment process.' %}">BCD <p class="small">
{% trans "Scan the qr-code with your banking app" %}
</p>
<p class="banktransfer-swiss-cross-overlay">
<svg class="banktransfer-swiss-cross" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.8 19.8"><path stroke="#fff" stroke-width="1.436" d="M.7.7h18.4v18.4H.7z"/><path fill="#fff" d="M8.3 4h3.3v11H8.3z"/><path fill="#fff" d="M4.4 7.9h11v3.3h-11z"/></svg>
<script type="text/plain" data-size="150" data-replace-with-qr data-desc="{% trans 'Scan this image with your banking apps QR-Reader to start the payment process.' %}">{{swiss_qrbill}}</script>
</p>
</div>
{% endif %}
<div id="banktransfer_qrcodes_girocode" class="tab-pane fade {% if not swiss_qrbill %}active in{% endif %}" role="tabpanel" aria-labelledby="banktransfer_qrcodes_girocode_tab">
<p class="small">
{% trans "Scan the qr-code with your banking app" %}
</p>
<p>
<script type="text/plain" data-size="150" data-replace-with-qr data-desc="{% trans 'Scan this image with your banking apps QR-Reader to start the payment process.' %}">BCD
002 002
2 2
SCT SCT
@@ -65,15 +80,22 @@ SCT
{{ code }} {{ code }}
</script> </script>
</p> </p>
</div> </div>
<div class="visible-xs-block text-center"> <div id="banktransfer_qrcodes_bezahlcode" class="tab-pane fade" role="tabpanel" aria-labelledby="banktransfer_qrcodes_bezahlcode_tab">
<p> <p class="small">
<a href="bank://singlepaymentsepa?name={{ settings.bank_details_sepa_name|urlencode }}&iban={{ settings.bank_details_sepa_iban }}&bic={{ settings.bank_details_sepa_bic }}&amount={{ amount|commadecimal }}&reason={{ code }}&currency={{ event.currency }}" class="btn btn-default"> {% trans "Scan the qr-code with your banking app" %}
{% trans "Open banking app" %} </p>
</a><br> <p>
<small>{% trans "Requires that the app supports BezahlCode" %}</small> <a aria-label="{% trans "Open BezahlCode in your banking app to start the payment process." %}" href="bank://singlepaymentsepa?name={{ settings.bank_details_sepa_name|urlencode }}&iban={{ settings.bank_details_sepa_iban }}&bic={{ settings.bank_details_sepa_bic }}&amount={{ amount|commadecimal }}&reason={{ code }}&currency={{ event.currency }}">
</p> <script type="text/plain" data-size="150" data-replace-with-qr data-desc="{% trans 'Scan this image with your banking apps QR-Reader to start the payment process.' %}">bank://singlepaymentsepa?name={{ settings.bank_details_sepa_name|urlencode }}&iban={{ settings.bank_details_sepa_iban }}&bic={{ settings.bank_details_sepa_bic }}&amount={{ amount|commadecimal }}&reason={{ code }}&currency={{ event.currency }}</script>
</a>
</p>
</div>
</div>
</div> </div>
{% endif %} {% endif %}
</div> </div>
{% if swiss_qrbill %}
<link rel="stylesheet" href="{% static "pretixplugins/banktransfer/swisscross.css" %}">
{% endif %}