chore: get datatrans admin helper cleanup

This commit is contained in:
Livio Bieri 2023-11-27 16:59:21 +01:00 committed by Christian Cueni
parent 18385b6870
commit 6f90d381f3
4 changed files with 26 additions and 22 deletions

View File

@ -13,7 +13,6 @@ def generate_invoice(modeladmin, request, queryset):
def sync_transaction_state(modeladmin, request, queryset):
for checkout in queryset:
state = get_transaction_state(transaction_id=checkout.transaction_id)
print(state)
checkout.state = state.value
checkout.save(
update_fields=[

View File

@ -101,7 +101,7 @@ def init_transaction(
def get_transaction_state(
transaction_id: str,
) -> CheckoutState | None:
) -> CheckoutState:
response = requests.get(
f"{settings.DATATRANS_API_ENDPOINT}/v1/transactions/{transaction_id}",
headers={
@ -110,9 +110,6 @@ def get_transaction_state(
},
)
if response.status_code != 200:
return None
transaction_state = response.json()["status"]
logger.info(
@ -121,8 +118,23 @@ def get_transaction_state(
response=transaction_state,
)
return CheckoutState(transaction_state)
return datatrans_state_to_checkout_state(transaction_state)
def get_payment_url(transaction_id: str):
return f"{settings.DATATRANS_PAY_URL}/v1/start/{transaction_id}"
def datatrans_state_to_checkout_state(
transaction_state: str,
) -> CheckoutState:
if transaction_state in ["settled", "transmitted"]:
return CheckoutState.PAID
elif transaction_state == "failed":
return CheckoutState.FAILED
elif transaction_state == "canceled":
return CheckoutState.CANCELED
else:
# An intermediate state such as "initialized", "challenge_ongoing", etc.
# -> we don't care about those states, we only care about final states here.
return CheckoutState.INITIALIZED

View File

@ -73,7 +73,7 @@ class DatatransWebhookTestCase(APITestCase):
)
@patch("vbv_lernwelt.shop.views.is_signature_valid")
def test_webhook_creates_course_session_user(self, mock_is_signature_valid):
def test_webhook_settled_transmitted_paid(self, mock_is_signature_valid):
# GIVEN
transaction_id = "1234567890"

View File

@ -15,6 +15,7 @@ from vbv_lernwelt.shop.models import (
)
from vbv_lernwelt.shop.serializers import BillingAddressSerializer
from vbv_lernwelt.shop.services import (
datatrans_state_to_checkout_state,
get_payment_url,
init_transaction,
InitTransactionException,
@ -66,7 +67,6 @@ def transaction_webhook(request):
Otherwise, this webhook was/will not be called for "initialized" -> "failed" state changes
For timed out transactions (cleaned up in 15 minute intervals, after 30 minutes by them),
"""
logger.info("Webhook: Datatrans called transaction webhook", body=request.body)
if not is_signature_valid(
@ -78,26 +78,19 @@ def transaction_webhook(request):
transaction = request.data
transaction_id = transaction["transactionId"]
transaction_status = transaction["status"]
# keep webhook history for debugging
# keep webhook history (for debugging)
checkout_info = CheckoutInformation.objects.get(transaction_id=transaction_id)
checkout_info.webhook_history.append(transaction)
checkout_info.save(update_fields=["webhook_history"])
# be aware autoSettle has implications on possible transaction states we get!
# See https://api-reference.datatrans.ch/#tag/v1transactions/operation/status
if transaction_status in ["settled", "transmitted"]:
update_checkout_state(checkout_info=checkout_info, state=CheckoutState.PAID)
# update checkout state
checkout_state = datatrans_state_to_checkout_state(transaction["status"])
update_checkout_state(checkout_info=checkout_info, state=checkout_state)
# handle paid
if checkout_state == CheckoutState.PAID:
create_vv_course_session_user(checkout_info=checkout_info)
elif transaction_status == "failed":
update_checkout_state(checkout_info=checkout_info, state=CheckoutState.FAILED)
elif transaction_status == "canceled":
update_checkout_state(checkout_info=checkout_info, state=CheckoutState.CANCELED)
else:
logger.warning(
"Unhandled transaction status", transaction_status=transaction_status
)
return JsonResponse({"status": "ok"})