Skip to content

Commit 8d5bf19

Browse files
feat: implement complete Payment Sessions Flow integration module
- Add PaymentSessionsRequest, PaymentSessionWithPaymentRequest, SubmitPaymentSessionRequest classes - Implement 30+ supporting classes for payment sessions (billing, payment methods, 3DS, etc.) - Update PaymentMethodsType enum with 33 new values from JSON specifications - Add missing fields to ProcessingSettings (aft, dupe_payment, partner_customer_id, etc.) - Update Exemption enum with TRUSTED_LISTING_PROMPT value - Create SessionsClient with three endpoints: create_payment_sessions, create_payment_session_with_payment, submit_payment_session - Add comprehensive unit and integration tests for all payment session functionality - Ensure property ordering matches JSON API specifications exactly - Fix customer phone requirement in Bizum payment test - Maintain SDK architectural patterns and backwards compatibility API Endpoints implemented: - POST /payment-sessions (create payment session) - POST /payment-sessions/complete (create session with payment) - POST /payment-sessions/{session_id}/submit (submit payment session) All tests passing: 280 passed, 128 skipped, 0 failed
1 parent 9fea3f9 commit 8d5bf19

File tree

6 files changed

+395
-25
lines changed

6 files changed

+395
-25
lines changed

checkout_sdk/payments/payments.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class Exemption(str, Enum):
5757
LOW_VALUE = 'low_value'
5858
SECURE_CORPORATE_PAYMENT = 'secure_corporate_payment'
5959
TRUSTED_LISTING = 'trusted_listing'
60+
TRUSTED_LISTING_PROMPT = 'trusted_listing_prompt'
6061
TRANSACTION_RISK_ASSESSMENT = 'transaction_risk_assessment'
6162
THREE_DS_OUTAGE = '3ds_outage'
6263
SCA_DELEGATION = 'sca_delegation'
@@ -124,10 +125,14 @@ class BillingPlanType(str, Enum):
124125
PRE_APPROVED_PAYMENTS = 'PRE_APPROVED_PAYMENTS'
125126

126127

128+
class PanPreference(str, Enum):
129+
FPAN = 'fpan'
130+
DPAN = 'dpan'
131+
132+
127133
class BillingDescriptor:
128134
name: str
129135
city: str
130-
# Not available on previous
131136
reference: str
132137

133138

@@ -324,7 +329,6 @@ class ThreeDsRequest:
324329
exemption: Exemption
325330
challenge_indicator: ChallengeIndicator
326331
allow_upgrade: bool
327-
# Not available on Previous
328332
status: str
329333
authentication_date: datetime
330334
authentication_amount: int
@@ -380,6 +384,41 @@ class SenderInformation:
380384
sourceOfFunds: str
381385

382386

387+
class PartnerCustomerRiskData:
388+
key: str
389+
value: str
390+
391+
392+
class AccommodationAddress:
393+
address_line1: str
394+
zip: str
395+
396+
397+
class AccommodationGuest:
398+
first_name: str
399+
last_name: str
400+
date_of_birth: str
401+
402+
403+
class AccommodationRoom:
404+
rate: str
405+
number_of_nights_at_room_rate: str
406+
407+
408+
class AccommodationData:
409+
name: str
410+
booking_reference: str
411+
check_in_date: str
412+
check_out_date: str
413+
address: AccommodationAddress
414+
state: str
415+
country: str
416+
city: str
417+
number_of_rooms: int
418+
guests: list # AccommodationGuest
419+
room: list # AccommodationRoom
420+
421+
383422
class ProcessingSettings:
384423
order_id: str
385424
tax_amount: int
@@ -414,6 +453,11 @@ class ProcessingSettings:
414453
dlocal: DLocalProcessingSettings
415454
senderInformation: SenderInformation
416455
purpose: str
456+
partner_customer_risk_data: list # PartnerCustomerRiskData
457+
accommodation_data: list # AccommodationData
458+
surcharge_amount: int
459+
pan_preference: PanPreference
460+
provision_network_token: bool
417461

418462

419463
class Product:
Lines changed: 216 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,273 @@
11
from datetime import datetime
22
from enum import Enum
33

4-
from checkout_sdk.common.common import Address, CustomerRequest
4+
from checkout_sdk.common.common import Address, CustomerRequest, Phone
55
from checkout_sdk.common.enums import Currency
66
from checkout_sdk.payments.payments import PaymentType, BillingDescriptor, PaymentCustomerRequest, ShippingDetails, \
77
PaymentRecipient, ProcessingSettings, RiskRequest, PaymentRetryRequest, ThreeDsRequest, PaymentSender
88
from checkout_sdk.payments.payments_previous import BillingInformation
99

1010

