def request(self, amount, orderid=None, name=None, email=None, language=None, description=None, **kwargs): reference = self.transaction_id(20, string.digits + string.ascii_letters) # prepend order id in payment reference if orderid: if len(orderid) > 24: raise ValueError('orderid length exceeds 25 characters') reference = orderid + ORDERID_TRANSACTION_SEPARATOR + self.transaction_id( 29 - len(orderid), string.digits + string.ascii_letters) language = language or self.language # convertir en centimes amount = Decimal(amount) * 100 # arrondi comptable francais amount = amount.quantize(Decimal('1.'), rounding=ROUND_HALF_UP) params = { 'AMOUNT': unicode(amount), 'ORDERID': reference, 'PSPID': self.pspid, 'LANGUAGE': language, 'CURRENCY': self.currency, } if self.normal_return_url: params['ACCEPTURL'] = self.normal_return_url params['BACKURL'] = self.normal_return_url params['CANCELURL'] = self.normal_return_url params['DECLINEURL'] = self.normal_return_url params['EXCEPTIONURL'] = self.normal_return_url if name: params['CN'] = name if email: params['EMAIL'] = email if description: params['COM'] = description for key, value in kwargs.iteritems(): params[key.upper()] = value params['SHASIGN'] = self.sha_sign_in(params) # uniformize all values to UTF-8 string for key in params: params[key] = force_text(params[key]) url = self.get_request_url() form = Form(url=url, method='POST', fields=[{ 'type': 'hidden', 'name': key, 'value': params[key] } for key in params]) return reference, FORM, form
def signature(self, fields): self.logger.debug('got fields %s to sign' % fields) ordered_keys = sorted( [key for key in fields.keys() if key.startswith('vads_')]) self.logger.debug('ordered keys %s' % ordered_keys) ordered_fields = [force_byte(fields[key]) for key in ordered_keys] secret = getattr(self, 'secret_%s' % fields['vads_ctx_mode'].lower()) signed_data = '+'.join(ordered_fields) signed_data = '%s+%s' % (signed_data, force_byte(secret)) self.logger.debug( u'generating signature on «%s»' % force_text(signed_data)) sign = hashlib.sha1(force_byte(signed_data)).hexdigest() self.logger.debug(u'signature «%s»' % sign) return sign
def response(self, query_string, **kwargs): params = urlparse.parse_qs(query_string, True) params = dict((key.upper(), params[key][0]) for key in params) if not set(params) >= set(['ORDERID', 'PAYID', 'STATUS', 'NCERROR']): raise ResponseError() # uniformize iso-8859-1 encoded values for key in params: params[key] = force_text(params[key], 'iso-8859-1') reference = params['ORDERID'] transaction_id = params['PAYID'] status = params['STATUS'] error = params['NCERROR'] signed = False if self.sha_in: signature = params.get('SHASIGN') expected_signature = self.sha_sign_out(params) signed = signature == expected_signature print 'signed', signature print 'expected', expected_signature if status == '1': result = CANCELLED elif status == '2': result = DENIED elif status == '5': result = ACCEPTED elif status == '9': result = PAID else: self.logger.error('response STATUS=%s NCERROR=%s NCERRORPLUS=%s', status, error, params.get('NCERRORPLUS', '')) result = ERROR # extract reference from received order id if ORDERID_TRANSACTION_SEPARATOR in reference: reference, transaction_id = reference.split( ORDERID_TRANSACTION_SEPARATOR, 1) return PaymentResponse(result=result, signed=signed, bank_data=params, order_id=reference, transaction_id=transaction_id)
def request(self, amount, **kwargs): '''Request a payment to the payment backend. Arguments: amount -- the amount of money to ask email -- the email of the customer (optional) usually redundant with the hardwired settings in the bank configuration panel. At this url you must use the Payment.response method to analyze the bank returned values. It returns a triple of values, (transaction_id, kind, data): - the first gives a string value to later match the payment with the invoice, - kind gives the type of the third value, payment.URL or payment.HTML or payment.FORM, - the third is the URL or the HTML form to contact the payment server, which must be sent to the customer browser. ''' logger.debug(u'%r' % kwargs) for param in kwargs: # encode all input params to unicode kwargs[param] = force_text(kwargs[param]) return self.backend.request(amount, **kwargs)
def request(self, amount, name=None, first_name=None, last_name=None, address=None, email=None, phone=None, orderid=None, info1=None, info2=None, info3=None, next_url=None, **kwargs): ''' Create the URL string to send a request to SystemPay ''' self.logger.debug( '%s amount %s name %s address %s email %s phone %s ' 'next_url %s info1 %s info2 %s info3 %s kwargs: %s', __name__, amount, name, address, email, phone, info1, info2, info3, next_url, kwargs) # amount unit is cents amount = '%.0f' % (100 * amount) kwargs.update(add_vads({'amount': unicode(amount)})) if amount < 0: raise ValueError('amount must be an integer >= 0') normal_return_url = self.normal_return_url if next_url: warnings.warn( "passing next_url to request() is deprecated, " "set normal_return_url in options", DeprecationWarning) normal_return_url = next_url if normal_return_url: kwargs[VADS_URL_RETURN] = unicode(normal_return_url) if name is not None: kwargs['vads_cust_name'] = unicode(name) if first_name is not None: kwargs[VADS_CUST_FIRST_NAME] = unicode(first_name) if last_name is not None: kwargs[VADS_CUST_LAST_NAME] = unicode(last_name) if address is not None: kwargs['vads_cust_address'] = unicode(address) if email is not None: kwargs['vads_cust_email'] = unicode(email) if phone is not None: kwargs['vads_cust_phone'] = unicode(phone) if info1 is not None: kwargs['vads_order_info'] = unicode(info1) if info2 is not None: kwargs['vads_order_info2'] = unicode(info2) if info3 is not None: kwargs['vads_order_info3'] = unicode(info3) if orderid is not None: # check orderid format first name = 'vads_order_id' orderid = unicode(orderid) ptype = 'an-' p = Parameter(name, ptype, 13, max_length=32) if not p.check_value(orderid): raise ValueError('%s value %s is not of the type %s' % (name, orderid, ptype)) kwargs[name] = orderid transaction_id = self.transaction_id(6, string.digits, 'systempay', self.options[VADS_SITE_ID]) kwargs[VADS_TRANS_ID] = unicode(transaction_id) fields = kwargs for parameter in PARAMETERS: name = parameter.name # import default parameters from configuration if name not in fields \ and name in self.options: fields[name] = unicode(self.options[name]) # import default parameters from module if name not in fields and parameter.default is not None: if callable(parameter.default): fields[name] = parameter.default() else: fields[name] = parameter.default check_vads(fields) fields[SIGNATURE] = unicode(self.signature(fields)) self.logger.debug('%s request contains fields: %s', __name__, fields) transaction_id = '%s_%s' % (fields[VADS_TRANS_DATE], transaction_id) self.logger.debug('%s transaction id: %s', __name__, transaction_id) form = Form(url=self.service_url, method='POST', fields=[{ 'type': u'hidden', 'name': force_text(field_name), 'value': force_text(field_value), } for field_name, field_value in fields.iteritems()]) return transaction_id, FORM, form
def request(self, amount, name=None, address=None, email=None, phone=None, orderid=None, info1=None, info2=None, info3=None, next_url=None, **kwargs): ''' Create the URL string to send a request to SystemPay ''' self.logger.debug('%s amount %s name %s address %s email %s phone %s ' 'next_url %s info1 %s info2 %s info3 %s kwargs: %s', __name__, amount, name, address, email, phone, info1, info2, info3, next_url, kwargs) # amount unit is cents amount = '%.0f' % (100 * amount) kwargs.update(add_vads({'amount': unicode(amount)})) if amount < 0: raise ValueError('amount must be an integer >= 0') normal_return_url = self.normal_return_url if next_url: warnings.warn("passing next_url to request() is deprecated, " "set normal_return_url in options", DeprecationWarning) normal_return_url = next_url if normal_return_url: kwargs[VADS_URL_RETURN] = unicode(normal_return_url) if name is not None: kwargs['vads_cust_name'] = unicode(name) if address is not None: kwargs['vads_cust_address'] = unicode(address) if email is not None: kwargs['vads_cust_email'] = unicode(email) if phone is not None: kwargs['vads_cust_phone'] = unicode(phone) if info1 is not None: kwargs['vads_order_info'] = unicode(info1) if info2 is not None: kwargs['vads_order_info2'] = unicode(info2) if info3 is not None: kwargs['vads_order_info3'] = unicode(info3) if orderid is not None: # check orderid format first name = 'vads_order_id' orderid = unicode(orderid) ptype = 'an-' p = Parameter(name, ptype, 13, max_length=32) if not p.check_value(orderid): raise ValueError('%s value %s is not of the type %s' % (name, orderid, ptype)) kwargs[name] = orderid transaction_id = self.transaction_id(6, string.digits, 'systempay', self.options[VADS_SITE_ID]) kwargs[VADS_TRANS_ID] = unicode(transaction_id) fields = kwargs for parameter in PARAMETERS: name = parameter.name # import default parameters from configuration if name not in fields \ and name in self.options: fields[name] = unicode(self.options[name]) # import default parameters from module if name not in fields and parameter.default is not None: if callable(parameter.default): fields[name] = parameter.default() else: fields[name] = parameter.default check_vads(fields) fields[SIGNATURE] = unicode(self.signature(fields)) self.logger.debug('%s request contains fields: %s', __name__, fields) transaction_id = '%s_%s' % (fields[VADS_TRANS_DATE], transaction_id) self.logger.debug('%s transaction id: %s', __name__, transaction_id) form = Form( url=self.service_url, method='POST', fields=[ { 'type': u'hidden', 'name': force_text(field_name), 'value': force_text(field_value), } for field_name, field_value in fields.iteritems()], submit_value=kwargs.get('submit_value', 'Submit'), submit_css=kwargs.get('submit_css') ) return transaction_id, FORM, form