Skip to content

Commit

Permalink
202443_Payment_Module_Configure_Mobile_money_delivery_mechanisms_to_s…
Browse files Browse the repository at this point in the history
…end_payment_records_to_WU_through_Payment_Gateway (#4020)
  • Loading branch information
MarekBiczysko authored Jul 11, 2024
1 parent 7930371 commit 54f2142
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 16 deletions.
23 changes: 23 additions & 0 deletions backend/hct_mis_api/apps/payment/migrations/0137_migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 3.2.25 on 2024-07-10 14:23

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('payment', '0136_migration'),
]

operations = [
migrations.AlterField(
model_name='payment',
name='status',
field=models.CharField(choices=[('Distribution Successful', 'Distribution Successful'), ('Not Distributed', 'Not Distributed'), ('Transaction Successful', 'Transaction Successful'), ('Transaction Erroneous', 'Transaction Erroneous'), ('Force failed', 'Force failed'), ('Partially Distributed', 'Partially Distributed'), ('Pending', 'Pending'), ('Sent to Payment Gateway', 'Sent to Payment Gateway'), ('Sent to FSP', 'Sent to FSP'), ('Manually Cancelled', 'Manually Cancelled')], default='Pending', max_length=255),
),
migrations.AlterField(
model_name='paymentrecord',
name='status',
field=models.CharField(choices=[('Distribution Successful', 'Distribution Successful'), ('Not Distributed', 'Not Distributed'), ('Transaction Successful', 'Transaction Successful'), ('Transaction Erroneous', 'Transaction Erroneous'), ('Force failed', 'Force failed'), ('Partially Distributed', 'Partially Distributed'), ('Pending', 'Pending'), ('Sent to Payment Gateway', 'Sent to Payment Gateway'), ('Sent to FSP', 'Sent to FSP'), ('Manually Cancelled', 'Manually Cancelled')], default='Pending', max_length=255),
),
]
39 changes: 24 additions & 15 deletions backend/hct_mis_api/apps/payment/services/payment_gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@ class Meta:
]


class PaymentPayloadSerializer(serializers.Serializer):
amount = serializers.DecimalField(max_digits=12, decimal_places=2, required=True)
phone_no = serializers.CharField(required=False)
last_name = serializers.CharField(required=False)
first_name = serializers.CharField(required=False)
full_name = serializers.CharField(required=False)
destination_currency = serializers.CharField(required=True)
service_provider_code = serializers.CharField(required=False)


class PaymentSerializer(ReadOnlyModelSerializer):
remote_id = serializers.CharField(source="id")
record_code = serializers.CharField(source="unicef_id")
Expand All @@ -115,21 +125,20 @@ def get_extra_data(self, obj: Payment) -> Dict:
return {}

def get_payload(self, obj: Payment) -> Dict:
"""
amount: int # 120000
phone_no: str # "78933211"
last_name: str # "Arabic"
first_name: str # "Angelina"
destination_currency: str # "USD"
"""
return {
"amount": obj.entitlement_quantity,
"phone_no": str(obj.collector.phone_no),
"last_name": obj.collector.family_name,
"first_name": obj.collector.given_name,
"full_name": obj.full_name,
"destination_currency": obj.currency,
}
payload = PaymentPayloadSerializer(
data={
"amount": obj.entitlement_quantity,
"phone_no": str(obj.collector.phone_no),
"last_name": obj.collector.family_name,
"first_name": obj.collector.given_name,
"full_name": obj.full_name,
"destination_currency": obj.currency,
"service_provider_code": obj.collector.flex_fields.get("service_provider_code", ""),
}
)
if not payload.is_valid():
raise serializers.ValidationError(payload.errors)
return payload.data

class Meta:
model = Payment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import pytest
from pytz import utc
from rest_framework.exceptions import ValidationError

from hct_mis_api.apps.account.fixtures import UserFactory
from hct_mis_api.apps.core.base_test_case import APITestCase
Expand Down Expand Up @@ -76,7 +77,12 @@ def setUpTestData(cls) -> None:
)
cls.payments = []
for _ in range(2):
collector = IndividualFactory(household=None)
collector = IndividualFactory(
household=None,
flex_fields={
"service_provider_code": "123456789",
},
)
hoh = IndividualFactory(household=None)
hh = HouseholdFactory(head_of_household=hoh)
IndividualRoleInHouseholdFactory(household=hh, individual=hoh, role=ROLE_PRIMARY)
Expand Down Expand Up @@ -411,3 +417,44 @@ def test_add_records_to_payment_instructions_error(self, add_records_to_payment_
self.assertEqual(self.payments[1].status, Payment.STATUS_ERROR)
self.assertEqual(self.payments[0].reason_for_unsuccessful_payment, "Error")
self.assertEqual(self.payments[1].reason_for_unsuccessful_payment, "Error")

@mock.patch("hct_mis_api.apps.payment.services.payment_gateway.PaymentGatewayAPI._post")
def test_api_add_records_to_payment_instruction(self, post_mock: Any) -> None:
post_mock.return_value = {
"remote_id": "123",
"records": {
"1": self.payments[0].id,
},
"errors": None,
}
PaymentGatewayAPI().add_records_to_payment_instruction([self.payments[0]], "123")
post_mock.assert_called_once_with(
"payment_instructions/123/add_records/",
[
{
"remote_id": str(self.payments[0].id),
"record_code": self.payments[0].unicef_id,
"payload": {
"amount": str(self.payments[0].entitlement_quantity),
"phone_no": str(self.payments[0].collector.phone_no),
"last_name": self.payments[0].collector.family_name,
"first_name": self.payments[0].collector.given_name,
"full_name": self.payments[0].collector.full_name,
"destination_currency": self.payments[0].currency,
"service_provider_code": self.payments[0].collector.flex_fields["service_provider_code"],
},
"extra_data": {},
}
],
validate_response=True,
)

@mock.patch("hct_mis_api.apps.payment.services.payment_gateway.PaymentGatewayAPI._post")
def test_api_add_records_to_payment_instruction_validation_error(self, post_mock: Any) -> None:
payment = self.payments[0]
payment.entitlement_quantity = None
payment.save()
with self.assertRaisesMessage(
ValidationError, "{'amount': [ErrorDetail(string='This field may not be null.', code='null')]}"
):
PaymentGatewayAPI().add_records_to_payment_instruction([payment], "123")

0 comments on commit 54f2142

Please sign in to comment.