Skip to content

Commit 3c7320a

Browse files
authored
Merge pull request #31 from Xpirix/switch_to_payrexx
Fix the payment system for credits top up
2 parents ff2d52c + d42eedf commit 3c7320a

File tree

15 files changed

+379
-15
lines changed

15 files changed

+379
-15
lines changed

.flake8

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ max-line-length = 79
55
# E12x continuation line indentation
66
# E251 no spaces around keyword / parameter equals
77
# E303 too many blank lines (3)
8-
ignore = E125,E126,E251,E303,W504,W60,F405,E501,E128
8+
ignore = E125,E126,E251,E303,W504,W60,F405,E501,E128,E111,E114,E121

deployment/.env.example

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,8 @@ SENTRY_RATE=0.2
7777
WEB_ENV=prod-ssl
7878

7979
# UWSGI Docker Image
80-
UWSGI_DOCKER_IMAGE=qgis/qgis-certification-uwsgi:latest
80+
UWSGI_DOCKER_IMAGE=qgis/qgis-certification-uwsgi:latest
81+
82+
# Payrexx
83+
PAYREXX_INSTANCE='qgis'
84+
PAYREXX_API_SECRET='your_payrexx_api_secret'

deployment/docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ services:
6666
- ADMIN_EMAIL=${ADMIN_EMAIL}
6767
- SENTRY_DSN=${SENTRY_DSN}
6868
- SENTRY_RATE=${SENTRY_RATE}
69+
- PAYREXX_INSTANCE=${PAYREXX_INSTANCE}
70+
- PAYREXX_API_SECRET=${PAYREXX_API_SECRET}
6971
volumes:
7072
- static-data:/home/web/static:rw
7173
- media-data:/home/web/media:rw

django_project/certification/admin.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from certification.models.checklist import Checklist
1919
from certification.models.organisation_checklist import OrganisationChecklist
2020
from certification.models.external_reviewer import ExternalReviewer
21+
from certification.models.credits_order import CreditsOrder
2122

2223

2324
class CertificateAdmin(admin.ModelAdmin):
@@ -195,6 +196,18 @@ class ExternalReviewerAdmin(admin.ModelAdmin):
195196
)
196197

197198

199+
class CreditsOrderAdmin(admin.ModelAdmin):
200+
list_display = (
201+
'organisation',
202+
'credits_requested',
203+
'credits_issued',
204+
'created_at',
205+
'updated_at'
206+
)
207+
list_filter = ('organisation', 'credits_issued')
208+
search_fields = ('organisation__name',)
209+
210+
198211
admin.site.register(Certificate, CertificateAdmin)
199212
admin.site.register(CertificateType, CertificateTypeAdmin)
200213
admin.site.register(Attendee, AttendeeAdmin)
@@ -210,3 +223,4 @@ class ExternalReviewerAdmin(admin.ModelAdmin):
210223
admin.site.register(Checklist, ChecklistAdmin)
211224
admin.site.register(OrganisationChecklist, OrganisationChecklistAdmin)
212225
admin.site.register(ExternalReviewer, ExternalReviewerAdmin)
226+
admin.site.register(CreditsOrder, CreditsOrderAdmin)

django_project/certification/api_views/invite_reviewer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def post(self, request, slug):
7979
'session_key': s.session_key
8080
}
8181
send_mail(
82-
u'Certification - You have been invited as a reviewer',
82+
u'QGIS Certification - You have been invited as a reviewer',
8383
u'Dear {name},\n\n'
8484
u'{invitation_text}'
8585
u'\n\n'
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Generated by Django 4.2.20 on 2025-05-08 16:09
2+
3+
from django.db import migrations, models
4+
import django.db.models.deletion
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('certification', '0028_certifyingorganisation_is_archived_and_more'),
11+
]
12+
13+
operations = [
14+
migrations.CreateModel(
15+
name='CreditsOrder',
16+
fields=[
17+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18+
('credits_requested', models.IntegerField(help_text='Number of credits requested in the order')),
19+
('credits_issued', models.BooleanField(default=False, help_text='Flag to indicate if credits have been issued')),
20+
('created_at', models.DateTimeField(auto_now_add=True, help_text='Timestamp when the payment was created')),
21+
('updated_at', models.DateTimeField(auto_now=True, help_text='Timestamp when the payment was last updated')),
22+
('organisation', models.ForeignKey(help_text='The certifying organisation that placed the order', on_delete=django.db.models.deletion.CASCADE, related_name='credits_orders', to='certification.certifyingorganisation')),
23+
],
24+
),
25+
]

