From fa227d4a2ebe70b28cd40e84fa1867836423c256 Mon Sep 17 00:00:00 2001 From: James Kachel Date: Fri, 8 Nov 2024 06:49:34 -0600 Subject: [PATCH] Add helper for decimal quantization, bump CyberSource REST client, quantize totals to 2 decimals --- .../20241107_212223_jkachel_add_tax.md | 43 +++++++++++++++++++ .../mitol/payment_gateway/api.py | 6 +-- .../mitol/payment_gateway/payment_utils.py | 7 +++ src/payment_gateway/pyproject.toml | 2 +- .../payment_gateway/api/test_cybersource.py | 5 ++- .../utils/test_payment_utils.py | 15 ++++++- 6 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 src/payment_gateway/changelog.d/20241107_212223_jkachel_add_tax.md diff --git a/src/payment_gateway/changelog.d/20241107_212223_jkachel_add_tax.md b/src/payment_gateway/changelog.d/20241107_212223_jkachel_add_tax.md new file mode 100644 index 00000000..bff25a8c --- /dev/null +++ b/src/payment_gateway/changelog.d/20241107_212223_jkachel_add_tax.md @@ -0,0 +1,43 @@ + + + + +### Added + +- Adds support for tax collection. +- Bumps CyberSource REST Client package to at least 0.0.54. +- Adds a helper for quantizing decimals for currency amounts. + + + + + diff --git a/src/payment_gateway/mitol/payment_gateway/api.py b/src/payment_gateway/mitol/payment_gateway/api.py index d39a29c1..9a9d2c67 100644 --- a/src/payment_gateway/mitol/payment_gateway/api.py +++ b/src/payment_gateway/mitol/payment_gateway/api.py @@ -34,7 +34,7 @@ InvalidTransactionException, RefundDuplicateException, ) -from mitol.payment_gateway.payment_utils import clean_request_data, strip_nones +from mitol.payment_gateway.payment_utils import clean_request_data, strip_nones, quantize_decimal @dataclass @@ -461,8 +461,8 @@ def prepare_checkout( payload = { "access_key": settings.MITOL_PAYMENT_GATEWAY_CYBERSOURCE_ACCESS_KEY, - "amount": str(total + tax_total), - "tax_amount": str(tax_total), + "amount": str(quantize_decimal((total + tax_total))), + "tax_amount": str(quantize_decimal((tax_total))), "consumer_id": consumer_id, "currency": "USD", "locale": "en-us", diff --git a/src/payment_gateway/mitol/payment_gateway/payment_utils.py b/src/payment_gateway/mitol/payment_gateway/payment_utils.py index eb64b6d4..1c18980b 100644 --- a/src/payment_gateway/mitol/payment_gateway/payment_utils.py +++ b/src/payment_gateway/mitol/payment_gateway/payment_utils.py @@ -1,5 +1,7 @@ """Utilities for the Payment Gateway""" +from decimal import Decimal + # To delete None values in Input Request Json body def clean_request_data(request_data): @@ -21,3 +23,8 @@ def strip_nones(datasource): retval[key] = datasource[key] return retval + + +def quantize_decimal(value, precision=2): + """Quantize a decimal value to the specified precision""" + return Decimal(value).quantize(Decimal("0.{}".format("0" * precision))) diff --git a/src/payment_gateway/pyproject.toml b/src/payment_gateway/pyproject.toml index 6e012aa3..482251c6 100644 --- a/src/payment_gateway/pyproject.toml +++ b/src/payment_gateway/pyproject.toml @@ -3,7 +3,7 @@ name = "mitol-django-payment-gateway" version = "2023.12.19" description = "Django application to handle payment processing" dependencies = [ -"cybersource-rest-client-python>=0.0.36", +"cybersource-rest-client-python>=0.0.59", "django-stubs>=1.13.1", "django>=3.0", "mitol-django-common" diff --git a/tests/mitol/payment_gateway/api/test_cybersource.py b/tests/mitol/payment_gateway/api/test_cybersource.py index e5fd19fe..acec731a 100644 --- a/tests/mitol/payment_gateway/api/test_cybersource.py +++ b/tests/mitol/payment_gateway/api/test_cybersource.py @@ -5,6 +5,7 @@ from collections import namedtuple from dataclasses import dataclass from datetime import datetime +from decimal import Decimal from typing import Dict import pytest @@ -98,8 +99,8 @@ def generate_test_cybersource_payload(order, cartitems, transaction_uuid): test_payload = { "access_key": settings.MITOL_PAYMENT_GATEWAY_CYBERSOURCE_ACCESS_KEY, - "amount": str(test_total + tax_total), - "tax_amount": str(tax_total), + "amount": str(Decimal(test_total + tax_total).quantize(Decimal("0.01"))), + "tax_amount": str(Decimal(tax_total).quantize(Decimal("0.01"))), "consumer_id": consumer_id, "currency": "USD", "locale": "en-us", diff --git a/tests/mitol/payment_gateway/utils/test_payment_utils.py b/tests/mitol/payment_gateway/utils/test_payment_utils.py index ff90cd4e..4042e47f 100644 --- a/tests/mitol/payment_gateway/utils/test_payment_utils.py +++ b/tests/mitol/payment_gateway/utils/test_payment_utils.py @@ -1,7 +1,9 @@ """Tests for payment_gateway application utils""" # noqa: INP001 +from decimal import Decimal + import pytest -from mitol.payment_gateway.payment_utils import clean_request_data, strip_nones +from mitol.payment_gateway.payment_utils import clean_request_data, strip_nones, quantize_decimal @pytest.mark.parametrize( @@ -44,3 +46,14 @@ def test_strip_nones(): test_ds2 = strip_nones(ds2) assert test_ds2 == ds2 + + +def test_quantize_decimal(): + """Tests quantize_decimal to make sure that the decimal is quantized to the correct precision""" + + test_decimal = 1.23456789 + test_precision = 2 + + quantized_decimal = quantize_decimal(test_decimal, test_precision) + + assert quantized_decimal == Decimal("1.23")