Skip to content

Commit c99a1a2

Browse files
committed
Moyapay API integration
1 parent 861d792 commit c99a1a2

File tree

16 files changed

+162
-3
lines changed

16 files changed

+162
-3
lines changed

comments/views.py

+6
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,15 @@
1717

1818
from comments.forms import AdminCommentForm, CommentFilterForm
1919
from comments.models import CannedResponse, CommentModeration
20+
from moyapay.payments import MoyaPayModeratorPayout
2021

2122

2223
def update(request, comment_pk, action):
24+
if CommentModeration.objects.get(id=comment_pk).state == CommentModeration.CommentModerationState.REJECTED:
25+
user = request.user
26+
comment = XtdComment.objects.get(pk=comment_pk)
27+
MoyaPayModeratorPayout(user=user, comment=comment).process_payment()
28+
2329
get_comment_with_children_filter = Q(parent_id=comment_pk) | Q(pk=comment_pk)
2430
comments = XtdComment.objects.filter(get_comment_with_children_filter)
2531
comment_moderations = []
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 3.1.14 on 2023-03-31 09:22
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('home', '0050_auto_20230213_1214'),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name='manifestsettings',
15+
name='language',
16+
field=models.CharField(choices=[('ar', 'Arabic'), ('bn', 'Bengali'), ('ny', 'Chichewa'), ('prs', 'Dari'), ('en', 'English'), ('fr', 'French'), ('hi', 'Hindi'), ('id', 'Indonesian'), ('kaa', 'Karakalpak'), ('km', 'Khmer'), ('rw', 'Kinyarwanda'), ('rn', 'Kirundi'), ('ku', 'Kurdish'), ('mg', 'Malagasy'), ('ne', 'Nepali'), ('nr', 'Ndebele'), ('ps', 'Pashto'), ('pt', 'Portuguese'), ('qu', 'Quechua'), ('ru', 'Russian'), ('sn', 'Shona'), ('si', 'Sinhala'), ('es', 'Spanish'), ('sw', 'Swahili'), ('tg', 'Tajik'), ('ta', 'Tamil'), ('ti', 'Tigrinya'), ('tr', 'Turkish'), ('uk', 'Ukraine'), ('ur', 'Urdu'), ('uz', 'Uzbek'), ('zu', 'Zulu'), ('xy', 'Testing')], default='en', help_text='Choose language', max_length=3, verbose_name='Language'),
17+
),
18+
]

iogt/settings/base.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
'messaging',
4141
'common',
4242
'notifications',
43+
'moyapay',
4344
'django.contrib.humanize',
4445
'wagtail_localize',
4546
'wagtail_localize.locales',
@@ -239,7 +240,7 @@
239240

240241
WAGTAIL_USER_EDIT_FORM = 'iogt_users.forms.WagtailAdminUserEditForm'
241242
WAGTAIL_USER_CREATION_FORM = 'iogt_users.forms.WagtailAdminUserCreateForm'
242-
WAGTAIL_USER_CUSTOM_FIELDS = ['display_name', 'first_name', 'last_name', 'email', 'terms_accepted']
243+
WAGTAIL_USER_CUSTOM_FIELDS = ['display_name', 'first_name', 'last_name', 'email', 'terms_accepted', 'moyapay_username']
243244

244245
# Base URL to use when referring to full URLs within the Wagtail admin backend -
245246
# e.g. in notification emails. Don't include '/admin' or a trailing slash

iogt/templates/wagtailusers/users/create.html

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
{% endif %}
77
{% include "wagtailadmin/shared/field_as_li.html" with field=form.email %}
88
{% block extra_fields %}
9+
{% include "wagtailadmin/shared/field_as_li.html" with field=form.moyapay_username %}
910
{% include "wagtailadmin/shared/field_as_li.html" with field=form.display_name %}
1011
{% include "wagtailadmin/shared/field_as_li.html" with field=form.first_name %}
1112
{% include "wagtailadmin/shared/field_as_li.html" with field=form.last_name %}

iogt/templates/wagtailusers/users/edit.html

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
{% endif %}
77
{% include "wagtailadmin/shared/field_as_li.html" with field=form.email %}
88
{% block extra_fields %}
9+
{% include "wagtailadmin/shared/field_as_li.html" with field=form.moyapay_username %}
910
{% include "wagtailadmin/shared/field_as_li.html" with field=form.display_name %}
1011
{% include "wagtailadmin/shared/field_as_li.html" with field=form.first_name %}
1112
{% include "wagtailadmin/shared/field_as_li.html" with field=form.last_name %}

iogt_users/adapters.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ class AccountAdapter(DefaultAccountAdapter):
55
def save_user(self, request, user, form, commit=True):
66
user = super(AccountAdapter, self).save_user(request, user, form, commit)
77
data = form.cleaned_data
8+
user.moyapay_username = data.get('moyapay_username')
89
user.display_name = data.get('display_name') or data.get('username')
910
user.first_name = data.get('first_name')
1011
user.last_name = data.get('last_name')
1112
user.terms_accepted = data.get('terms_accepted', False)
12-
user.save(update_fields=['display_name', 'first_name', 'last_name', 'terms_accepted'])
13+
user.save(update_fields=['display_name', 'first_name', 'last_name', 'terms_accepted', 'moyapay_username'])
1314
return user

iogt_users/forms.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class Meta:
7676