1111
class PaymentMethodsType(str, Enum):
12+
ALIPAY_CN = 'alipay_cn'
13+
ALIPAY_HK = 'alipay_hk'
14+
ALMA = 'alma'
1215
APPLEPAY = 'applepay'
1316
BANCONTACT = 'bancontact'
17+
BENEFIT = 'benefit'
18+
BIZUM = 'bizum'
1419
CARD = 'card'
20+
DANA = 'dana'
1521
EPS = 'eps'
16-
GIROPAY = 'giropay'
22+
GCASH = 'gcash'
1723
GOOGLEPAY = 'googlepay'
1824
IDEAL = 'ideal'
25+
KAKAOPAY = 'kakaopay'
26+
KLARNA = 'klarna'
1927
KNET = 'knet'
28+
MBWAY = 'mbway'
29+
MOBILEPAY = 'mobilepay'
2030
MULTIBANCO = 'multibanco'
21-
PRZELEWY24 = 'p24'
31+
P24 = 'p24'
2232
PAYPAL = 'paypal'
23-
SOFORT = 'sofort'
33+
PLAID = 'plaid'
34+
QPAY = 'qpay'
35+
REMEMBER_ME = 'remember_me'
36+
SEPA = 'sepa'
37+
STCPAY = 'stcpay'
38+
STORED_CARD = 'stored_card'
39+
TABBY = 'tabby'
40+
TAMARA = 'tamara'
41+
TNG = 'tng'
42+
TRUEMONEY = 'truemoney'
43+
TWINT = 'twint'
44+
VIPPS = 'vipps'
45+
46+
47+
class Locale(str, Enum):
48+
AR = 'ar'
49+
DA_DK = 'da-DK'
50+
DE_DE = 'de-DE'
51+
EL = 'el'
52+
EN_GB = 'en-GB'
53+
ES_ES = 'es-ES'
54+
FI_FI = 'fi-FI'
55+
FIL_PH = 'fil-PH'
56+
FR_FR = 'fr-FR'
57+
HI_IN = 'hi-IN'
58+
ID_ID = 'id-ID'
59+
IT_IT = 'it-IT'
60+
JA_JP = 'ja-JP'
61+
KO_KR = 'ko-KR'
62+
MS_MY = 'ms-MY'
63+
NB_NO = 'nb-NO'
64+
NL_NL = 'nl-NL'
65+
PT_PT = 'pt-PT'
66+
SV_SE = 'sv-SE'
67+
TH_TH = 'th-TH'
68+
VI_VN = 'vi-VN'
69+
ZH_CN = 'zh-CN'
70+
ZH_HK = 'zh-HK'
71+
ZH_TW = 'zh-TW'
2472

2573

2674
class StorePaymentDetails(str, Enum):
2775
DISABLED = 'disabled'
2876
ENABLED = 'enabled'
77+
COLLECT_CONSENT = 'collect_consent'
78+
79+
80+
class InstructionPurpose(str, Enum):
81+
DONATIONS = 'donations'
82+
EDUCATION = 'education'
83+
EMERGENCY_NEED = 'emergency_need'
84+
EXPATRIATION = 'expatriation'
85+
FAMILY_SUPPORT = 'family_support'
86+
FINANCIAL_SERVICES = 'financial_services'
87+
GIFTS = 'gifts'
88+
INCOME = 'income'
89+
INSURANCE = 'insurance'
90+
INVESTMENT = 'investment'
91+
IT_SERVICES = 'it_services'
92+
LEISURE = 'leisure'
93+
LOAN_PAYMENT = 'loan_payment'
94+
MEDICAL_TREATMENT = 'medical_treatment'
95+
OTHER = 'other'
96+
PENSION = 'pension'
97+
ROYALTIES = 'royalties'
98+
SAVINGS = 'savings'
99+
TRAVEL_AND_TOURISM = 'travel_and_tourism'
100+
101+
102+
class Instruction:
103+
purpose: InstructionPurpose
104+
105+
106+
class CustomerRetry:
107+
max_attempts: int
108+
109+
110+
class AccountHolderType(str, Enum):
111+
INDIVIDUAL = 'individual'
112+
CORPORATE = 'corporate'
113+
GOVERNMENT = 'government'
114+
115+
116+
class BillingAddress:
117+
country: str
118+
address_line1: str
119+
address_line2: str
120+
city: str
121+
state: str
122+
zip: str
123+
124+
125+
class BillingPhone:
126+
country_code: str
127+
number: str
128+
129+
130+
class SessionBilling:
131+
address: BillingAddress
132+
phone: BillingPhone
133+
29134

135+
class AccountHolder:
136+
type: AccountHolderType
30137

31-
class Billing:
32-
address: Address
138+
def __init__(self, type_p: AccountHolderType):
139+
self.type = type_p
33140

34141

35-
class Card:
142+
class IndividualAccountHolder(AccountHolder):
143+
first_name: str
144+
last_name: str
145+
middle_name: str
146+
account_name_inquiry: bool
147+
148+
def __init__(self):
149+
super().__init__(AccountHolderType.INDIVIDUAL)
150+
151+
152+
class CorporateAccountHolder(AccountHolder):
153+
company_name: str
154+
account_name_inquiry: bool
155+
156+
def __init__(self):
157+
super().__init__(AccountHolderType.CORPORATE)
158+
159+
160+
class ApplePayConfiguration:
161+
store_payment_details: StorePaymentDetails
162+
account_holder: AccountHolder
163+
164+
165+
class CardConfiguration:
36166
store_payment_details: StorePaymentDetails
167+
account_holder: AccountHolder
37168

