From bbee825e796463664e239343f50451bdf23f269b Mon Sep 17 00:00:00 2001 From: David Grayston Date: Tue, 11 Nov 2025 23:20:15 +0000 Subject: [PATCH] feat: Added additional support for local Korean payment methods --- CHANGELOG.md | 6 +++ paddle_billing/Entities/PaymentMethod.py | 9 +++- .../Entities/Shared/MethodDetails.py | 9 +++- .../Entities/Shared/PaymentMethodType.py | 5 +++ .../Entities/Shared/SavedPaymentMethodType.py | 5 +++ .../Entities/Shared/SouthKoreaLocalCard.py | 18 ++++++++ .../Shared/SouthKoreaLocalCardType.py | 27 ++++++++++++ paddle_billing/Entities/Shared/__init__.py | 2 + .../Entities/Shared/MethodDetails.py | 9 +++- .../Entities/Shared/PaymentMethodType.py | 5 +++ .../Entities/Shared/SavedPaymentMethodType.py | 5 +++ .../Entities/Shared/SouthKoreaLocalCard.py | 18 ++++++++ .../Shared/SouthKoreaLocalCardType.py | 27 ++++++++++++ .../Notifications/Entities/Shared/__init__.py | 2 + .../_fixtures/response/full_entity_card.json | 1 + .../response/full_entity_korea_local.json | 1 + .../response/full_entity_paypal.json | 1 + .../full_entity_south_korea_local_card.json | 22 ++++++++++ .../_fixtures/response/list_default.json | 2 + .../response/list_paginated_page_one.json | 2 + .../response/list_paginated_page_two.json | 2 + .../test_PaymentMethodsClient.py | 44 +++++++++++++++++++ .../payload/transaction.completed.json | 2 + .../_fixtures/payload/transaction.paid.json | 2 + .../payload/transaction.past_due.json | 1 + .../payload/transaction.payment_failed.json | 1 + .../_fixtures/response/full_entity.json | 6 ++- .../_fixtures/response/list_default.json | 6 ++- .../response/list_paginated_page_one.json | 3 +- .../response/list_paginated_page_two.json | 3 +- .../entity/transaction.completed.json | 2 + .../notification/entity/transaction.paid.json | 22 ++++++++++ .../entity/transaction.past_due.json | 1 + .../entity/transaction.payment_failed.json | 1 + .../entity/transaction.revised.json | 2 + 35 files changed, 265 insertions(+), 9 deletions(-) create mode 100644 paddle_billing/Entities/Shared/SouthKoreaLocalCard.py create mode 100644 paddle_billing/Entities/Shared/SouthKoreaLocalCardType.py create mode 100644 paddle_billing/Notifications/Entities/Shared/SouthKoreaLocalCard.py create mode 100644 paddle_billing/Notifications/Entities/Shared/SouthKoreaLocalCardType.py create mode 100644 tests/Functional/Resources/PaymentMethods/_fixtures/response/full_entity_south_korea_local_card.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 46b76423..60eef903 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,12 +10,18 @@ Check our main [developer changelog](https://developer.paddle.com/?utm_source=dx ### Added +- Added additional support for local Korean payment methods. See [related changelog](https://developer.paddle.com/changelog/2025/improved-korean-payment-methods?utm_source=dx&utm_medium=paddle-python-sdk) - Support for payout reconciliation reports and `remittance_reference`, see [changelog](https://developer.paddle.com/changelog/2025/payout-reconciliation-report?utm_source=dx&utm_medium=paddle-python-sdk) - Added `location` value for `price.tax_mode`, see [changelog](https://developer.paddle.com/changelog/2025/default-automatic-tax-setting?utm_source=dx&utm_medium=paddle-python-sdk) ### Fixed - Fixed `ReportsClient.create()` operation type +### Deprecated + +- `korea_local` payment method type is deprecated. Use `south_korea_local_card`, `kakao_pay`, `naver_pay`, `payco`, or `samsung_pay` instead. +- `underlying_details` is deprecated on `method_details` and saved `payment_method` responses. Use specific payment method fields such as `south_korea_local_card`. + ## 1.11.0 - 2025-10-07 ### Added diff --git a/paddle_billing/Entities/PaymentMethod.py b/paddle_billing/Entities/PaymentMethod.py index 11c9e363..eef29afe 100644 --- a/paddle_billing/Entities/PaymentMethod.py +++ b/paddle_billing/Entities/PaymentMethod.py @@ -10,6 +10,7 @@ Paypal, SavedPaymentMethodOrigin, SavedPaymentMethodType, + SouthKoreaLocalCard, ) @@ -24,7 +25,8 @@ class PaymentMethod(Entity): origin: SavedPaymentMethodOrigin saved_at: datetime updated_at: datetime - underlying_details: PaymentMethodUnderlyingDetails | None + underlying_details: PaymentMethodUnderlyingDetails | None # deprecated + south_korea_local_card: SouthKoreaLocalCard | None @staticmethod def from_dict(data: dict[str, Any]) -> PaymentMethod: @@ -43,4 +45,9 @@ def from_dict(data: dict[str, Any]) -> PaymentMethod: origin=SavedPaymentMethodOrigin(data["origin"]), saved_at=datetime.fromisoformat(data["saved_at"]), updated_at=datetime.fromisoformat(data["updated_at"]), + south_korea_local_card=( + SouthKoreaLocalCard.from_dict(data["south_korea_local_card"]) + if data.get("south_korea_local_card") + else None + ), ) diff --git a/paddle_billing/Entities/Shared/MethodDetails.py b/paddle_billing/Entities/Shared/MethodDetails.py index b6d072d0..15443e9a 100644 --- a/paddle_billing/Entities/Shared/MethodDetails.py +++ b/paddle_billing/Entities/Shared/MethodDetails.py @@ -5,13 +5,15 @@ from paddle_billing.Entities.Shared.Card import Card from paddle_billing.Entities.Shared.PaymentMethodType import PaymentMethodType from paddle_billing.Entities.Shared.PaymentMethodUnderlyingDetails import PaymentMethodUnderlyingDetails +from paddle_billing.Entities.Shared.SouthKoreaLocalCard import SouthKoreaLocalCard @dataclass class MethodDetails: type: PaymentMethodType card: Card | None - underlying_details: PaymentMethodUnderlyingDetails | None + underlying_details: PaymentMethodUnderlyingDetails | None # deprecated + south_korea_local_card: SouthKoreaLocalCard | None @staticmethod def from_dict(data: dict[str, Any]) -> MethodDetails: @@ -23,4 +25,9 @@ def from_dict(data: dict[str, Any]) -> MethodDetails: if data.get("underlying_details") else None ), + ( + SouthKoreaLocalCard.from_dict(data["south_korea_local_card"]) + if data.get("south_korea_local_card") + else None + ), ) diff --git a/paddle_billing/Entities/Shared/PaymentMethodType.py b/paddle_billing/Entities/Shared/PaymentMethodType.py index 15f8d20c..cb664e9f 100644 --- a/paddle_billing/Entities/Shared/PaymentMethodType.py +++ b/paddle_billing/Entities/Shared/PaymentMethodType.py @@ -9,11 +9,16 @@ class PaymentMethodType(PaddleStrEnum, metaclass=PaddleStrEnumMeta): Card: "PaymentMethodType" = "card" GooglePay: "PaymentMethodType" = "google_pay" Ideal: "PaymentMethodType" = "ideal" + KakaoPay: "PaymentMethodType" = "kakao_pay" KoreaLocal: "PaymentMethodType" = "korea_local" MbWay: "PaymentMethodType" = "mb_way" + NaverPay: "PaymentMethodType" = "naver_pay" Offline: "PaymentMethodType" = "offline" + Payco: "PaymentMethodType" = "payco" Paypal: "PaymentMethodType" = "paypal" Pix: "PaymentMethodType" = "pix" + SamsungPay: "PaymentMethodType" = "samsung_pay" + SouthKoreaLocalCard: "PaymentMethodType" = "south_korea_local_card" Unknown: "PaymentMethodType" = "unknown" Upi: "PaymentMethodType" = "upi" WireTransfer: "PaymentMethodType" = "wire_transfer" diff --git a/paddle_billing/Entities/Shared/SavedPaymentMethodType.py b/paddle_billing/Entities/Shared/SavedPaymentMethodType.py index aabd3519..677fc7ab 100644 --- a/paddle_billing/Entities/Shared/SavedPaymentMethodType.py +++ b/paddle_billing/Entities/Shared/SavedPaymentMethodType.py @@ -7,8 +7,13 @@ class SavedPaymentMethodType(PaddleStrEnum, metaclass=PaddleStrEnumMeta): Blik: "SavedPaymentMethodType" = "blik" Card: "SavedPaymentMethodType" = "card" GooglePay: "SavedPaymentMethodType" = "google_pay" + KakaoPay: "SavedPaymentMethodType" = "kakao_pay" KoreaLocal: "SavedPaymentMethodType" = "korea_local" MbWay: "SavedPaymentMethodType" = "mb_way" + NaverPay: "SavedPaymentMethodType" = "naver_pay" + Payco: "SavedPaymentMethodType" = "payco" Paypal: "SavedPaymentMethodType" = "paypal" Pix: "SavedPaymentMethodType" = "pix" + SamsungPay: "SavedPaymentMethodType" = "samsung_pay" + SouthKoreaLocalCard: "SavedPaymentMethodType" = "south_korea_local_card" Upi: "SavedPaymentMethodType" = "upi" diff --git a/paddle_billing/Entities/Shared/SouthKoreaLocalCard.py b/paddle_billing/Entities/Shared/SouthKoreaLocalCard.py new file mode 100644 index 00000000..e69b1570 --- /dev/null +++ b/paddle_billing/Entities/Shared/SouthKoreaLocalCard.py @@ -0,0 +1,18 @@ +from __future__ import annotations +from dataclasses import dataclass +from typing import Any + +from paddle_billing.Entities.Shared.SouthKoreaLocalCardType import SouthKoreaLocalCardType + + +@dataclass +class SouthKoreaLocalCard: + type: SouthKoreaLocalCardType + last4: str + + @staticmethod + def from_dict(data: dict[str, Any]) -> SouthKoreaLocalCard: + return SouthKoreaLocalCard( + type=SouthKoreaLocalCardType(data["type"]), + last4=data["last4"], + ) diff --git a/paddle_billing/Entities/Shared/SouthKoreaLocalCardType.py b/paddle_billing/Entities/Shared/SouthKoreaLocalCardType.py new file mode 100644 index 00000000..8728a7dd --- /dev/null +++ b/paddle_billing/Entities/Shared/SouthKoreaLocalCardType.py @@ -0,0 +1,27 @@ +from paddle_billing.PaddleStrEnum import PaddleStrEnum, PaddleStrEnumMeta + + +class SouthKoreaLocalCardType(PaddleStrEnum, metaclass=PaddleStrEnumMeta): + BC: "SouthKoreaLocalCardType" = "bc" + Citi: "SouthKoreaLocalCardType" = "citi" + Hana: "SouthKoreaLocalCardType" = "hana" + Hyundai: "SouthKoreaLocalCardType" = "hyundai" + Jeju: "SouthKoreaLocalCardType" = "jeju" + Jeonbuk: "SouthKoreaLocalCardType" = "jeonbuk" + KakaoBank: "SouthKoreaLocalCardType" = "kakaobank" + KBank: "SouthKoreaLocalCardType" = "kbank" + KDBBank: "SouthKoreaLocalCardType" = "kdbbank" + Kookmin: "SouthKoreaLocalCardType" = "kookmin" + Kwangju: "SouthKoreaLocalCardType" = "kwangju" + Lotte: "SouthKoreaLocalCardType" = "lotte" + MG: "SouthKoreaLocalCardType" = "mg" + NH: "SouthKoreaLocalCardType" = "nh" + Post: "SouthKoreaLocalCardType" = "post" + Samsung: "SouthKoreaLocalCardType" = "samsung" + SavingsBank: "SouthKoreaLocalCardType" = "savingsbank" + Shinhan: "SouthKoreaLocalCardType" = "shinhan" + Shinhyup: "SouthKoreaLocalCardType" = "shinhyup" + Suhyup: "SouthKoreaLocalCardType" = "suhyup" + TossBank: "SouthKoreaLocalCardType" = "tossbank" + Unknown: "SouthKoreaLocalCardType" = "unknown" + Woori: "SouthKoreaLocalCardType" = "woori" diff --git a/paddle_billing/Entities/Shared/__init__.py b/paddle_billing/Entities/Shared/__init__.py index 4075d228..96102c61 100644 --- a/paddle_billing/Entities/Shared/__init__.py +++ b/paddle_billing/Entities/Shared/__init__.py @@ -35,6 +35,8 @@ from paddle_billing.Entities.Shared.PaymentAttemptStatus import PaymentAttemptStatus from paddle_billing.Entities.Shared.PaymentMethodType import PaymentMethodType from paddle_billing.Entities.Shared.PaymentMethodUnderlyingDetails import PaymentMethodUnderlyingDetails +from paddle_billing.Entities.Shared.SouthKoreaLocalCard import SouthKoreaLocalCard +from paddle_billing.Entities.Shared.SouthKoreaLocalCardType import SouthKoreaLocalCardType from paddle_billing.Entities.Shared.PayoutTotalsAdjustment import PayoutTotalsAdjustment from paddle_billing.Entities.Shared.Paypal import Paypal from paddle_billing.Entities.Shared.PriceQuantity import PriceQuantity diff --git a/paddle_billing/Notifications/Entities/Shared/MethodDetails.py b/paddle_billing/Notifications/Entities/Shared/MethodDetails.py index 14689e21..e2bbca6d 100644 --- a/paddle_billing/Notifications/Entities/Shared/MethodDetails.py +++ b/paddle_billing/Notifications/Entities/Shared/MethodDetails.py @@ -5,13 +5,15 @@ from paddle_billing.Notifications.Entities.Shared.Card import Card from paddle_billing.Notifications.Entities.Shared.PaymentMethodType import PaymentMethodType from paddle_billing.Notifications.Entities.Shared.PaymentMethodUnderlyingDetails import PaymentMethodUnderlyingDetails +from paddle_billing.Notifications.Entities.Shared.SouthKoreaLocalCard import SouthKoreaLocalCard @dataclass class MethodDetails: type: PaymentMethodType card: Card | None - underlying_details: PaymentMethodUnderlyingDetails | None + underlying_details: PaymentMethodUnderlyingDetails | None # deprecated + south_korea_local_card: SouthKoreaLocalCard | None @staticmethod def from_dict(data: dict[str, Any]) -> MethodDetails: @@ -23,4 +25,9 @@ def from_dict(data: dict[str, Any]) -> MethodDetails: if data.get("underlying_details") else None ), + ( + SouthKoreaLocalCard.from_dict(data["south_korea_local_card"]) + if data.get("south_korea_local_card") + else None + ), ) diff --git a/paddle_billing/Notifications/Entities/Shared/PaymentMethodType.py b/paddle_billing/Notifications/Entities/Shared/PaymentMethodType.py index 15f8d20c..cb664e9f 100644 --- a/paddle_billing/Notifications/Entities/Shared/PaymentMethodType.py +++ b/paddle_billing/Notifications/Entities/Shared/PaymentMethodType.py @@ -9,11 +9,16 @@ class PaymentMethodType(PaddleStrEnum, metaclass=PaddleStrEnumMeta): Card: "PaymentMethodType" = "card" GooglePay: "PaymentMethodType" = "google_pay" Ideal: "PaymentMethodType" = "ideal" + KakaoPay: "PaymentMethodType" = "kakao_pay" KoreaLocal: "PaymentMethodType" = "korea_local" MbWay: "PaymentMethodType" = "mb_way" + NaverPay: "PaymentMethodType" = "naver_pay" Offline: "PaymentMethodType" = "offline" + Payco: "PaymentMethodType" = "payco" Paypal: "PaymentMethodType" = "paypal" Pix: "PaymentMethodType" = "pix" + SamsungPay: "PaymentMethodType" = "samsung_pay" + SouthKoreaLocalCard: "PaymentMethodType" = "south_korea_local_card" Unknown: "PaymentMethodType" = "unknown" Upi: "PaymentMethodType" = "upi" WireTransfer: "PaymentMethodType" = "wire_transfer" diff --git a/paddle_billing/Notifications/Entities/Shared/SavedPaymentMethodType.py b/paddle_billing/Notifications/Entities/Shared/SavedPaymentMethodType.py index aabd3519..677fc7ab 100644 --- a/paddle_billing/Notifications/Entities/Shared/SavedPaymentMethodType.py +++ b/paddle_billing/Notifications/Entities/Shared/SavedPaymentMethodType.py @@ -7,8 +7,13 @@ class SavedPaymentMethodType(PaddleStrEnum, metaclass=PaddleStrEnumMeta): Blik: "SavedPaymentMethodType" = "blik" Card: "SavedPaymentMethodType" = "card" GooglePay: "SavedPaymentMethodType" = "google_pay" + KakaoPay: "SavedPaymentMethodType" = "kakao_pay" KoreaLocal: "SavedPaymentMethodType" = "korea_local" MbWay: "SavedPaymentMethodType" = "mb_way" + NaverPay: "SavedPaymentMethodType" = "naver_pay" + Payco: "SavedPaymentMethodType" = "payco" Paypal: "SavedPaymentMethodType" = "paypal" Pix: "SavedPaymentMethodType" = "pix" + SamsungPay: "SavedPaymentMethodType" = "samsung_pay" + SouthKoreaLocalCard: "SavedPaymentMethodType" = "south_korea_local_card" Upi: "SavedPaymentMethodType" = "upi" diff --git a/paddle_billing/Notifications/Entities/Shared/SouthKoreaLocalCard.py b/paddle_billing/Notifications/Entities/Shared/SouthKoreaLocalCard.py new file mode 100644 index 00000000..ea23df93 --- /dev/null +++ b/paddle_billing/Notifications/Entities/Shared/SouthKoreaLocalCard.py @@ -0,0 +1,18 @@ +from __future__ import annotations +from dataclasses import dataclass +from typing import Any + +from paddle_billing.Notifications.Entities.Shared.SouthKoreaLocalCardType import SouthKoreaLocalCardType + + +@dataclass +class SouthKoreaLocalCard: + type: SouthKoreaLocalCardType + last4: str + + @staticmethod + def from_dict(data: dict[str, Any]) -> SouthKoreaLocalCard: + return SouthKoreaLocalCard( + type=SouthKoreaLocalCardType(data["type"]), + last4=data["last4"], + ) diff --git a/paddle_billing/Notifications/Entities/Shared/SouthKoreaLocalCardType.py b/paddle_billing/Notifications/Entities/Shared/SouthKoreaLocalCardType.py new file mode 100644 index 00000000..8728a7dd --- /dev/null +++ b/paddle_billing/Notifications/Entities/Shared/SouthKoreaLocalCardType.py @@ -0,0 +1,27 @@ +from paddle_billing.PaddleStrEnum import PaddleStrEnum, PaddleStrEnumMeta + + +class SouthKoreaLocalCardType(PaddleStrEnum, metaclass=PaddleStrEnumMeta): + BC: "SouthKoreaLocalCardType" = "bc" + Citi: "SouthKoreaLocalCardType" = "citi" + Hana: "SouthKoreaLocalCardType" = "hana" + Hyundai: "SouthKoreaLocalCardType" = "hyundai" + Jeju: "SouthKoreaLocalCardType" = "jeju" + Jeonbuk: "SouthKoreaLocalCardType" = "jeonbuk" + KakaoBank: "SouthKoreaLocalCardType" = "kakaobank" + KBank: "SouthKoreaLocalCardType" = "kbank" + KDBBank: "SouthKoreaLocalCardType" = "kdbbank" + Kookmin: "SouthKoreaLocalCardType" = "kookmin" + Kwangju: "SouthKoreaLocalCardType" = "kwangju" + Lotte: "SouthKoreaLocalCardType" = "lotte" + MG: "SouthKoreaLocalCardType" = "mg" + NH: "SouthKoreaLocalCardType" = "nh" + Post: "SouthKoreaLocalCardType" = "post" + Samsung: "SouthKoreaLocalCardType" = "samsung" + SavingsBank: "SouthKoreaLocalCardType" = "savingsbank" + Shinhan: "SouthKoreaLocalCardType" = "shinhan" + Shinhyup: "SouthKoreaLocalCardType" = "shinhyup" + Suhyup: "SouthKoreaLocalCardType" = "suhyup" + TossBank: "SouthKoreaLocalCardType" = "tossbank" + Unknown: "SouthKoreaLocalCardType" = "unknown" + Woori: "SouthKoreaLocalCardType" = "woori" diff --git a/paddle_billing/Notifications/Entities/Shared/__init__.py b/paddle_billing/Notifications/Entities/Shared/__init__.py index 06470cac..aeb63206 100644 --- a/paddle_billing/Notifications/Entities/Shared/__init__.py +++ b/paddle_billing/Notifications/Entities/Shared/__init__.py @@ -27,6 +27,8 @@ from paddle_billing.Notifications.Entities.Shared.Original import Original from paddle_billing.Notifications.Entities.Shared.PaymentAttemptStatus import PaymentAttemptStatus from paddle_billing.Notifications.Entities.Shared.PaymentMethodType import PaymentMethodType +from paddle_billing.Notifications.Entities.Shared.SouthKoreaLocalCard import SouthKoreaLocalCard +from paddle_billing.Notifications.Entities.Shared.SouthKoreaLocalCardType import SouthKoreaLocalCardType from paddle_billing.Notifications.Entities.Shared.PayoutTotalsAdjustment import PayoutTotalsAdjustment from paddle_billing.Notifications.Entities.Shared.Paypal import Paypal from paddle_billing.Notifications.Entities.Shared.PriceQuantity import PriceQuantity diff --git a/tests/Functional/Resources/PaymentMethods/_fixtures/response/full_entity_card.json b/tests/Functional/Resources/PaymentMethods/_fixtures/response/full_entity_card.json index 97ca643a..d1d6245e 100644 --- a/tests/Functional/Resources/PaymentMethods/_fixtures/response/full_entity_card.json +++ b/tests/Functional/Resources/PaymentMethods/_fixtures/response/full_entity_card.json @@ -12,6 +12,7 @@ "cardholder_name": "Sam Miller" }, "paypal": null, + "south_korea_local_card": null, "origin": "subscription", "saved_at": "2024-05-03T11:50:23.422Z", "updated_at": "2024-05-04T11:50:23.422Z", diff --git a/tests/Functional/Resources/PaymentMethods/_fixtures/response/full_entity_korea_local.json b/tests/Functional/Resources/PaymentMethods/_fixtures/response/full_entity_korea_local.json index eb8f415d..d50cbdca 100644 --- a/tests/Functional/Resources/PaymentMethods/_fixtures/response/full_entity_korea_local.json +++ b/tests/Functional/Resources/PaymentMethods/_fixtures/response/full_entity_korea_local.json @@ -7,6 +7,7 @@ "type": "korea_local", "card": null, "paypal": null, + "south_korea_local_card": null, "origin": "subscription", "saved_at": "2024-05-03T11:50:23.422Z", "updated_at": "2024-05-04T11:50:23.422Z", diff --git a/tests/Functional/Resources/PaymentMethods/_fixtures/response/full_entity_paypal.json b/tests/Functional/Resources/PaymentMethods/_fixtures/response/full_entity_paypal.json index 261be4fb..f8b34c1a 100644 --- a/tests/Functional/Resources/PaymentMethods/_fixtures/response/full_entity_paypal.json +++ b/tests/Functional/Resources/PaymentMethods/_fixtures/response/full_entity_paypal.json @@ -9,6 +9,7 @@ "email": "sam@example.com", "reference": "some-reference" }, + "south_korea_local_card": null, "origin": "saved_during_purchase", "saved_at": "2024-05-03T11:50:23.422Z", "updated_at": "2024-05-04T11:50:23.422Z" diff --git a/tests/Functional/Resources/PaymentMethods/_fixtures/response/full_entity_south_korea_local_card.json b/tests/Functional/Resources/PaymentMethods/_fixtures/response/full_entity_south_korea_local_card.json new file mode 100644 index 00000000..7db79f58 --- /dev/null +++ b/tests/Functional/Resources/PaymentMethods/_fixtures/response/full_entity_south_korea_local_card.json @@ -0,0 +1,22 @@ +{ + "data": { + "id": "paymtd_01hs8zx6x377xfsfrt2bqsevbw", + "customer_id": "ctm_01hv6y1jedq4p1n0yqn5ba3ky4", + "address_id": "add_01hv8h6jj90jjz0d71m6hj4r9z", + "type": "south_korea_local_card", + "card": null, + "paypal": null, + "south_korea_local_card": { + "type": "kookmin", + "last4": "4242" + }, + "origin": "subscription", + "saved_at": "2024-05-03T11:50:23.422Z", + "updated_at": "2024-05-04T11:50:23.422Z" + }, + "meta": { + "request_id": "03dae283-b7e9-47dc-b8c0-229576d90139" + } +} + + diff --git a/tests/Functional/Resources/PaymentMethods/_fixtures/response/list_default.json b/tests/Functional/Resources/PaymentMethods/_fixtures/response/list_default.json index 58a9f590..6e2ff8eb 100644 --- a/tests/Functional/Resources/PaymentMethods/_fixtures/response/list_default.json +++ b/tests/Functional/Resources/PaymentMethods/_fixtures/response/list_default.json @@ -13,6 +13,7 @@ }, "cardholder_name": "Sam Miller", "paypal": null, + "south_korea_local_card": null, "origin": "saved_during_purchase", "saved_at": "2024-05-03T11:50:23.422Z", "updated_at": "2024-05-03T11:50:23.422Z" @@ -30,6 +31,7 @@ }, "cardholder_name": "Sam Miller", "paypal": null, + "south_korea_local_card": null, "origin": "saved_during_purchase", "saved_at": "2024-05-03T11:50:23.422Z", "updated_at": "2024-05-03T11:50:23.422Z" diff --git a/tests/Functional/Resources/PaymentMethods/_fixtures/response/list_paginated_page_one.json b/tests/Functional/Resources/PaymentMethods/_fixtures/response/list_paginated_page_one.json index f5a9f7ad..99010be6 100644 --- a/tests/Functional/Resources/PaymentMethods/_fixtures/response/list_paginated_page_one.json +++ b/tests/Functional/Resources/PaymentMethods/_fixtures/response/list_paginated_page_one.json @@ -13,6 +13,7 @@ }, "cardholder_name": "Sam Miller", "paypal": null, + "south_korea_local_card": null, "origin": "saved_during_purchase", "saved_at": "2024-05-03T11:50:23.422Z", "updated_at": "2024-05-03T11:50:23.422Z" @@ -30,6 +31,7 @@ }, "cardholder_name": "Sam Miller", "paypal": null, + "south_korea_local_card": null, "origin": "saved_during_purchase", "saved_at": "2024-05-03T11:50:23.422Z", "updated_at": "2024-05-03T11:50:23.422Z" diff --git a/tests/Functional/Resources/PaymentMethods/_fixtures/response/list_paginated_page_two.json b/tests/Functional/Resources/PaymentMethods/_fixtures/response/list_paginated_page_two.json index 7c774b00..3e584cea 100644 --- a/tests/Functional/Resources/PaymentMethods/_fixtures/response/list_paginated_page_two.json +++ b/tests/Functional/Resources/PaymentMethods/_fixtures/response/list_paginated_page_two.json @@ -13,6 +13,7 @@ }, "cardholder_name": "Sam Miller", "paypal": null, + "south_korea_local_card": null, "origin": "saved_during_purchase", "saved_at": "2024-05-03T11:50:23.422Z", "updated_at": "2024-05-03T11:50:23.422Z" @@ -30,6 +31,7 @@ }, "cardholder_name": "Sam Miller", "paypal": null, + "south_korea_local_card": null, "origin": "saved_during_purchase", "saved_at": "2024-05-03T11:50:23.422Z", "updated_at": "2024-05-03T11:50:23.422Z" diff --git a/tests/Functional/Resources/PaymentMethods/test_PaymentMethodsClient.py b/tests/Functional/Resources/PaymentMethods/test_PaymentMethodsClient.py index 2229e1f8..4a879920 100644 --- a/tests/Functional/Resources/PaymentMethods/test_PaymentMethodsClient.py +++ b/tests/Functional/Resources/PaymentMethods/test_PaymentMethodsClient.py @@ -18,6 +18,7 @@ Paypal, SavedPaymentMethodOrigin, SavedPaymentMethodType, + SouthKoreaLocalCardType, ) from tests.Utils.ReadsFixture import ReadsFixtures @@ -313,6 +314,49 @@ def test_get_payment_methods_returns_expected_korea_local_response( assert isinstance(underlying_details, PaymentMethodUnderlyingDetails) assert underlying_details.korea_local.type == KoreaLocalPaymentMethodType.KakaoBank + def test_get_payment_methods_returns_expected_south_korea_local_card_response( + self, + test_client, + mock_requests, + ): + customer_id = "ctm_01hv6y1jedq4p1n0yqn5ba3ky4" + payment_method_id = "paymtd_01hs8zx6x377xfsfrt2bqsevbw" + expected_response_status = 200 + expected_response_body = ReadsFixtures.read_raw_json_fixture("response/full_entity_south_korea_local_card") + expected_path = "/customers/ctm_01hv6y1jedq4p1n0yqn5ba3ky4/payment-methods/paymtd_01hs8zx6x377xfsfrt2bqsevbw" + + expected_url = f"{test_client.base_url}{expected_path}" + mock_requests.get(expected_url, status_code=expected_response_status, text=expected_response_body) + + response = test_client.client.payment_methods.get(customer_id, payment_method_id) + response_json = test_client.client.payment_methods.response.json() + last_request = mock_requests.last_request + + assert isinstance(response, PaymentMethod) + assert last_request is not None + assert last_request.method == "GET" + assert test_client.client.status_code == expected_response_status + assert ( + unquote(last_request.url) == expected_url + ), "The URL does not match the expected URL, verify the query string is correct" + assert response_json == loads( + str(expected_response_body) + ), "The response JSON generated by ResponseParser() doesn't match the expected fixture JSON" + + assert response.id == "paymtd_01hs8zx6x377xfsfrt2bqsevbw" + assert response.customer_id == "ctm_01hv6y1jedq4p1n0yqn5ba3ky4" + assert response.address_id == "add_01hv8h6jj90jjz0d71m6hj4r9z" + assert response.card is None + assert response.paypal is None + assert response.type == SavedPaymentMethodType.SouthKoreaLocalCard + assert response.origin == SavedPaymentMethodOrigin.Subscription + assert response.saved_at.isoformat() == "2024-05-03T11:50:23.422000+00:00" + assert response.updated_at.isoformat() == "2024-05-04T11:50:23.422000+00:00" + + assert response.south_korea_local_card is not None + assert response.south_korea_local_card.type == SouthKoreaLocalCardType.Kookmin + assert response.south_korea_local_card.last4 == "4242" + def test_delete_payment_method_returns_expected_response( self, test_client, diff --git a/tests/Functional/Resources/Simulations/_fixtures/payload/transaction.completed.json b/tests/Functional/Resources/Simulations/_fixtures/payload/transaction.completed.json index 0cc9f88e..bf5f1c3e 100644 --- a/tests/Functional/Resources/Simulations/_fixtures/payload/transaction.completed.json +++ b/tests/Functional/Resources/Simulations/_fixtures/payload/transaction.completed.json @@ -277,6 +277,7 @@ "cardholder_name": "Michael McGovern" }, "type": "card", + "south_korea_local_card": null, "underlying_details": null }, "payment_method_id": "paymtd_01hv8x1tpjfnttxddw73xnqx6s", @@ -298,6 +299,7 @@ "cardholder_name": "Michael McGovern" }, "type": "card", + "south_korea_local_card": null, "underlying_details": null }, "payment_method_id": "paymtd_01hv8wx2mka7dfsqjjsxh1ne7z", diff --git a/tests/Functional/Resources/Simulations/_fixtures/payload/transaction.paid.json b/tests/Functional/Resources/Simulations/_fixtures/payload/transaction.paid.json index 6bbd91fd..f7895e51 100644 --- a/tests/Functional/Resources/Simulations/_fixtures/payload/transaction.paid.json +++ b/tests/Functional/Resources/Simulations/_fixtures/payload/transaction.paid.json @@ -263,6 +263,7 @@ "cardholder_name": "Michael McGovern" }, "type": "card", + "south_korea_local_card": null, "underlying_details": null }, "payment_method_id": "paymtd_01hv8x1tpjfnttxddw73xnqx6s", @@ -284,6 +285,7 @@ "cardholder_name": "Michael McGovern" }, "type": "card", + "south_korea_local_card": null, "underlying_details": null }, "payment_method_id": "paymtd_01hv8wx2mka7dfsqjjsxh1ne7z", diff --git a/tests/Functional/Resources/Simulations/_fixtures/payload/transaction.past_due.json b/tests/Functional/Resources/Simulations/_fixtures/payload/transaction.past_due.json index 55b19811..c17c8700 100644 --- a/tests/Functional/Resources/Simulations/_fixtures/payload/transaction.past_due.json +++ b/tests/Functional/Resources/Simulations/_fixtures/payload/transaction.past_due.json @@ -227,6 +227,7 @@ "cardholder_name": "Michael McGovern" }, "type": "card", + "south_korea_local_card": null, "underlying_details": null }, "payment_method_id": "paymtd_01hv8x1tpjfnttxddw73xnqx6s", diff --git a/tests/Functional/Resources/Simulations/_fixtures/payload/transaction.payment_failed.json b/tests/Functional/Resources/Simulations/_fixtures/payload/transaction.payment_failed.json index 28b5c82e..661674c4 100644 --- a/tests/Functional/Resources/Simulations/_fixtures/payload/transaction.payment_failed.json +++ b/tests/Functional/Resources/Simulations/_fixtures/payload/transaction.payment_failed.json @@ -263,6 +263,7 @@ "cardholder_name": "Michael McGovern" }, "type": "card", + "south_korea_local_card": null, "underlying_details": null }, "payment_method_id": "paymtd_01hv8wx2mka7dfsqjjsxh1ne7z", diff --git a/tests/Functional/Resources/Transactions/_fixtures/response/full_entity.json b/tests/Functional/Resources/Transactions/_fixtures/response/full_entity.json index 08f1381a..c9c154c0 100644 --- a/tests/Functional/Resources/Transactions/_fixtures/response/full_entity.json +++ b/tests/Functional/Resources/Transactions/_fixtures/response/full_entity.json @@ -177,7 +177,8 @@ "expiry_month": 1, "expiry_year": 2024, "cardholder_name": "Joe Bloggs" - } + }, + "south_korea_local_card": null }, "created_at": "2023-08-18T21:13:07.18821Z", "captured_at": "2023-08-18T21:13:09.477933Z" @@ -197,7 +198,8 @@ "expiry_month": 1, "expiry_year": 2024, "cardholder_name": "Joe Bloggs" - } + }, + "south_korea_local_card": null }, "created_at": "2023-08-18T21:13:07.18821Z", "captured_at": "2023-08-18T21:13:09.477933Z" diff --git a/tests/Functional/Resources/Transactions/_fixtures/response/list_default.json b/tests/Functional/Resources/Transactions/_fixtures/response/list_default.json index d3185c81..66a2d189 100644 --- a/tests/Functional/Resources/Transactions/_fixtures/response/list_default.json +++ b/tests/Functional/Resources/Transactions/_fixtures/response/list_default.json @@ -975,7 +975,8 @@ "expiry_month": 1, "expiry_year": 2024, "cardholder_name": "Joe Bloggs" - } + }, + "south_korea_local_card": null }, "created_at": "2023-08-18T21:13:07.18821Z", "captured_at": "2023-08-18T21:13:09.477933Z" @@ -995,7 +996,8 @@ "expiry_month": 1, "expiry_year": 2024, "cardholder_name": "Joe Bloggs" - } + }, + "south_korea_local_card": null }, "created_at": "2023-08-18T21:13:07.18821Z", "captured_at": "2023-08-18T21:13:09.477933Z" diff --git a/tests/Functional/Resources/Transactions/_fixtures/response/list_paginated_page_one.json b/tests/Functional/Resources/Transactions/_fixtures/response/list_paginated_page_one.json index 4310c98d..c9e754e7 100644 --- a/tests/Functional/Resources/Transactions/_fixtures/response/list_paginated_page_one.json +++ b/tests/Functional/Resources/Transactions/_fixtures/response/list_paginated_page_one.json @@ -961,7 +961,8 @@ "expiry_month": 1, "expiry_year": 2024, "cardholder_name": "Joe Bloggs" - } + }, + "south_korea_local_card": null }, "created_at": "2023-08-18T21:13:07.18821Z", "captured_at": "2023-08-18T21:13:09.477933Z" diff --git a/tests/Functional/Resources/Transactions/_fixtures/response/list_paginated_page_two.json b/tests/Functional/Resources/Transactions/_fixtures/response/list_paginated_page_two.json index 94aa826d..2984dea1 100644 --- a/tests/Functional/Resources/Transactions/_fixtures/response/list_paginated_page_two.json +++ b/tests/Functional/Resources/Transactions/_fixtures/response/list_paginated_page_two.json @@ -961,7 +961,8 @@ "expiry_month": 1, "expiry_year": 2024, "cardholder_name": "Joe Bloggs" - } + }, + "south_korea_local_card": null }, "created_at": "2023-08-18T21:13:07.18821Z", "captured_at": "2023-08-18T21:13:09.477933Z" diff --git a/tests/Unit/Entities/_fixtures/notification/entity/transaction.completed.json b/tests/Unit/Entities/_fixtures/notification/entity/transaction.completed.json index 37623a2b..2c69caad 100644 --- a/tests/Unit/Entities/_fixtures/notification/entity/transaction.completed.json +++ b/tests/Unit/Entities/_fixtures/notification/entity/transaction.completed.json @@ -277,6 +277,7 @@ "cardholder_name": "Michael McGovern" }, "type": "card", + "south_korea_local_card": null, "underlying_details": null }, "payment_method_id": "paymtd_01hv8x1tpjfnttxddw73xnqx6s", @@ -298,6 +299,7 @@ "cardholder_name": "Michael McGovern" }, "type": "card", + "south_korea_local_card": null, "underlying_details": null }, "payment_method_id": "paymtd_01hv8wx2mka7dfsqjjsxh1ne7z", diff --git a/tests/Unit/Entities/_fixtures/notification/entity/transaction.paid.json b/tests/Unit/Entities/_fixtures/notification/entity/transaction.paid.json index 52ef9095..e0fb0b33 100644 --- a/tests/Unit/Entities/_fixtures/notification/entity/transaction.paid.json +++ b/tests/Unit/Entities/_fixtures/notification/entity/transaction.paid.json @@ -263,6 +263,7 @@ "cardholder_name": "Michael McGovern" }, "type": "card", + "south_korea_local_card": null, "underlying_details": null }, "payment_method_id": "paymtd_01hv8x1tpjfnttxddw73xnqx6s", @@ -284,6 +285,7 @@ "cardholder_name": "Michael McGovern" }, "type": "card", + "south_korea_local_card": null, "underlying_details": null }, "payment_method_id": "paymtd_01hv8wx2mka7dfsqjjsxh1ne7z", @@ -299,6 +301,7 @@ "method_details": { "card": null, "type": "korea_local", + "south_korea_local_card": null, "underlying_details": { "korea_local": { "type": "kdbbank" @@ -308,6 +311,25 @@ "payment_method_id": "paymtd_01hv8wx2mka7dfsqjjsxh1ne7z", "payment_attempt_id": "8f72cfa6-26b4-4a57-91dc-8f2708f7822d", "stored_payment_method_id": "a78ece50-356f-4e0c-b72d-ad5368b0a0d9" + }, + { + "amount": "65215", + "status": "error", + "created_at": "2024-04-12T10:18:40.000000Z", + "error_code": "declined", + "captured_at": null, + "method_details": { + "card": null, + "type": "south_korea_local_card", + "south_korea_local_card": { + "type": "kakaobank", + "last4": "4242" + }, + "underlying_details": null + }, + "payment_method_id": "paymtd_01hv8wx2mka7dfsqjjsxh1ne8a", + "payment_attempt_id": "9a82cfa6-26b4-4a57-91dc-8f2708f7822e", + "stored_payment_method_id": "b78ece50-356f-4e0c-b72d-ad5368b0a0d8" } ], "billed_at": "2024-04-12T10:18:48.294633Z", diff --git a/tests/Unit/Entities/_fixtures/notification/entity/transaction.past_due.json b/tests/Unit/Entities/_fixtures/notification/entity/transaction.past_due.json index a2af329b..a4854b58 100644 --- a/tests/Unit/Entities/_fixtures/notification/entity/transaction.past_due.json +++ b/tests/Unit/Entities/_fixtures/notification/entity/transaction.past_due.json @@ -227,6 +227,7 @@ "cardholder_name": "Michael McGovern" }, "type": "card", + "south_korea_local_card": null, "underlying_details": null }, "payment_method_id": "paymtd_01hv8x1tpjfnttxddw73xnqx6s", diff --git a/tests/Unit/Entities/_fixtures/notification/entity/transaction.payment_failed.json b/tests/Unit/Entities/_fixtures/notification/entity/transaction.payment_failed.json index 41bed503..404ac4bf 100644 --- a/tests/Unit/Entities/_fixtures/notification/entity/transaction.payment_failed.json +++ b/tests/Unit/Entities/_fixtures/notification/entity/transaction.payment_failed.json @@ -263,6 +263,7 @@ "cardholder_name": "Michael McGovern" }, "type": "card", + "south_korea_local_card": null, "underlying_details": null }, "payment_method_id": "paymtd_01hv8wx2mka7dfsqjjsxh1ne7z", diff --git a/tests/Unit/Entities/_fixtures/notification/entity/transaction.revised.json b/tests/Unit/Entities/_fixtures/notification/entity/transaction.revised.json index d33c293b..d9a7f61d 100644 --- a/tests/Unit/Entities/_fixtures/notification/entity/transaction.revised.json +++ b/tests/Unit/Entities/_fixtures/notification/entity/transaction.revised.json @@ -290,6 +290,7 @@ "cardholder_name": "Michael McGovern" }, "type": "card", + "south_korea_local_card": null, "underlying_details": null }, "payment_method_id": "paymtd_01hv8x1tpjfnttxddw73xnqx6s", @@ -311,6 +312,7 @@ "cardholder_name": "Michael McGovern" }, "type": "card", + "south_korea_local_card": null, "underlying_details": null }, "payment_method_id": "paymtd_01hv8wx2mka7dfsqjjsxh1ne7z",