7777
class WagtailAdminUserCreateForm(WagtailUserCreationForm):
7878
email = forms.EmailField(required=False, label='Email')
79-
display_name = forms.CharField(required=False, label='Display Name')
79+
moyapay_username = forms.CharField(required=False, label='MoyaPay Username')
8080
first_name = forms.CharField(required=False, label='First Name')
8181
last_name = forms.CharField(required=False, label='Last Name')
8282
terms_accepted = forms.BooleanField(label=_('I accept the Terms and Conditions.'))
@@ -96,6 +96,7 @@ def clean_displayname(self):
9696

9797
class WagtailAdminUserEditForm(WagtailUserEditForm):
9898
email = forms.EmailField(required=False, label='Email')
99+
moyapay_username = forms.CharField(required=False, label='MoyaPay Username')
99100
display_name = forms.CharField(required=False, label='Display Name')
100101
first_name = forms.CharField(required=False, label='First Name')
101102
last_name = forms.CharField(required=False, label='Last Name')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 3.1.14 on 2023-03-31 09:22
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('iogt_users', '0005_auto_20220120_0813'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='user',
15+
name='moyapay_username',
16+
field=models.CharField(blank=True, max_length=150, null=True, unique=True, verbose_name='MoyaPay username'),
17+
),
18+
]

iogt_users/models.py

+7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ class User(AbstractUser):
1717
display_name = models.CharField('display name', max_length=255, null=True, blank=True)
1818
email = models.EmailField('email address', null=True, blank=True)
1919
terms_accepted = models.BooleanField(default=False)
20+
moyapay_username = models.CharField(
21+
'MoyaPay username',
22+
max_length=150,
23+
unique=True,
24+
null=True,
25+
blank=True,
26+
)
2027

2128
has_filled_registration_survey = models.BooleanField(default=False)
2229
has_viewed_registration_survey = models.BooleanField(default=False)

moyapay/__init__.py

Whitespace-only changes.

moyapay/client.py

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from requests import Session, Request
2+
from rest_framework import status
3+
4+
5+
class MoyaPayClient:
6+
BASE_URL = 'https://payments.api.dev.moyapayd.app'
7+
customer_url = f'{BASE_URL}/customers'
8+
merchant_url = f'{BASE_URL}/merchants'
9+
merchant_token_url = f'{merchant_url}/tokens/validate'
10+
merchant_wallet_url = f'{merchant_url}/wallet'
11+
pay_customer_url = f'{customer_url}/pay'
12+
13+
def __init__(self):
14+
self.session = Session()
15+
self.access_token = ''
16+
17+
def _get_headers(self):
18+
return {
19+
'Authorization': f'Bearer {self.access_token}',
20+
'Content-Type': 'application/json'
21+
}
22+
23+
def _get_validated_response(self, response):
24+
if response.ok:
25+
return response.json()
26+
elif response.status_code == status.HTTP_401_UNAUTHORIZED:
27+
raise Exception('Unauthorised - Invalid or no authentication token supplied')
28+
else:
29+
raise Exception(f'Something went wrong. Status: {response.status_code}')
30+
31+
def _api_caller(self, request):
32+
request = self.session.prepare_request(request)
33+
response = self.session.send(request)
34+
return self._get_validated_response(response)
35+
36+
def authenticate(self):
37+
request = Request(method='GET', url=self.merchant_token_url, headers=self._get_headers())
38+
self._api_caller(request)
39+
40+
def get_merchant_balance(self):
41+
request = Request(method='GET', url=self.merchant_wallet_url, headers=self._get_headers())
42+
return self._api_caller(request).get('balance')
43+

moyapay/migrations/0001_initial.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Generated by Django 3.1.14 on 2023-03-31 09:23
2+
3+
from django.conf import settings
4+
from django.db import migrations, models
5+
import django.db.models.deletion
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
initial = True
11+
12+
dependencies = [
13+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14+
]
15+
16+
operations = [
17+
migrations.CreateModel(
18+
name='MoyaPayPayment',
19+
fields=[
20+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
21+
('amount', models.IntegerField()),
22+
('is_successful', models.BooleanField(default=True)),
23+
('created_at', models.DateTimeField(auto_now_add=True)),
24+
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
25+
],
26+
),
27+
]

moyapay/migrations/__init__.py

Whitespace-only changes.

moyapay/models.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from django.db import models
2+
from iogt_users.models import User
3+
4+
5+
class MoyaPayPayment(models.Model):
6+
amount = models.IntegerField()
7+
is_successful = models.BooleanField(default=True)
8+
created_at = models.DateTimeField(auto_now_add=True)
9+
user = models.ForeignKey(User, on_delete=models.CASCADE)
10+
11+
def __str__(self):
12+
return self.user.moyapay_username

moyapay/payments.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from django.utils import timezone
2+
3+
from moyapay.client import MoyaPayClient
4+
from moyapay.utils import can_process_payment
5+
6+
7+
class MoyaPayModeratorPayout:
8+
def __init__(self, user, comment):
9+
self.user = user
10+
self.comment = comment
11+
self.amount = 50
12+
self.client = MoyaPayClient()
13+
self.client.authenticate()
14+
self.current_datetime = timezone.now().strftime("%Y-%m-%d %H:%M:%S")
15+
16+
def process_payment(self):
17+
can_process_payment(self.user, self.comment)

moyapay/utils.py

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
def can_process_payment(user, comment):
2+
# if a moderator moderate his own comment
3+
if comment.user == user:
4+
return False
5+
6+

0 commit comments

Comments
 (0)