Skip to content

Commit

Permalink
Merge pull request #2 from radekholy24/process_data_save
Browse files Browse the repository at this point in the history
PayPal: Save captured_amount when processing data
  • Loading branch information
PetrDlouhy authored May 14, 2024
2 parents 405ae6d + 7341472 commit 8b40e5d
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 1 deletion.
2 changes: 2 additions & 0 deletions payments/paypal/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ def process_data(self, payment, request):
payment.attrs.payer_info = executed_payment["payer"]["payer_info"]
if self._capture:
payment.captured_amount = payment.total
payment.objects.filter(pk=payment.pk).update(captured_amount=payment.captured_amount)
payment.change_status(PaymentStatus.CONFIRMED)
else:
payment.change_status(PaymentStatus.PREAUTH)
Expand All @@ -302,6 +303,7 @@ def process_subscription_data(self, payment, request):
return redirect(failure_url)
if subscription_data["status"] == "ACTIVE":
payment.captured_amount = payment.total
payment.objects.filter(pk=payment.pk).update(captured_amount=payment.captured_amount)
payment.change_status(PaymentStatus.CONFIRMED)
return redirect(success_url)
payment.change_status(PaymentStatus.REJECTED)
Expand Down
85 changes: 84 additions & 1 deletion payments/paypal/test_paypal.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
from copy import deepcopy
from datetime import date
from decimal import Decimal
from unittest import TestCase
Expand Down Expand Up @@ -30,7 +31,49 @@
}


class PaymentQuerySet(Mock):
__payments = {}

def create(self, **kwargs):
if kwargs:
raise NotImplementedError(f"arguments not supported yet: {kwargs}")
id_ = max(self.__payments) + 1 if self.__payments else 1
self.__payments[id_] = {}
payment = Payment()
payment.id = id_
payment.save()
return payment

def get(self, *args, **kwargs):
if args or kwargs:
return self.filter(*args, **kwargs).get()
payment = Payment()
payment_fields, = self.__payments.values()
for payment_field_name, payment_field_value in payment_fields.items():
setattr(payment, payment_field_name, deepcopy(payment_field_value))
return payment

def filter(self, *args, pk=None, **kwargs):
if args or kwargs:
raise NotImplementedError(f"arguments not supported yet: {args}, {kwargs}")
if pk is not None:
return PaymentQuerySet({pk_: payment for pk_, payment in self.__payments.items() if pk_ == pk})
return self

def update(self, **kwargs):
for payment in self.__payments.values():
for field_name, field_value in kwargs.items():
if not any(field.name == field_name for field in Payment._meta.get_fields(include_parents=True, include_hidden=True)):
raise NotImplementedError(f"updating unknown field not supported yet: {field_name}")
payment[field_name] = deepcopy(field_value)

def delete(self):
self.__payments.clear()


class Payment(Mock):
objects = PaymentQuerySet()

id = 1
description = "payment"
currency = "USD"
Expand All @@ -54,9 +97,14 @@ class Payment(Mock):
}
)

@property
def pk(self):
return self.id

def change_status(self, status, message=""):
self.status = status
self.message = message
self.save(update_fields=["status", "message"])

def get_failure_url(self):
return "http://cancel.com"
Expand All @@ -74,10 +122,37 @@ def get_purchased_items(self):
def get_success_url(self):
return "http://success.com"

def save(self, *args, update_fields=None, **kwargs):
if args or kwargs:
raise NotImplementedError(f"arguments not supported yet: {args}, {kwargs}")
if update_fields is None:
update_fields = {field.name for field in self._meta.get_fields(include_parents=True, include_hidden=True)}
Payment.objects.filter(pk=self.pk).update(**{field: getattr(self, field) for field in update_fields})

def refresh_from_db(self, *args, **kwargs):
if args or kwargs:
raise NotImplementedError(f"arguments not supported yet: {args}, {kwargs}")
payment_from_db = Payment.objects.get(pk=self.pk)
for field in self._meta.get_fields(include_parents=True, include_hidden=True):
field_value_from_db = getattr(payment_from_db, field.name)
setattr(self, field.name, field_value_from_db)

class Meta(Mock):
def get_fields(self, include_parents=True, include_hidden=False):
fields = []
for field_name in {"id", "description", "currency", "delivery", "status", "tax", "token", "total", "captured_amount", "variant", "transaction_id", "message", "extra_data"}:
field = Mock()
field.name = field_name
fields.append(field)
return tuple(fields)

_meta = Meta()


class TestPaypalProvider(TestCase):
def setUp(self):
self.payment = Payment()
Payment.objects.delete()
self.payment = Payment.objects.create()
self.provider = PaypalProvider(secret=SECRET, client_id=CLIENT_ID)

def test_provider_raises_redirect_needed_on_success(self):
Expand Down Expand Up @@ -190,6 +265,9 @@ def test_provider_redirects_on_success_captured_payment(

self.assertEqual(self.payment.status, PaymentStatus.CONFIRMED)
self.assertEqual(self.payment.captured_amount, self.payment.total)
self.payment.refresh_from_db()
self.assertEqual(self.payment.status, PaymentStatus.CONFIRMED)
self.assertEqual(self.payment.captured_amount, self.payment.total)

@patch("requests.post")
@patch("payments.paypal.redirect")
Expand Down Expand Up @@ -221,6 +299,9 @@ def test_provider_redirects_on_success_preauth_payment(

self.assertEqual(self.payment.status, PaymentStatus.PREAUTH)
self.assertEqual(self.payment.captured_amount, Decimal("0"))
self.payment.refresh_from_db()
self.assertEqual(self.payment.status, PaymentStatus.PREAUTH)
self.assertEqual(self.payment.captured_amount, Decimal("0"))

@patch("payments.paypal.redirect")
def test_provider_request_without_payerid_redirects_on_failure(
Expand All @@ -230,6 +311,8 @@ def test_provider_request_without_payerid_redirects_on_failure(
request.GET = {"token": "test", "PayerID": None}
self.provider.process_data(self.payment, request)
self.assertEqual(self.payment.status, PaymentStatus.REJECTED)
self.payment.refresh_from_db()
self.assertEqual(self.payment.status, PaymentStatus.REJECTED)

@patch("requests.post")
def test_provider_renews_access_token(self, mocked_post):
Expand Down

0 comments on commit 8b40e5d

Please sign in to comment.