Skip to content

Commit ed1c05c

Browse files
[PW-3896] Add idempotency key support (#131)
* Add idempotency key to the client * Add optional parameter the idempotency key in service * Fix pycodestyle * Add idempotency support to refund and capture * Add idempotency support to all services
1 parent 7805bf3 commit ed1c05c

File tree

2 files changed

+30
-24
lines changed

2 files changed

+30
-24
lines changed

Adyen/client.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def __str__(self):
4545

4646

4747
class AdyenClient(object):
48+
IDEMPOTENCY_HEADER_NAME = 'Idempotency-Key'
4849
"""A requesting client that interacts with Adyen. This class holds the
4950
adyen logic of Adyen HTTP API communication. This is the object that can
5051
maintain its own username, password, merchant_account, hmac and skin_code.
@@ -220,7 +221,7 @@ def call_api(
220221
request_data,
221222
service,
222223
action,
223-
idempotency=False,
224+
idempotency_key=None,
224225
**kwargs
225226
):
226227
"""This will call the adyen api. username, password, merchant_account,
@@ -229,6 +230,8 @@ def call_api(
229230
is raised.
230231
231232
Args:
233+
idempotency_key: https://docs.adyen.com/development-resources
234+
/api-idempotency
232235
request_data (dict): The dictionary of the request to place. This
233236
should be in the structure of the Adyen API.
234237
https://docs.adyen.com/manuals/api-manual
@@ -338,8 +341,8 @@ def call_api(
338341
# Adyen requires this header to be set and uses the combination of
339342
# merchant account and merchant reference to determine uniqueness.
340343
headers = {}
341-
if idempotency:
342-
headers['Pragma'] = 'process-retry'
344+
if idempotency_key:
345+
headers[self.IDEMPOTENCY_HEADER_NAME] = idempotency_key
343346

344347
url = self._determine_api_url(platform, service, action)
345348

@@ -373,9 +376,6 @@ def call_hpp(self, message, action, hmac_key="", **kwargs):
373376
https://docs.adyen.com/manuals/api-manual
374377
service (str): This is the API service to be called.
375378
action (str): The specific action of the API service to be called
376-
idempotency (bool, optional): Whether the transaction should be
377-
processed idempotently.
378-
https://docs.adyen.com/manuals/api-manual#apiidempotency
379379
Returns:
380380
AdyenResult: The AdyenResult is returned when a request was
381381
succesful.
@@ -433,13 +433,16 @@ class instance.
433433
status_code, headers, message)
434434
return adyen_result
435435

436-
def call_checkout_api(self, request_data, action, **kwargs):
436+
def call_checkout_api(self, request_data, action, idempotency_key=None,
437+
**kwargs):
437438
"""This will call the checkout adyen api. xapi key merchant_account,
438439
and platform are pulled from root module level and or self object.
439440
AdyenResult will be returned on 200 response. Otherwise, an exception
440441
is raised.
441442
442443
Args:
444+
idempotency_key: https://docs.adyen.com/development-resources
445+
/api-idempotency
443446
request_data (dict): The dictionary of the request to place. This
444447
should be in the structure of the Adyen API.
445448
https://docs.adyen.com/developers/checkout/api-integration
@@ -510,7 +513,8 @@ def call_checkout_api(self, request_data, action, **kwargs):
510513
# Adyen requires this header to be set and uses the combination of
511514
# merchant account and merchant reference to determine uniqueness.
512515
headers = {}
513-
516+
if idempotency_key:
517+
headers[self.IDEMPOTENCY_HEADER_NAME] = idempotency_key
514518
url = self._determine_checkout_url(platform, action)
515519

516520
raw_response, raw_request, status_code, headers = \

Adyen/services.py

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def __init__(self, client=None):
146146
super(AdyenPayment, self).__init__(client=client)
147147
self.service = "Payment"
148148

149-
def authorise(self, request, **kwargs):
149+
def authorise(self, request, idempotency_key=None, **kwargs):
150150

151151
action = "authorise"
152152

@@ -162,21 +162,21 @@ def authorise(self, request, **kwargs):
162162
' name when authorising recurring contracts.')
163163

164164
return self.client.call_api(request, self.service,
165-
action, **kwargs)
165+
action, idempotency_key, **kwargs)
166166

167-
def authorise3d(self, request, **kwargs):
167+
def authorise3d(self, request, idempotency_key=None, **kwargs):
168168
action = "authorise3d"
169169

170170
return self.client.call_api(request, self.service,
171-
action, **kwargs)
171+
action, idempotency_key, **kwargs)
172172

173-
def cancel(self, request, **kwargs):
173+
def cancel(self, request, idempotency_key=None, **kwargs):
174174
action = "cancel"
175175

176176
return self.client.call_api(request, self.service,
177-
action, **kwargs)
177+
action, idempotency_key, **kwargs)
178178

179-
def capture(self, request, **kwargs):
179+
def capture(self, request, idempotency_key=None, **kwargs):
180180

181181
action = "capture"
182182

@@ -192,10 +192,10 @@ def capture(self, request, **kwargs):
192192
"reference of the transaction to be modified")
193193

194194
response = self.client.call_api(request, self.service,
195-
action, **kwargs)
195+
action, idempotency_key, **kwargs)
196196
return response
197197

198-
def refund(self, request, **kwargs):
198+
def refund(self, request, idempotency_key=None, **kwargs):
199199

200200
action = "refund"
201201

@@ -207,13 +207,13 @@ def refund(self, request, **kwargs):
207207
"to partially refund this payment.")
208208
else:
209209
return self.client.call_api(request, self.service,
210-
action, **kwargs)
210+
action, idempotency_key, **kwargs)
211211

212-
def cancel_or_refund(self, request, **kwargs):
212+
def cancel_or_refund(self, request, idempotency_key=None, **kwargs):
213213
action = "cancelOrRefund"
214214

215215
return self.client.call_api(
216-
request, self.service, action, **kwargs
216+
request, self.service, action, idempotency_key, **kwargs
217217
)
218218

219219

@@ -296,13 +296,15 @@ def payment_methods(self, request, **kwargs):
296296

297297
return self.client.call_checkout_api(request, action, **kwargs)
298298

299-
def payments(self, request, **kwargs):
299+
def payments(self, request, idempotency_key=None, **kwargs):
300300
action = "payments"
301-
return self.client.call_checkout_api(request, action, **kwargs)
301+
return self.client.call_checkout_api(request, action, idempotency_key,
302+
**kwargs)
302303

303-
def payments_details(self, request=None, **kwargs):
304+
def payments_details(self, request=None, idempotency_key=None, **kwargs):
304305
action = "paymentsDetails"
305-
return self.client.call_checkout_api(request, action, **kwargs)
306+
return self.client.call_checkout_api(request, action, idempotency_key,
307+
**kwargs)
306308

307309
def payment_session(self, request=None, **kwargs):
308310
action = "paymentSession"

0 commit comments

Comments
 (0)