@@ -180,6 +180,16 @@ def _process_response(self, adyen_response, params):
180180
181181
182182class BaseInteraction :
183+ REQUIRED_FIELDS = ()
184+ OPTIONAL_FIELDS = ()
185+ HASH_KEYS = ()
186+ HASH_FIELD = None
187+
188+ def hash (self ):
189+ return self .client ._compute_hash (self .HASH_KEYS , self .params )
190+
191+ def validate (self ):
192+ self .check_fields ()
183193
184194 def check_fields (self ):
185195 """
@@ -204,42 +214,9 @@ def check_fields(self):
204214 )
205215
206216
207- # ---[ REQUESTS ]---
208-
209- class BaseRequest (BaseInteraction ):
210- REQUIRED_FIELDS = ()
211- OPTIONAL_FIELDS = ()
212- HASH_KEYS = ()
213-
214- def __init__ (self , client , params = None ):
215-
216- if params is None :
217- params = {}
218-
219- self .client = client
220- self .params = params
221- self .validate ()
222-
223- # Compute request hash.
224- self .params .update ({self .HASH_FIELD : self .hash ()})
225-
226- def validate (self ):
227- self .check_fields ()
228-
229- def hash (self ):
230- return self .client ._compute_hash (self .HASH_KEYS , self .params )
231-
232-
233217# ---[ FORM-BASED REQUESTS ]---
234218
235- class FormRequest (BaseRequest ):
236-
237- def build_form_fields (self ):
238- return [{'type' : 'hidden' , 'name' : name , 'value' : value }
239- for name , value in self .params .items ()]
240-
241-
242- class PaymentFormRequest (FormRequest ):
219+ class PaymentFormRequest (BaseInteraction ):
243220 REQUIRED_FIELDS = (
244221 Constants .MERCHANT_ACCOUNT ,
245222 Constants .MERCHANT_REFERENCE ,
@@ -290,26 +267,28 @@ class PaymentFormRequest(FormRequest):
290267 Constants .OFFSET ,
291268 )
292269
270+ def __init__ (self , client , params = None ):
271+ self .client = client
272+ self .params = params or {}
273+ self .validate ()
274+
275+ # Compute request hash.
276+ self .params .update ({self .HASH_FIELD : self .hash ()})
277+
278+ def build_form_fields (self ):
279+ return [{'type' : 'hidden' , 'name' : name , 'value' : value }
280+ for name , value in self .params .items ()]
281+
293282
294283# ---[ RESPONSES ]---
295284
296285class BaseResponse (BaseInteraction ):
297- REQUIRED_FIELDS = ()
298- OPTIONAL_FIELDS = ()
299- HASH_FIELD = None
300- HASH_KEYS = ()
301286
302287 def __init__ (self , client , params ):
303288 self .client = client
304289 self .secret_key = client .secret_key
305290 self .params = params
306291
307- def validate (self ):
308- self .check_fields ()
309-
310- def hash (self ):
311- return self .client ._compute_hash (self .HASH_KEYS , self .params )
312-
313292 def process (self ):
314293 return NotImplemented
315294
@@ -353,7 +332,7 @@ def check_fields(self):
353332 "System communication" setup (instead of the old "notifications" tab
354333 in the settings).
355334 We currently don't need any of that data, so we just drop it
356- before validating the response .
335+ before validating the notification .
357336 :return:
358337 """
359338 self .params = {
@@ -404,13 +383,11 @@ def validate(self):
404383 # Check that the transaction has not been tampered with.
405384 received_hash = self .params .get (self .HASH_FIELD )
406385 expected_hash = self .hash ()
407- if expected_hash != received_hash :
386+ if not received_hash or expected_hash != received_hash :
408387 raise InvalidTransactionException (
409- "The transaction is invalid. "
410- "This may indicate a fraud attempt."
411- )
388+ "The transaction is invalid. This may indicate a fraud attempt." )
412389
413390 def process (self ):
414- payment_result = self .params . get ( Constants .AUTH_RESULT , None )
391+ payment_result = self .params [ Constants .AUTH_RESULT ]
415392 accepted = payment_result == Constants .PAYMENT_RESULT_AUTHORISED
416393 return accepted , payment_result , self .params
0 commit comments