django_project/certification/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@
1616
from certification.models.checklist import *
1717
from certification.models.organisation_checklist import *
1818
from certification.models.external_reviewer import *
19+
from certification.models.credits_order import *
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from django.db import models
2+
from .certifying_organisation import CertifyingOrganisation
3+
4+
5+
class CreditsOrder(models.Model):
6+
organisation = models.ForeignKey(
7+
CertifyingOrganisation,
8+
on_delete=models.CASCADE,
9+
related_name='credits_orders',
10+
help_text="The certifying organisation that placed the order"
11+
)
12+
credits_requested = models.IntegerField(help_text="Number of credits requested in the order")
13+
credits_issued = models.BooleanField(default=False, help_text="Flag to indicate if credits have been issued")
14+
created_at = models.DateTimeField(auto_now_add=True, help_text="Timestamp when the payment was created")
15+
updated_at = models.DateTimeField(auto_now=True, help_text="Timestamp when the payment was last updated")

django_project/certification/templates/certificate/top_up.html

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ <h1 >Top up credits for {{ cert_organisation }}</h1>
4848
</div>
4949
<div class="column">
5050
<button type="submit" class="button is-success is-fullwidth" id="buy" disabled>
51-
PAY WITH STRIPE
51+
PAY WITH PAYREXX
5252
</button>
5353
</div>
5454
</div>
5555
</div>
5656
</form>
5757
</div>
58-
{% include "stripe.html" %}
58+
{% comment %} {% include "stripe.html" %} {% endcomment %}
5959

6060
<script>
6161

@@ -104,7 +104,7 @@ <h1 >Top up credits for {{ cert_organisation }}</h1>
104104
updateTotal(this)
105105
});
106106

107-
$payButton.click(function (e) {
107+
{% comment %} $payButton.click(function (e) {
108108
e.preventDefault();
109109
let creditAmount = $creditAmount.val();
110110
if (!creditAmount) {
@@ -118,9 +118,9 @@ <h1 >Top up credits for {{ cert_organisation }}</h1>
118118
alert('error calculating total payment');
119119
}
120120
window.location = `{% url 'checkout' %}?unit=${creditAmount}&total=${totalToPay}&org=${org}`;
121-
});
121+
}); {% endcomment %}
122122

123-
function stripeSourceHandler(source) {
123+
{% comment %} function stripeSourceHandler(source) {
124124
// Insert the source ID into the form so it gets submitted to the
125125
// server
126126
$('<input>').attr({
@@ -129,7 +129,7 @@ <h1 >Top up credits for {{ cert_organisation }}</h1>
129129
name: 'stripe-source-id'
130130
}).appendTo($form).val(source.id);
131131
$form.submit();
132-
}
132+
} {% endcomment %}
133133

134134
</script>
135135
{% endblock %}

django_project/certification/urls.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@
8282
ValidateCertificate,
8383
ValidateCertificateOrganisation,
8484

85-
TopUpView,
85+
# TopUpView,
86+
PayrexxTopUpView,
87+
PayrexxWebhookView,
8688

8789
CheckoutSessionSuccessView,
8890
CreateCheckoutSessionView
@@ -253,7 +255,7 @@
253255
view=update_paid_status,
254256
name='paid-certificate'),
255257
url(r'^certifyingorganisation/(?P<organisation_slug>[\w-]+)/top-up/$',
256-
view=TopUpView.as_view(),
258+
view=PayrexxTopUpView.as_view(),
257259
name='top-up'),
258260
url(r'^certificate/(?P<id>[\w-]+)/$',
259261
view=CertificateDetailView.as_view(),
@@ -332,4 +334,9 @@
332334
url("^checkout-success/$",
333335
CheckoutSessionSuccessView.as_view(),
334336
name="checkout-success"),
337+
338+
# Payrexx webhook
339+
url(r'^payrexx-hook/$',
340+
view=PayrexxWebhookView.as_view(),
341+
name='payrexx-webhook'),
335342
]

0 commit comments

Comments
 (0)