Skip to content

Commit

Permalink
bugfixes on stripe refund call. Update on the payment model to record…
Browse files Browse the repository at this point in the history
… and retrieve refunds
  • Loading branch information
rhimmelbauer committed May 24, 2024
1 parent c683c05 commit b11d93d
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 18 deletions.
8 changes: 8 additions & 0 deletions develop/core/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ def test_partial_refund_payment_fail(self):
response = self.client.post(url, form_data)
self.assertIn('refund_amount', json.loads(response.content)['error'])

def test_get_payment_refund_form(self):
payment = Payment.objects.get(pk=1)
url = reverse('vendor_api:refund-payment-api', kwargs={"uuid": payment.uuid})

response = self.client.get(url)

self.assertEqual(response.status_code, 200)


@skipIf(True, "Webhook tests are highly dependent on data in Authroizenet and local data.")
class AuthorizeNetAPITest(TestCase):
Expand Down
18 changes: 7 additions & 11 deletions src/vendor/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,25 +319,21 @@ class PaymentRefundForm(forms.ModelForm):

class Meta:
model = Payment
fields = ["refund_amount", "reason", "void_end_date"]
fields = ['refund_amount', 'reason', 'void_end_date']

def clean_refund_amount(self):
past_refunds_amount = 0
refund_amount = self.cleaned_data.get("refund_amount", 0)
refund_amount = self.cleaned_data.get('refund_amount', 0)

if refund_amount > self.instance.amount:
raise forms.ValidationError(
_("Refund amount cannot be greater than the original amount")
)

if past_refunds := self.instance.result.get("refunds", []):
raise forms.ValidationError(_("Refund amount cannot be greater than the original amount"))

if (past_refunds := self.instance.result.get('refunds', [])):
for partial_refund in past_refunds:
past_refunds_amount += Decimal(partial_refund.get("amount", 0))
past_refunds_amount += Decimal(partial_refund.get('amount', 0))

if (refund_amount + past_refunds_amount) > self.instance.amount:
raise forms.ValidationError(
_("Refund amount cannot be greater than the original amount")
)
raise forms.ValidationError(_("Refund amount cannot be greater than the original amount"))

return refund_amount

Expand Down
37 changes: 34 additions & 3 deletions src/vendor/models/payment.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import uuid

from decimal import Decimal
from django.db.models.aggregates import Sum
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
from django.db import models
Expand All @@ -9,7 +10,7 @@
from vendor.models.receipt import Receipt
from vendor.models.subscription import Subscription
from vendor.models.base import SoftDeleteModelBase
from vendor.models.choice import PurchaseStatus
from vendor.models.choice import PurchaseStatus, RefundReasons
from vendor.utils import get_display_decimal


Expand Down Expand Up @@ -146,13 +147,43 @@ def get_receipt(self):
def get_amount_display(self):
return get_display_decimal(self.amount)

def record_refund(self, amount, date=timezone.now()):
def record_refund(self, amount, date=timezone.now(), reason=RefundReasons.OTHER.value):
self.status = PurchaseStatus.REFUNDED
if "refunds" not in self.result:
self.result["refunds"] = []

self.result["refunds"].append({
"date": date.strftime("%Y-%m-%d_%H:%M:%S"),
"date": date.isoformat(),
"reason": reason,
"amount": str(amount)
})

self.save()

def is_refund_available(self, refund_amount):
past_refunds = 0
past_refund_amount = 0

if refund_amount > self.amount:
return False

if (past_refunds := self.result.get("refunds", [])):
past_refund_amount = sum([
Decimal(past_refund.get("amount", 0))
for past_refund in past_refunds
])

if (past_refund_amount + refund_amount) > self.amount:
return False

return True

def get_past_refunds(self):
past_refunds = []
reasons = {reason[0]: reason[1] for reason in RefundReasons.choices}

for refund in self.result.get("refunds", []):
refund['reason'] = reasons[refund['reason'].lower()]
past_refunds.append(refund)

return past_refunds
2 changes: 1 addition & 1 deletion src/vendor/processors/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ def subscription_update_price(self, subscription, new_price, user):
# -------------------
# Refund a Payment
def refund_payment(self, refund_form, date=timezone.now()):
refund_form.instance.record_refund(refund_form.cleaned_data['refund_amount'], date)
refund_form.instance.record_refund(refund_form.cleaned_data['refund_amount'], date, refund_form.cleaned_data['reason'])

if refund_form.cleaned_data['void_end_date']:
receipt = refund_form.instance.get_receipt()
Expand Down
6 changes: 3 additions & 3 deletions src/vendor/processors/stripe.py
Original file line number Diff line number Diff line change
Expand Up @@ -685,11 +685,11 @@ def build_invoice(self, currency=DEFAULT_CURRENCY):
}

def build_refund(self, refund_form):
int_amount = self.convert_decimal_to_integer(amount=refund_form.cleared_data["amount"])
int_amount = self.convert_decimal_to_integer(refund_form.cleaned_data["refund_amount"])
return {
"charge": refund_form.instance.transaction_id,
"charge": refund_form.instance.transaction,
"amount": int_amount,
"reverse_transaction": True,
"reverse_transfer": True,
"refund_application_fee": True,
"reason": refund_form.cleaned_data['reason']
}
Expand Down

0 comments on commit b11d93d

Please sign in to comment.