Skip to content

Commit 2f2ee81

Browse files
committed
Initial payment flow with Pix code and QR Code generation
1 parent aa58cdc commit 2f2ee81

4 files changed

Lines changed: 120 additions & 9 deletions

File tree

pretix_pix_manual/payment.py

Lines changed: 84 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
1+
import base64
12
from collections import OrderedDict
3+
from io import BytesIO
24

35
from django import forms
46
from django.core.exceptions import ValidationError
7+
from django.template.loader import get_template
58
from django.utils.translation import gettext_lazy as _
69

10+
import qrcode
11+
from pypix import Pix
12+
713
from pretix.base.payment import BasePaymentProvider
814

15+
from pretix_pix_manual.pix import PixInfo
16+
917

1018
def _is_valid_pix_key(pix_key):
1119
return True
@@ -30,7 +38,39 @@ def settings_form_fields(self):
3038
),
3139
required=True,
3240
),
33-
)
41+
),
42+
(
43+
"_proof_of_payment_email",
44+
forms.EmailField(
45+
label=_("Proof of payment e-mail"),
46+
help_text=_(
47+
"Email address that customers should use to send proof of payment",
48+
),
49+
required=True,
50+
),
51+
),
52+
(
53+
"_merchant_city",
54+
forms.CharField(
55+
label=_("Merchant city"),
56+
help_text=_(
57+
"City of payment beneficiary."
58+
),
59+
required=False,
60+
max_length=15,
61+
),
62+
),
63+
(
64+
"_merchant_name",
65+
forms.CharField(
66+
label=_("Merchant name"),
67+
help_text=_(
68+
"Name of payment beneficiary"
69+
),
70+
required=False,
71+
max_length=25,
72+
),
73+
),
3474
]
3575
return OrderedDict(custom_keys + default_form_fields)
3676

@@ -45,7 +85,7 @@ def settings_form_clean(self, cleaned_data):
4585

4686
def settings_content_render(self, request):
4787
return _(
48-
"This payment method will generate a Pix key with order information "
88+
"This payment method will generate a Pix code with order information "
4989
"that your customer can use to make the payment. Payment confirmation, "
5090
"cancellations, and refunds must be done manually."
5191
)
@@ -61,15 +101,50 @@ def payment_is_valid_session(self, request):
61101
return True
62102

63103
def checkout_confirm_render(self, request, order=None, info_data=None):
64-
return "Review order info"
104+
template = get_template('pretix_pix_manual/checkout_confirm.html')
105+
return template.render({})
65106

66107
def order_pending_mail_render(self, order, payment):
67108
return "Alguma coisa no email de confirmação"
68109

69110
def payment_pending_render(self, request, payment):
70-
"""
71-
Render customer-facing instructions on how to proceed with a pending payment
72-
73-
:return: HTML
74-
"""
75-
return "como vou pagar essa bodega"
111+
pix_key = self.settings.get('_pix_key')
112+
merchant_city = self.settings.get('_merchant_city') or ''
113+
merchant_name = self.settings.get('_merchant_name') or ''
114+
proof_of_payment_email = self.settings.get('_proof_of_payment_email')
115+
116+
txid = f"{self.event.id}-{payment.order.code}"
117+
amount = str(payment.amount)
118+
119+
pix = Pix()
120+
pix.set_pixkey(pix_key)
121+
pix.set_amount(amount)
122+
pix.set_merchant_city(merchant_city)
123+
pix.set_merchant_name(merchant_name)
124+
pix.set_txid(payment.order.code)
125+
pix_code = str(pix)
126+
127+
qr = qrcode.QRCode(
128+
version=1,
129+
error_correction=qrcode.constants.ERROR_CORRECT_M,
130+
box_size=6,
131+
border=4,
132+
)
133+
qr.add_data(pix_code)
134+
qr.make(fit=True)
135+
qr_code_img = qr.make_image(fill_color="black", back_color="white")
136+
137+
buffered = BytesIO()
138+
qr_code_img.save(buffered, format="PNG")
139+
img_str = base64.b64encode(buffered.getvalue())
140+
base64_qr_code = f"data:image/png;base64,{img_str.decode()}"
141+
142+
template = get_template('pretix_pix_manual/payment_pending.html')
143+
ctx = {
144+
'pix_code': pix_code,
145+
'base64_qr_code': base64_qr_code,
146+
'order_code': payment.order.code,
147+
'proof_of_payment_email': proof_of_payment_email,
148+
'contact_mail': self.event.settings.get("contact_mail"),
149+
}
150+
return template.render(ctx, request=request)

pretix_pix_manual/templates/pretix_pix_manual/.gitkeep

Whitespace-only changes.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{% load i18n %}
2+
3+
<p>{% blocktrans trimmed %}
4+
After completing your purchase, we will provide you with a <strong>Pix code</strong> that
5+
you must use to pay for your order.
6+
{% endblocktrans %}</p>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{% load i18n %}
2+
3+
<p>{% blocktrans trimmed %}
4+
Your order has been successfully received. Make the payment via Pix by scanning the
5+
QR Code below or copy and paste the following code into your banking app.
6+
{% endblocktrans %}</p>
7+
8+
<center><img src="{{ base64_qr_code }}" /></center>
9+
<center><p>{{ pix_code }}</p></center>
10+
11+
<hr/>
12+
13+
<p>{% blocktrans trimmed %}
14+
After making payment, send proof of payment to <strong>{{ proof_of_payment_email }}</strong>,
15+
including your order code <strong>{{ order_code }}</strong> in the subject line.
16+
{% endblocktrans %}</p>
17+
18+
<p>{% blocktrans trimmed %}
19+
<strong>IMPORTANT: Payment confirmation is handled manually by the event organizers.
20+
Therefore, if you do not send proof of payment, your order will remain pending payment,
21+
preventing you from checking in.</strong>
22+
{% endblocktrans %}</p>
23+
24+
<p>{% blocktrans trimmed %}
25+
If you have any questions regarding your order, please contact the event organizers
26+
{% endblocktrans %}
27+
{% if contact_mail %}at <strong>{{ contact_mail }}</strong>{% endif %}.
28+
</p>
29+
30+
<hr/>

0 commit comments

Comments
 (0)