chore: rename model

This commit is contained in:
2024-03-24 20:41:33 +01:00
parent 3742037d68
commit 05ece2c074
8 changed files with 90 additions and 96 deletions
+2 -2
View File
@@ -1,10 +1,10 @@
from django.contrib import admin from django.contrib import admin
from tpv.models import PaymentTPV from tpv.models import PaymentTransaction
from unfold.admin import ModelAdmin from unfold.admin import ModelAdmin
# Register your models here. # Register your models here.
@admin.register(PaymentTPV) @admin.register(PaymentTransaction)
class PaymentTPVAdmin(ModelAdmin): class PaymentTPVAdmin(ModelAdmin):
list_display = ( list_display = (
"hash", "hash",
+2 -2
View File
@@ -1,4 +1,4 @@
# Generated by Django 5.0.3 on 2024-03-21 22:43 # Generated by Django 5.0.3 on 2024-03-24 19:19
import tpv.models import tpv.models
import uuid import uuid
@@ -14,7 +14,7 @@ class Migration(migrations.Migration):
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name="PaymentTPV", name="PaymentTransaction",
fields=[ fields=[
( (
"id", "id",
+1 -5
View File
@@ -8,7 +8,7 @@ def set_default_metadata():
return {"items": [], "response": None} return {"items": [], "response": None}
class PaymentTPV(models.Model): class PaymentTransaction(models.Model):
class StatusChoices(models.TextChoices): class StatusChoices(models.TextChoices):
PAID = "PAI", _("Pagado") PAID = "PAI", _("Pagado")
PENDING = "PEN", _("Pendiente") PENDING = "PEN", _("Pendiente")
@@ -62,10 +62,6 @@ class PaymentTPV(models.Model):
} }
""" """
def regenerate_uuid(self):
self.hash = uuid4()
self.save()
@property @property
def amount_integer(self) -> int: def amount_integer(self) -> int:
return int(self.amount * 100) return int(self.amount * 100)
+24 -26
View File
@@ -3,7 +3,7 @@ import json
from django.conf import settings from django.conf import settings
from django.urls import reverse from django.urls import reverse
from tpv.models import PaymentTPV from tpv.models import PaymentTransaction
from tpv.utils import compute_signature from tpv.utils import compute_signature
@@ -43,16 +43,16 @@ class RedsysClient:
def get_currency_code(self) -> str: def get_currency_code(self) -> str:
return settings.REDSYS_CURRENCY_CODE return settings.REDSYS_CURRENCY_CODE
def get_merchant_url_ok_for_order(self, order: PaymentTPV) -> str: def get_merchant_url_ok_for_transaction(self, transaction: PaymentTransaction) -> str:
path = reverse("tpv:ok", kwargs={"order": order.hash}) path = reverse("tpv:ok", kwargs={"transaction": transaction.hash})
return f"{settings.REDSYS_TPV_DOMAIN}{path}" return f"{settings.REDSYS_TPV_DOMAIN}{path}"
def get_merchant_url_ko_for_order(self, order: PaymentTPV) -> str: def get_merchant_url_ko_for_transaction(self, transaction: PaymentTransaction) -> str:
path = reverse("tpv:ko", kwargs={"order": order.hash}) path = reverse("tpv:ko", kwargs={"transaction": transaction.hash})
return f"{settings.REDSYS_TPV_DOMAIN}{path}" return f"{settings.REDSYS_TPV_DOMAIN}{path}"
def get_webhook_url_for_order(self, order: PaymentTPV) -> str: def get_webhook_url_for_transaction(self, transaction: PaymentTransaction) -> str:
path = reverse("tpv:webhook", kwargs={"order": order.hash}) path = reverse("tpv:webhook", kwargs={"transaction": transaction.hash})
return f"{settings.REDSYS_TPV_DOMAIN}{path}" return f"{settings.REDSYS_TPV_DOMAIN}{path}"
def get_shared_secret(self) -> str: def get_shared_secret(self) -> str:
@@ -62,41 +62,39 @@ class RedsysClient:
key = self.get_shared_secret() key = self.get_shared_secret()
return compute_signature(str(hash), payload, key).decode() return compute_signature(str(hash), payload, key).decode()
def get_merchant_parameters_for_order( def get_merchant_parameters_for_transaction(
self, order: PaymentTPV, transaction_type: int = TransactionTypes.AUTHORIZATION self, transaction: PaymentTransaction, transaction_type: int = TransactionTypes.AUTHORIZATION
) -> dict: ) -> dict:
merchant_code = self.get_merchant_code() merchant_code = self.get_merchant_code()
return { return {
"DS_MERCHANT_AMOUNT": str(order.amount_integer), "DS_MERCHANT_AMOUNT": str(transaction.amount_integer),
"DS_MERCHANT_CURRENCY": self.get_currency_code(), "DS_MERCHANT_CURRENCY": self.get_currency_code(),
"DS_MERCHANT_MERCHANTCODE": merchant_code, "DS_MERCHANT_MERCHANTCODE": merchant_code,
"DS_MERCHANT_MERCHANTURL": self.get_webhook_url_for_order(order), # Webhook "DS_MERCHANT_MERCHANTURL": self.get_webhook_url_for_transaction(transaction), # Webhook
"DS_MERCHANT_ORDER": order.hash.hex, "DS_MERCHANT_ORDER": transaction.hash.hex,
"DS_MERCHANT_TERMINAL": self.get_terminal(), "DS_MERCHANT_TERMINAL": self.get_terminal(),
"DS_MERCHANT_TRANSACTIONTYPE": transaction_type, "DS_MERCHANT_TRANSACTIONTYPE": transaction_type,
"DS_MERCHANT_URLKO": self.get_merchant_url_ko_for_order( # Página informativa al usuario - Pago erróneo
order "DS_MERCHANT_URLKO": self.get_merchant_url_ko_for_transaction(transaction),
), # Página informativa al usuario - Pago erróneo # Página informativa al usuario - Pago confirmado
"DS_MERCHANT_URLOK": self.get_merchant_url_ok_for_order( "DS_MERCHANT_URLOK": self.get_merchant_url_ok_for_transaction(transaction),
order
), # Página informativa al usuario - Pago confirmado
} }
def get_encoded_merchant_parameters_for_order( def get_encoded_merchant_parameters_for_transaction(
self, order: PaymentTPV, transaction_type: int = TransactionTypes.AUTHORIZATION self, transaction: PaymentTransaction, transaction_type: int = TransactionTypes.AUTHORIZATION
) -> str: ) -> str:
body = self.get_merchant_parameters_for_order(order, transaction_type) body = self.get_merchant_parameters_for_transaction(transaction, transaction_type)
stringified_body = json.dumps(body) stringified_body = json.dumps(body)
return base64.b64encode(stringified_body.encode()).decode("utf-8") return base64.b64encode(stringified_body.encode()).decode("utf-8")
def get_body_for_order( def get_body_for_transaction(
self, order: PaymentTPV, transaction_type: int = TransactionTypes.AUTHORIZATION self, transaction: PaymentTransaction, transaction_type: int = TransactionTypes.AUTHORIZATION
) -> dict: ) -> dict:
merchant_parameters = self.get_encoded_merchant_parameters_for_order( merchant_parameters = self.get_encoded_merchant_parameters_for_transaction(
order, transaction_type transaction, transaction_type
) )
signature = self.get_signature(order.hash.hex, merchant_parameters) signature = self.get_signature(transaction.hash.hex, merchant_parameters)
return { return {
"Ds_MerchantParameters": merchant_parameters, "Ds_MerchantParameters": merchant_parameters,
+25 -25
View File
@@ -6,7 +6,7 @@ from rest_framework import status
from rest_framework.test import APITestCase from rest_framework.test import APITestCase
from django.conf import settings from django.conf import settings
from tpv.models import PaymentTPV from tpv.models import PaymentTransaction
from tpv.redsys import RedsysClient from tpv.redsys import RedsysClient
from tpv.settings import ERROR_CODES from tpv.settings import ERROR_CODES
@@ -14,7 +14,7 @@ from tpv.settings import ERROR_CODES
class TestRedsysTPV(APITestCase): class TestRedsysTPV(APITestCase):
def test_redsys_client(self): def test_redsys_client(self):
amount_to_pay = Decimal("10.00") amount_to_pay = Decimal("10.00")
order = PaymentTPV.objects.create(amount=amount_to_pay) transaction = PaymentTransaction.objects.create(amount=amount_to_pay)
items = [ items = [
{ {
@@ -26,13 +26,13 @@ class TestRedsysTPV(APITestCase):
} }
] ]
order.metadata["items"] = items transaction.metadata["items"] = items
order.save() transaction.save()
client = RedsysClient() client = RedsysClient()
merchant_parameters = client.get_merchant_parameters_for_order(order) merchant_parameters = client.get_merchant_parameters_for_transaction(transaction)
assert merchant_parameters.get("DS_MERCHANT_ORDER") == order.hash.hex assert merchant_parameters.get("DS_MERCHANT_ORDER") == transaction.hash.hex
assert merchant_parameters.get("DS_MERCHANT_AMOUNT") == str( assert merchant_parameters.get("DS_MERCHANT_AMOUNT") == str(
int(amount_to_pay) * 100 int(amount_to_pay) * 100
) )
@@ -44,11 +44,11 @@ class TestRedsysTPV(APITestCase):
== settings.REDSYS_MERCHANT_CODE == settings.REDSYS_MERCHANT_CODE
) )
client.get_body_for_order(order) client.get_body_for_transaction(transaction)
def test_redsys_webhook(self): def test_redsys_webhook(self):
amount_to_pay = Decimal("10.00") amount_to_pay = Decimal("10.00")
order = PaymentTPV.objects.create(amount=amount_to_pay) transaction = PaymentTransaction.objects.create(amount=amount_to_pay)
items = [ items = [
{ {
@@ -59,19 +59,19 @@ class TestRedsysTPV(APITestCase):
"amount_to_pay": str(amount_to_pay), "amount_to_pay": str(amount_to_pay),
} }
] ]
order.metadata["items"] = items transaction.metadata["items"] = items
order.save() transaction.save()
response = self.client.get( response = self.client.get(
reverse("tpv:order_created", kwargs={"order": order.hash}) reverse("tpv:order_created", kwargs={"transaction": transaction.hash})
) )
assert response.status_code == status.HTTP_200_OK assert response.status_code == status.HTTP_200_OK
redsys_response_data = { redsys_response_data = {
"Ds_MerchantCode": "999008881", "Ds_MerchantCode": "999008881",
"Ds_Terminal": "001", "Ds_Terminal": "001",
"Ds_Order": order.hash.hex, "Ds_Order": transaction.hash.hex,
"Ds_Amount": str(order.amount_integer), "Ds_Amount": str(transaction.amount_integer),
"Ds_Currency": "978", "Ds_Currency": "978",
"Ds_Date": "01/01/2024", "Ds_Date": "01/01/2024",
"Ds_Hour": "00:00", "Ds_Hour": "00:00",
@@ -94,7 +94,7 @@ class TestRedsysTPV(APITestCase):
).decode() ).decode()
response = self.client.post( response = self.client.post(
reverse("tpv:webhook", kwargs={"order": order.hash}), reverse("tpv:webhook", kwargs={"transaction": transaction.hash}),
data={ data={
"Ds_MerchantParameters": b64_merchant_params, "Ds_MerchantParameters": b64_merchant_params,
"Ds_Signature": settings.REDSYS_SHARED_SECRET, "Ds_Signature": settings.REDSYS_SHARED_SECRET,
@@ -105,13 +105,13 @@ class TestRedsysTPV(APITestCase):
assert response.status_code == status.HTTP_200_OK assert response.status_code == status.HTTP_200_OK
response = self.client.get( response = self.client.get(
reverse("tpv:ok", kwargs={"order": order.hash}) reverse("tpv:ok", kwargs={"transaction": transaction.hash})
) )
assert response.status_code == status.HTTP_200_OK assert response.status_code == status.HTTP_200_OK
def test_redsys_webhook_payment_error(self): def test_redsys_webhook_payment_error(self):
amount_to_pay = Decimal("10.00") amount_to_pay = Decimal("10.00")
order = PaymentTPV.objects.create(amount=amount_to_pay) transaction = PaymentTransaction.objects.create(amount=amount_to_pay)
items = [ items = [
{ {
@@ -123,19 +123,19 @@ class TestRedsysTPV(APITestCase):
} }
] ]
order.metadata["items"] = items transaction.metadata["items"] = items
order.save() transaction.save()
response = self.client.get( response = self.client.get(
reverse("tpv:order_created", kwargs={"order": order.hash}) reverse("tpv:order_created", kwargs={"transaction": transaction.hash})
) )
assert response.status_code == status.HTTP_200_OK assert response.status_code == status.HTTP_200_OK
redsys_response_data = { redsys_response_data = {
"Ds_MerchantCode": "999008881", "Ds_MerchantCode": "999008881",
"Ds_Terminal": "001", "Ds_Terminal": "001",
"Ds_Order": order.hash.hex, "Ds_Order": transaction.hash.hex,
"Ds_Amount": "1000", "Ds_Amount": "1000",
"Ds_Currency": "978", "Ds_Currency": "978",
"Ds_Date": "01/01/2024", "Ds_Date": "01/01/2024",
@@ -160,7 +160,7 @@ class TestRedsysTPV(APITestCase):
).decode() ).decode()
response = self.client.post( response = self.client.post(
reverse("tpv:webhook", kwargs={"order": order.hash}), reverse("tpv:webhook", kwargs={"transaction": transaction.hash}),
data={ data={
"Ds_MerchantParameters": b64_merchant_params, "Ds_MerchantParameters": b64_merchant_params,
"Ds_Signature": settings.REDSYS_SHARED_SECRET, "Ds_Signature": settings.REDSYS_SHARED_SECRET,
@@ -169,11 +169,11 @@ class TestRedsysTPV(APITestCase):
) )
assert response.status_code == status.HTTP_409_CONFLICT assert response.status_code == status.HTTP_409_CONFLICT
order.refresh_from_db() transaction.refresh_from_db()
assert str(ERROR_CODES.get("0184")) in order.observations assert str(ERROR_CODES.get("0184")) in transaction.observations
assert order.status == PaymentTPV.StatusChoices.ERROR assert transaction.status == PaymentTransaction.StatusChoices.ERROR
response = self.client.get( response = self.client.get(
reverse("tpv:ko", kwargs={"order": order.hash}) reverse("tpv:ko", kwargs={"transaction": transaction.hash})
) )
assert response.status_code == status.HTTP_200_OK assert response.status_code == status.HTTP_200_OK
+5 -5
View File
@@ -1,12 +1,12 @@
from django.urls import path from django.urls import path
from tpv.views import order_created, webhook, payment_accepted, payment_rejected from tpv.views import transaction_created, webhook, payment_accepted, payment_rejected
app_name = "tpv" app_name = "tpv"
urlpatterns = [ urlpatterns = [
path("order/<str:order>/", order_created, name="order_created"), path("transaction/<str:transaction>/", transaction_created, name="order_created"),
path("order/<str:order>/webhook/", webhook, name="webhook"), path("transaction/<str:transaction>/webhook/", webhook, name="webhook"),
path("order/<str:order>/ok/", payment_accepted, name="ok"), path("transaction/<str:transaction>/ok/", payment_accepted, name="ok"),
path("order/<str:order>/ko/", payment_rejected, name="ko"), path("transaction/<str:transaction>/ko/", payment_rejected, name="ko"),
] ]
+8 -8
View File
@@ -10,7 +10,7 @@ from decimal import Decimal
from django.utils.text import gettext_lazy as _ from django.utils.text import gettext_lazy as _
from tpv.exceptions import RedsysValidationException, RedsysPaymentException from tpv.exceptions import RedsysValidationException, RedsysPaymentException
from tpv.models import PaymentTPV from tpv.models import PaymentTransaction
from tpv.settings import ERROR_CODES from tpv.settings import ERROR_CODES
@@ -39,7 +39,7 @@ def compare_signatures(signature_1, signature_2):
return sig1safe == sig2safe return sig1safe == sig2safe
def validate_payment_for_order(request, order: PaymentTPV) -> Decimal: def validate_payment_for_transaction(request, transaction: PaymentTransaction) -> Decimal:
""" """
example_response_data = { example_response_data = {
'Ds_MerchantCode': '999008881', 'Ds_MerchantCode': '999008881',
@@ -64,7 +64,7 @@ def validate_payment_for_order(request, order: PaymentTPV) -> Decimal:
} }
:param request: :param request:
:param order: :param transaction:
:return: :return:
""" """
data = request.POST data = request.POST
@@ -79,8 +79,8 @@ def validate_payment_for_order(request, order: PaymentTPV) -> Decimal:
merchant_params = base64.b64decode(merchant_parameters).decode() merchant_params = base64.b64decode(merchant_parameters).decode()
result = json.loads(merchant_params) result = json.loads(merchant_params)
order_hex = result.get("Ds_Order") transaction_hex = result.get("Ds_Order")
assert order_hex == order.hash.hex assert transaction_hex == transaction.hash.hex
status_code = result.get("Ds_Response") status_code = result.get("Ds_Response")
@@ -94,6 +94,6 @@ def validate_payment_for_order(request, order: PaymentTPV) -> Decimal:
return amount return amount
def pay_order(order: PaymentTPV, amount_paid: Decimal): def pay_transaction(transaction: PaymentTransaction, amount_paid: Decimal):
order.status = PaymentTPV.StatusChoices.PAID transaction.status = PaymentTransaction.StatusChoices.PAID
order.save() transaction.save()
+23 -23
View File
@@ -4,68 +4,68 @@ from django.shortcuts import render, get_object_or_404, redirect
from django.http.response import HttpResponse from django.http.response import HttpResponse
from tpv.forms import UpdateEmailForm from tpv.forms import UpdateEmailForm
from tpv.models import PaymentTPV from tpv.models import PaymentTransaction
from tpv.redsys import RedsysClient from tpv.redsys import RedsysClient
from tpv.utils import pay_order, validate_payment_for_order from tpv.utils import pay_transaction, validate_payment_for_transaction
from tpv.signals import redsys_payment_accepted, redsys_payment_rejected from tpv.signals import redsys_payment_accepted, redsys_payment_rejected
def payment_accepted(request, order): def payment_accepted(request, transaction):
order = get_object_or_404(PaymentTPV, hash=order) transaction = get_object_or_404(PaymentTransaction, hash=transaction)
return render( return render(
request, request,
template_name="tpv/order_created.html", template_name="tpv/order_created.html",
context={ context={
"order": order, "order": transaction,
}, },
) )
def payment_rejected(request, order): def payment_rejected(request, transaction):
order = get_object_or_404(PaymentTPV, hash=order) transaction = get_object_or_404(PaymentTransaction, hash=transaction)
return render( return render(
request, request,
template_name="tpv/order_created.html", template_name="tpv/order_created.html",
context={ context={
"order": order, "order": transaction,
}, },
) )
@csrf_exempt @csrf_exempt
def webhook(request, order): def webhook(request, transaction):
order = get_object_or_404(PaymentTPV, hash=order) transaction = get_object_or_404(PaymentTransaction, hash=transaction)
try: try:
amount_paid = validate_payment_for_order(request, order) amount_paid = validate_payment_for_transaction(request, transaction)
pay_order(order, amount_paid) pay_transaction(transaction, amount_paid)
redsys_payment_accepted.send_robust(PaymentTPV.__class__, hash=order.hash) redsys_payment_accepted.send_robust(PaymentTransaction.__class__, hash=transaction.hash)
return HttpResponse(status=200) return HttpResponse(status=200)
except Exception as e: except Exception as e:
order.status = PaymentTPV.StatusChoices.ERROR transaction.status = PaymentTransaction.StatusChoices.ERROR
order.observations = str(e) transaction.observations = str(e)
order.save() transaction.save()
redsys_payment_rejected.send_robust(PaymentTPV.__class__, hash=order.hash) redsys_payment_rejected.send_robust(PaymentTransaction.__class__, hash=transaction.hash)
return HttpResponse(status=409) return HttpResponse(status=409)
def order_created(request, order): def transaction_created(request, transaction):
order = get_object_or_404(PaymentTPV, hash=order) transaction = get_object_or_404(PaymentTransaction, hash=transaction)
client = RedsysClient() client = RedsysClient()
parameters = client.get_body_for_order(order) parameters = client.get_body_for_transaction(transaction)
return render( return render(
request, request,
template_name="tpv/order_created.html", template_name="tpv/order_created.html",
context={ context={
"form": UpdateEmailForm({"contact_email": order.contact_email}), "form": UpdateEmailForm({"contact_email": transaction.contact_email}),
"action": reverse("tpv:order_created", kwargs={"order": order.hash}), "action": reverse("tpv:order_created", kwargs={"transaction": transaction.hash}),
"order": order, "order": transaction,
"signature_version": parameters.get("Ds_SignatureVersion"), "signature_version": parameters.get("Ds_SignatureVersion"),
"merchant_parameters": parameters.get("Ds_MerchantParameters"), "merchant_parameters": parameters.get("Ds_MerchantParameters"),
"signature": parameters.get("Ds_Signature"), "signature": parameters.get("Ds_Signature"),