better return transaction state

This commit is contained in:
Benjamin Dauvergne 2012-02-20 19:07:55 +01:00
parent 6e649aeb52
commit 9290931626
3 changed files with 48 additions and 16 deletions

View File

@ -4,7 +4,8 @@ import random
import logging
from datetime import date
__all__ = [ 'PaymentCommon', 'URL', 'HTML', 'RANDOM' ]
__all__ = [ 'PaymentCommon', 'URL', 'HTML', 'RANDOM', 'RECEIVED', 'ACCEPTED',
'PAID', 'ERROR' ]
LOGGER = logging.getLogger(__name__)
@ -13,6 +14,11 @@ RANDOM = random.SystemRandom()
URL = 1
HTML = 2
RECEIVED = 1
ACCEPTED = 2
PAID = 3
ERROR = 99
class PaymentResponse(object):
'''Holds a generic view on the result of payment transaction response.
@ -35,11 +41,11 @@ class PaymentResponse(object):
an identifier internal to the bank.
'''
def __init__(self, result=None, signed_result=None, bank_data=dict(),
def __init__(self, result=None, signed=None, bank_data=dict(),
return_content=None, bank_status='', transaction_id='',
order_id=''):
self.result = result
self.signed_result = signed_result
self.signed = signed
self.bank_data = bank_data
self.return_content = return_content
self.bank_status = bank_status
@ -49,6 +55,19 @@ class PaymentResponse(object):
def __repr__(self):
return '<%s %s>' % (self.__class__.__name__, self.__dict__)
def is_received(self):
return self.result == RECEIVED
def is_accepted(self):
return self.result == ACCEPTED
def is_paid(self):
return self.result == PAID
def is_error(self):
return self.result == ERROR
class PaymentCommon(object):
PATH = '/tmp'
BANK_ID = '__bank_id'

View File

@ -7,7 +7,7 @@ try:
except:
from urlparse import parse_qs
from common import PaymentCommon, URL, PaymentResponse
from common import PaymentCommon, URL, PaymentResponse, PAID, ERROR
__all__ = [ 'Payment' ]
@ -98,11 +98,10 @@ class Payment(PaymentCommon):
else:
content = None
signed = signed or self.consider_all_response_signed
result = 'ok' in form
signed_result = result if signed else None
result = PAID if 'ok' in form else ERROR
response = PaymentResponse(result=result,
signed_result=signed_result,
signed=signed,
bank_data=form,
return_content=content,
order_id=transaction_id,

View File

@ -11,7 +11,8 @@ import logging
import re
import Crypto.Cipher.DES
from common import PaymentCommon, URL, PaymentResponse
from common import (PaymentCommon, URL, PaymentResponse, RECEIVED, ACCEPTED,
PAID, ERROR)
__all__ = ['Payment']
@ -19,11 +20,12 @@ KEY_DES_KEY = '\x45\x1f\xba\x4f\x4c\x3f\xd4\x97'
IV = '\x30\x78\x30\x62\x2c\x30\x78\x30'
REFERENCE = 'reference'
ETAT = 'etat'
ETAT_PAIEMENT_ACCEPTE = '1'
SPCHECKOK = 'spcheckok'
LOGGER = logging.getLogger(__name__)
REFSFP = 'refsfp'
# Pour un paiement comptant la chaine des états est: 1 -> 4 -> 10, seul l'état
# 10 garanti le paiement
SPPLUS_RESPONSE_CODES = {
'1': 'Autorisation de paiement acceptée',
'2': 'Autorisation de paiement refusée',
@ -43,6 +45,11 @@ SPPLUS_RESPONSE_CODES = {
'99': 'Paiement de test en production',
}
VALID_STATE = ('1', '4', '10')
ACCEPTED_STATE = ('1', '4')
PAID_STATE = ('10',)
def decrypt_ntkey(ntkey):
key = binascii.unhexlify(ntkey.replace(' ',''))
return decrypt_key(key)
@ -144,11 +151,11 @@ next_url=%s' % (montant, email, next_url))
logger.debug('parsed as %s' % form)
reference = form.get(REFERENCE)
bank_status = []
signed_result = None
result = form.get('etat') == '1'
signed = False
form[self.BANK_ID] = form.get(REFSFP)
etat = form.get('etat')
status = '%s: %s' % (etat, SPPLUS_RESPONSE_CODES.get(etat, 'Unknown code'))
logger.debug('status is %s', status)
bank_status.append(status)
if 'hmac' in form:
try:
@ -157,21 +164,28 @@ next_url=%s' % (montant, email, next_url))
logger.debug('got signature %s' % hmac)
computed_hmac = sign_ntkey_query(self.cle, signed_data)
logger.debug('computed signature %s' % hmac)
if hmac == computed_hmac:
signed_result = result
else:
signed = hmac == computed_hmac
if not signed:
bank_status.append('invalid signature')
except ValueError:
bank_status.append('invalid signature')
if etat in PAID_STATE:
result = PAID
if etat in ACCEPTED_STATE:
result = ACCEPTED
elif etat in VALID_STATE:
result = RECEIVED
else:
result = ERROR
response = PaymentResponse(
result=result,
signed_result=signed_result,
signed=signed,
bank_data=form,
order_id=reference,
transaction_id=form[self.BANK_ID],
bank_status=' - '.join(bank_status),
return_content=SPCHECKOK if 'hmac' in form else None)
return_content=SPCHECKOK)
return response