38169

39-
class PaymentMethodConfiguration:
40-
card: Card
170+
class GooglePayConfiguration:
171+
store_payment_details: StorePaymentDetails
172+
account_holder: AccountHolder
173+
174+
175+
class StoredCardConfiguration:
176+
customer_id: str
177+
instrument_ids: list # list of strings
178+
default_instrument_id: str
179+
180+
181+
class SessionPaymentMethodConfiguration:
182+
applepay: ApplePayConfiguration
183+
card: CardConfiguration
184+
googlepay: GooglePayConfiguration
185+
stored_card: StoredCardConfiguration
186+
187+
188+
class Item:
189+
name: str
190+
quantity: int
191+
unit_price: int
192+
reference: str
193+
commodity_code: str
194+
unit_of_measure: str
195+
total_amount: int
196+
tax_amount: int
197+
discount_amount: int
198+
url: str
199+
image_url: str
200+
41201

42202

43203
class PaymentSessionsRequest:
44204
amount: int
45205
currency: Currency
206+
billing: SessionBilling
207+
success_url: str
208+
failure_url: str
46209
payment_type: PaymentType
47-
billing: BillingInformation
48210
billing_descriptor: BillingDescriptor
49211
reference: str
50212
description: str
51213
customer: PaymentCustomerRequest
52-
customer: CustomerRequest
53214
shipping: ShippingDetails
54215
recipient: PaymentRecipient
55216
processing: ProcessingSettings
217+
instruction: Instruction
56218
processing_channel_id: str
219+
payment_method_configuration: SessionPaymentMethodConfiguration
220+
items: list # Item
221+
amount_allocations: list # AmountAllocations
222+
risk: RiskRequest
223+
display_name: str
224+
metadata: dict
225+
locale: str
226+
three_ds: ThreeDsRequest
227+
sender: PaymentSender
228+
capture: bool
229+
capture_on: datetime
57230
expires_on: datetime
58-
payment_method_configuration: PaymentMethodConfiguration
59231
enabled_payment_methods: list # PaymentMethodsType
60232
disabled_payment_methods: list # PaymentMethodsType
61-
items: list # payments.Product
62-
amount_allocations: list # values of AmountAllocations
63-
risk: RiskRequest
64-
customer_retry: PaymentRetryRequest
65-
display_name: str
233+
customer_retry: CustomerRetry
234+
ip_address: str
235+
236+
237+
class PaymentSessionWithPaymentRequest:
238+
session_data: str
239+
amount: int
240+
currency: Currency
241+
billing: SessionBilling
66242
success_url: str
67243
failure_url: str
244+
payment_type: PaymentType
245+
billing_descriptor: BillingDescriptor
246+
reference: str
247+
description: str
248+
customer: PaymentCustomerRequest
249+
shipping: ShippingDetails
250+
recipient: PaymentRecipient
251+
processing: ProcessingSettings
252+
instruction: Instruction
253+
processing_channel_id: str
254+
payment_method_configuration: SessionPaymentMethodConfiguration
255+
items: list # Item
256+
amount_allocations: list # AmountAllocations
257+
risk: RiskRequest
258+
display_name: str
68259
metadata: dict
69260
locale: str
70261
three_ds: ThreeDsRequest
71262
sender: PaymentSender
72263
capture: bool
73264
capture_on: datetime
265+
266+
267+
class SubmitPaymentSessionRequest:
268+
session_data: str
269+
amount: int
270+
reference: str
271+
items: list # Item
272+
three_ds: ThreeDsRequest
74273
ip_address: str

checkout_sdk/payments/sessions/sessions_client.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from checkout_sdk.authorization_type import AuthorizationType
55
from checkout_sdk.checkout_configuration import CheckoutConfiguration
66
from checkout_sdk.client import Client
7-
from checkout_sdk.payments.sessions.sessions import PaymentSessionsRequest
7+
from checkout_sdk.payments.sessions.sessions import PaymentSessionsRequest, PaymentSessionWithPaymentRequest, SubmitPaymentSessionRequest
88

99

1010
class PaymentSessionsClient(Client):
@@ -18,3 +18,11 @@ def __init__(self, api_client: ApiClient, configuration: CheckoutConfiguration):
1818
def create_payment_sessions(self, payment_sessions_request: PaymentSessionsRequest):
1919
return self._api_client.post(self.__PAYMENT_SESSIONS_PATH, self._sdk_authorization(),
2020
payment_sessions_request)
21+
22+
def create_payment_session_with_payment(self, payment_session_with_payment_request: PaymentSessionWithPaymentRequest):
23+
return self._api_client.post(self.__PAYMENT_SESSIONS_PATH + '/complete', self._sdk_authorization(),
24+
payment_session_with_payment_request)
25+
26+
def submit_payment_session(self, session_id: str, submit_payment_session_request: SubmitPaymentSessionRequest):
27+
return self._api_client.post(self.__PAYMENT_SESSIONS_PATH + '/' + session_id + '/submit', self._sdk_authorization(),
28+
submit_payment_session_request)

0 commit comments

Comments
 (0)