def _vcsweb_form_get_tx_from_data(self, data): #if controller is called directly. reference = data.get('p2') if not reference: error_msg = _('VCSWeb: no transactional reference received') raise ValidationError(error_msg) tx = self.search([("reference", "=", reference)]) #did we find the transaction? if not tx: error_msg = _( 'VCSWeb: received data for reference %s; no order found') % ( reference) raise ValidationError(error_msg) elif len(tx) > 1: error_msg = _( 'VCSWeb: received data for reference %s; multiple orders found' ) % (reference) raise ValidationError(error_msg) #check hash - just redisplay transaction if data.get("p3", "") == '~MD5 Hash mismatch': _logger.info("acquirer found hash mismatch on input data") return tx hash = data.get("Hash", None) if hash: calculated_hash = tx.acquirer_id._calculate_vcsweb_hash('in', data) if hash.upper() != calculated_hash.upper(): error_msg = _( 'VCSWeb: invalid hash, received %s, computed %s, for data %s' ) % (hash, calculated_hash, data) _logger.info(error_msg) raise ValidationError(error_msg) return tx
def _payulatam_form_get_tx_from_data(self, data): """ Given a data dict coming from payulatam, verify it and find the related transaction record. """ reference, txnid, sign = data.get('referenceCode'), data.get( 'transactionId'), data.get('signature') if not reference or not txnid or not sign: raise ValidationError( _('PayU Latam: received data with missing reference (%s) or transaction id (%s) or sign (%s)' ) % (reference, txnid, sign)) transaction = self.search([('reference', '=', reference)]) if not transaction: error_msg = ( _('PayU Latam: received data for reference %s; no order found') % (reference)) raise ValidationError(error_msg) elif len(transaction) > 1: error_msg = (_( 'PayU Latam: received data for reference %s; multiple orders found' ) % (reference)) raise ValidationError(error_msg) # verify shasign sign_check = transaction.acquirer_id._payulatam_generate_sign( 'out', data) if sign_check.upper() != sign.upper(): raise ValidationError(( 'PayU Latam: invalid sign, received %s, computed %s, for data %s' ) % (sign, sign_check, data)) return transaction
def _alipay_form_get_tx_from_data(self, data): reference, txn_id, sign = data.get('reference'), data.get('trade_no'), data.get('sign') if not reference or not txn_id: _logger.info('Alipay: received data with missing reference (%s) or txn_id (%s)' % (reference, txn_id)) raise ValidationError(_('Alipay: received data with missing reference (%s) or txn_id (%s)') % (reference, txn_id)) txs = self.env['payment.transaction'].search([('reference', '=', reference)]) if not txs or len(txs) > 1: error_msg = _('Alipay: received data for reference %s') % (reference) logger_msg = 'Alipay: received data for reference %s' % (reference) if not txs: error_msg += _('; no order found') logger_msg += '; no order found' else: error_msg += _('; multiple order found') logger_msg += '; multiple order found' _logger.info(logger_msg) raise ValidationError(error_msg) # verify sign sign_check = txs.acquirer_id._build_sign(data) if sign != sign_check: _logger.info('Alipay: invalid sign, received %s, computed %s, for data %s' % (sign, sign_check, data)) raise ValidationError(_('Alipay: invalid sign, received %s, computed %s, for data %s') % (sign, sign_check, data)) return txs
def _authorize_form_get_tx_from_data(self, data): """ Given a data dict coming from authorize, verify it and find the related transaction record. """ reference, description, trans_id, fingerprint = data.get( 'x_invoice_num'), data.get('x_description'), data.get( 'x_trans_id' ), data.get('x_SHA2_Hash') or data.get('x_MD5_Hash') if not reference or not trans_id or not fingerprint: error_msg = _( 'Authorize: received data with missing reference (%s) or trans_id (%s) or fingerprint (%s)' ) % (reference, trans_id, fingerprint) _logger.info(error_msg) raise ValidationError(error_msg) tx = self.search([ '|', ('reference', '=', reference), ('reference', '=', description) ]) if not tx or len(tx) > 1: error_msg = 'Authorize: received data for x_invoice_num %s and x_description %s' % ( reference, description) if not tx: error_msg += '; no order found' else: error_msg += '; multiple order found' _logger.info(error_msg) raise ValidationError(error_msg) return tx[0]
def _adyen_form_get_tx_from_data(self, data): reference, pspReference = data.get('merchantReference'), data.get('pspReference') if not reference or not pspReference: error_msg = _('Adyen: received data with missing reference (%s) or missing pspReference (%s)') % (reference, pspReference) _logger.info(error_msg) raise ValidationError(error_msg) # find tx -> @TDENOTE use pspReference ? tx = self.env['payment.transaction'].search([('reference', '=', reference)]) if not tx or len(tx) > 1: error_msg = _('Adyen: received data for reference %s') % (reference) if not tx: error_msg += _('; no order found') else: error_msg += _('; multiple order found') _logger.info(error_msg) raise ValidationError(error_msg) # verify shasign if len(tx.acquirer_id.adyen_skin_hmac_key) == 64: shasign_check = tx.acquirer_id._adyen_generate_merchant_sig_sha256('out', data) else: shasign_check = tx.acquirer_id._adyen_generate_merchant_sig('out', data) if shasign_check != data.get('merchantSig'): error_msg = _('Adyen: invalid merchantSig, received %s, computed %s') % (data.get('merchantSig'), shasign_check) _logger.warning(error_msg) raise ValidationError(error_msg) return tx
def _buckaroo_form_get_tx_from_data(self, data): """ Given a data dict coming from buckaroo, verify it and find the related transaction record. """ origin_data = dict(data) data = normalize_keys_upper(data) reference, pay_id, shasign = data.get('BRQ_INVOICENUMBER'), data.get('BRQ_PAYMENT'), data.get('BRQ_SIGNATURE') if not reference or not pay_id or not shasign: error_msg = _('Buckaroo: received data with missing reference (%s) or pay_id (%s) or shasign (%s)') % (reference, pay_id, shasign) _logger.info(error_msg) raise ValidationError(error_msg) tx = self.search([('reference', '=', reference)]) if not tx or len(tx) > 1: error_msg = _('Buckaroo: received data for reference %s') % (reference) if not tx: error_msg += _('; no order found') else: error_msg += _('; multiple order found') _logger.info(error_msg) raise ValidationError(error_msg) # verify shasign shasign_check = tx.acquirer_id._buckaroo_generate_digital_sign('out', origin_data) if shasign_check.upper() != shasign.upper(): error_msg = _('Buckaroo: invalid shasign, received %s, computed %s, for data %s') % (shasign, shasign_check, data) _logger.info(error_msg) raise ValidationError(error_msg) return tx
def _payumoney_form_get_tx_from_data(self, data): """ Given a data dict coming from payumoney, verify it and find the related transaction record. """ reference = data.get('txnid') pay_id = data.get('mihpayid') shasign = data.get('hash') if not reference or not pay_id or not shasign: raise ValidationError( _('PayUmoney: received data with missing reference (%s) or pay_id (%s) or shashign (%s)' ) % (reference, pay_id, shasign)) transaction = self.search([('reference', '=', reference)]) if not transaction: error_msg = ( _('PayUmoney: received data for reference %s; no order found') % (reference)) raise ValidationError(error_msg) elif len(transaction) > 1: error_msg = (_( 'PayUmoney: received data for reference %s; multiple orders found' ) % (reference)) raise ValidationError(error_msg) #verify shasign shasign_check = transaction.acquirer_id._payumoney_generate_sign( 'out', data) if shasign_check.upper() != shasign.upper(): raise ValidationError( _('PayUmoney: invalid shasign, received %s, computed %s, for data %s' ) % (shasign, shasign_check, data)) return transaction
def _stripe_form_get_tx_from_data(self, data): """ Given a data dict coming from stripe, verify it and find the related transaction record. """ reference = data.get('metadata', {}).get('reference') if not reference: stripe_error = data.get('error', {}).get('message', '') _logger.error( 'Stripe: invalid reply received from stripe API, looks like ' 'the transaction failed. (error: %s)', stripe_error or 'n/a') error_msg = _( "We're sorry to report that the transaction has failed.") if stripe_error: error_msg += " " + (_( "Stripe gave us the following info about the problem: '%s'" ) % stripe_error) error_msg += " " + _( "Perhaps the problem can be solved by double-checking your " "credit card details, or contacting your bank?") raise ValidationError(error_msg) tx = self.search([('reference', '=', reference)]) if not tx: error_msg = (_('Stripe: no order found for reference %s') % reference) _logger.error(error_msg) raise ValidationError(error_msg) elif len(tx) > 1: error_msg = (_('Stripe: %s orders found for reference %s') % (len(tx), reference)) _logger.error(error_msg) raise ValidationError(error_msg) return tx[0]
def _ogone_form_get_tx_from_data(self, data): """ Given a data dict coming from ogone, verify it and find the related transaction record. Create a payment token if an alias is returned.""" reference, pay_id, shasign, alias = data.get('orderID'), data.get( 'PAYID'), data.get('SHASIGN'), data.get('ALIAS') if not reference or not pay_id or not shasign: error_msg = _( 'Ogone: received data with missing reference (%s) or pay_id (%s) or shasign (%s)' ) % (reference, pay_id, shasign) _logger.info(error_msg) raise ValidationError(error_msg) # find tx -> @TDENOTE use paytid ? tx = self.search([('reference', '=', reference)]) if not tx or len(tx) > 1: error_msg = _('Ogone: received data for reference %s') % ( reference) if not tx: error_msg += _('; no order found') else: error_msg += _('; multiple order found') _logger.info(error_msg) raise ValidationError(error_msg) # verify shasign shasign_check = tx.acquirer_id._ogone_generate_shasign('out', data) if shasign_check.upper() != shasign.upper(): error_msg = _( 'Ogone: invalid shasign, received %s, computed %s, for data %s' ) % (shasign, shasign_check, data) _logger.info(error_msg) raise ValidationError(error_msg) if not tx.acquirer_reference: tx.acquirer_reference = pay_id # alias was created on ogone server, store it if alias and tx.type == 'form_save': Token = self.env['payment.token'] domain = [('acquirer_ref', '=', alias)] cardholder = data.get('CN') if not Token.search_count(domain): _logger.info('Ogone: saving alias %s for partner %s' % (data.get('CARDNO'), tx.partner_id)) ref = Token.create({ 'name': data.get('CARDNO') + (' - ' + cardholder if cardholder else ''), 'partner_id': tx.partner_id.id, 'acquirer_id': tx.acquirer_id.id, 'acquirer_ref': alias }) tx.write({'payment_token_id': ref.id}) return tx
def authorize_create(self, values): if values.get('cc_number'): values['cc_number'] = values['cc_number'].replace(' ', '') acquirer = self.env['payment.acquirer'].browse( values['acquirer_id']) expiry = str(values['cc_expiry'][:2]) + str( values['cc_expiry'][-2:]) partner = self.env['res.partner'].browse(values['partner_id']) transaction = AuthorizeAPI(acquirer) res = transaction.create_customer_profile(partner, values['cc_number'], expiry, values['cc_cvc']) if res.get('profile_id') and res.get('payment_profile_id'): return { 'authorize_profile': res.get('profile_id'), 'name': 'XXXXXXXXXXXX%s - %s' % (values['cc_number'][-4:], values['cc_holder_name']), 'acquirer_ref': res.get('payment_profile_id'), } else: raise ValidationError( _('The Customer Profile creation in Authorize.NET failed.') ) else: return values
def sips_form_generate_values(self, values): self.ensure_one() base_url = self.get_base_url() currency = self.env['res.currency'].sudo().browse(values['currency_id']) sips_currency = SIPS_SUPPORTED_CURRENCIES.get(currency.name) if not sips_currency: raise ValidationError(_('Currency not supported by Wordline: %s') % currency.name) # rounded to its smallest unit, depends on the currency amount = round(values['amount'] * (10 ** sips_currency.decimal)) sips_tx_values = dict(values) data = { 'amount': amount, 'currencyCode': sips_currency.iso_id, 'merchantId': self.sips_merchant_id, 'normalReturnUrl': urls.url_join(base_url, SipsController._return_url), 'automaticResponseUrl': urls.url_join(base_url, SipsController._notify_url), 'transactionReference': values['reference'], 'statementReference': values['reference'], 'keyVersion': self.sips_key_version, } sips_tx_values.update({ 'Data': '|'.join([f'{k}={v}' for k,v in data.items()]), 'InterfaceVersion': self.sips_version, }) return_context = {} if sips_tx_values.get('return_url'): return_context['return_url'] = urls.url_quote(sips_tx_values.get('return_url')) return_context['reference'] = sips_tx_values['reference'] sips_tx_values['Data'] += '|returnContext=%s' % (json.dumps(return_context)) shasign = self._sips_generate_shasign(sips_tx_values) sips_tx_values['Seal'] = shasign return sips_tx_values
def _paypal_form_get_tx_from_data(self, data): reference, txn_id = data.get('item_number'), data.get('txn_id') if not reference or not txn_id: error_msg = _('Paypal: received data with missing reference (%s) or txn_id (%s)') % (reference, txn_id) _logger.info(error_msg) raise ValidationError(error_msg) # find tx -> @TDENOTE use txn_id ? txs = self.env['payment.transaction'].search([('reference', '=', reference)]) if not txs or len(txs) > 1: error_msg = 'Paypal: received data for reference %s' % (reference) if not txs: error_msg += '; no order found' else: error_msg += '; multiple order found' _logger.info(error_msg) raise ValidationError(error_msg) return txs[0]
def _sips_generate_shasign(self, values): """ Generate the shasign for incoming or outgoing communications. :param dict values: transaction values :return string: shasign """ if self.provider != 'sips': raise ValidationError(_('Incorrect payment acquirer provider')) data = values['Data'] key = self.sips_secret shasign = sha256((data + key).encode('utf-8')) return shasign.hexdigest()
def _stripe_form_get_tx_from_data(self, data): """ Given a data dict coming from stripe, verify it and find the related transaction record. """ reference = data.get('metadata', {}).get('reference') if not reference: error_msg = _( 'Stripe: invalid reply received from provider, missing reference. Additional message: %s' % data.get('error', {}).get('message', '')) _logger.error(error_msg) raise ValidationError(error_msg) tx = self.search([('reference', '=', reference)]) if not tx: error_msg = (_('Stripe: no order found for reference %s') % reference) _logger.error(error_msg) raise ValidationError(error_msg) elif len(tx) > 1: error_msg = (_('Stripe: %s orders found for reference %s') % (len(tx), reference)) _logger.error(error_msg) raise ValidationError(error_msg) return tx[0]
def _transfer_form_get_tx_from_data(self, data): reference, amount, currency_name = data.get('reference'), data.get('amount'), data.get('currency_name') tx = self.search([('reference', '=', reference)]) if not tx or len(tx) > 1: error_msg = _('received data for reference %s') % (pprint.pformat(reference)) if not tx: error_msg += _('; no order found') else: error_msg += _('; multiple order found') _logger.info(error_msg) raise ValidationError(error_msg) return tx
def _mollie_form_get_tx_from_data(self, data): reference = data.get('reference') payment_tx = self.search([('reference', '=', reference)]) if not payment_tx or len(payment_tx) > 1: error_msg = _('received data for reference %s') % (pprint.pformat(reference)) if not payment_tx: error_msg += _('; no order found') else: error_msg += _('; multiple order found') _logger.info(error_msg) raise ValidationError(error_msg) return payment_tx
def _check_alipay_configuration(self, vals): acquirer_id = int(vals.get('acquirer_id')) acquirer = self.env['payment.acquirer'].sudo().browse(acquirer_id) if acquirer and acquirer.provider == 'alipay' and acquirer.alipay_payment_method == 'express_checkout': currency_id = int(vals.get('currency_id')) if currency_id: currency = self.env['res.currency'].sudo().browse(currency_id) if currency and currency.name != 'CNY': _logger.info("Only CNY currency is allowed for Alipay Express Checkout") raise ValidationError(_(""" Only transactions in Chinese Yuan (CNY) are allowed for Alipay Express Checkout.\n If you wish to use another currency than CNY for your transactions, switch your configuration to a Cross-border account on the Alipay payment acquirer in Flectra. """)) return True
def _sips_generate_shasign(self, values): """ Generate the shasign for incoming or outgoing communications. :param dict values: transaction values :return string: shasign """ if self.provider != 'sips': raise ValidationError(_('Incorrect payment acquirer provider')) data = values['Data'] # Test key provided by Worldine key = u'002001000000001_KEY1' if self.environment == 'prod': key = getattr(self, 'sips_secret') shasign = sha256((data + key).encode('utf-8')) return shasign.hexdigest()
def _sips_form_get_tx_from_data(self, data): """ Given a data dict coming from sips, verify it and find the related transaction record. """ data = self._sips_data_to_object(data.get('Data')) reference = data.get('transactionReference') if not reference: return_context = json.loads(data.get('returnContext', '{}')) reference = return_context.get('reference') payment_tx = self.search([('reference', '=', reference)]) if not payment_tx: error_msg = _('Sips: received data for reference %s; no order found') % reference _logger.error(error_msg) raise ValidationError(error_msg) return payment_tx
def sips_form_generate_values(self, values): self.ensure_one() base_url = self.env['ir.config_parameter'].sudo().get_param( 'web.base.url') currency = self.env['res.currency'].sudo().browse( values['currency_id']) currency_code = CURRENCY_CODES.get(currency.name, False) if not currency_code: raise ValidationError(_('Currency not supported by Wordline')) amount = int(values['amount'] * 100) if self.environment == 'prod': # For production environment, key version 2 is required merchant_id = getattr(self, 'sips_merchant_id') key_version = self.env['ir.config_parameter'].sudo().get_param( 'sips.key_version', '2') else: # Test key provided by Atos Wordline works only with version 1 merchant_id = '002001000000001' key_version = '1' sips_tx_values = dict(values) sips_tx_values.update({ 'Data': u'amount=%s|' % amount + u'currencyCode=%s|' % currency_code + u'merchantId=%s|' % merchant_id + u'normalReturnUrl=%s|' % urls.url_join(base_url, SipsController._return_url) + u'automaticResponseUrl=%s|' % urls.url_join(base_url, SipsController._return_url) + u'transactionReference=%s|' % values['reference'] + u'statementReference=%s|' % values['reference'] + u'keyVersion=%s' % key_version, 'InterfaceVersion': self.sips_version, }) return_context = {} if sips_tx_values.get('return_url'): return_context[u'return_url'] = u'%s' % sips_tx_values.pop( 'return_url') return_context[u'reference'] = u'%s' % sips_tx_values['reference'] sips_tx_values['Data'] += u'|returnContext=%s' % ( json.dumps(return_context)) shasign = self._sips_generate_shasign(sips_tx_values) sips_tx_values['Seal'] = shasign return sips_tx_values
def _sips_form_get_tx_from_data(self, data): """ Given a data dict coming from sips, verify it and find the related transaction record. """ data = self._sips_data_to_object(data.get('Data')) reference = data.get('transactionReference') if not reference: custom = json.loads(data.pop('returnContext', False) or '{}') reference = custom.get('reference') payment_tx = self.search([('reference', '=', reference)]) if not payment_tx or len(payment_tx) > 1: error_msg = _('Sips: received data for reference %s') % reference if not payment_tx: error_msg += _('; no order found') else: error_msg += _('; multiple order found') _logger.error(error_msg) raise ValidationError(error_msg) return payment_tx
def authorize_create(self, values): if values.get('opaqueData') and values.get('encryptedCardData'): acquirer = self.env['payment.acquirer'].browse( values['acquirer_id']) partner = self.env['res.partner'].browse(values['partner_id']) transaction = AuthorizeAPI(acquirer) res = transaction.create_customer_profile(partner, values['opaqueData']) if res.get('profile_id') and res.get('payment_profile_id'): return { 'authorize_profile': res.get('profile_id'), 'name': values['encryptedCardData'].get('cardNumber'), 'acquirer_ref': res.get('payment_profile_id'), 'verified': True } else: raise ValidationError( _('The Customer Profile creation in Authorize.NET failed.') ) else: return values
def mollie_intermediate(self, **post): acquirer = request.env['payment.acquirer'].browse(int(post['Key'])) url = post['URL'] + "payments" headers = { 'content-type': 'application/json', 'Authorization': 'Bearer ' + acquirer._get_mollie_api_keys( acquirer.environment)['mollie_api_key'] } base_url = post['BaseUrl'] orderid = post['OrderId'] description = post['Description'] currency = post['Currency'] amount = post['Amount'] language = post['Language'] name = post['Name'] email = post['Email'] zip = post['Zip'] address = post['Address'] town = post['Town'] country = post['Country'] phone = post['Phone'] payload = { "description": description, "amount": amount, "redirectUrl": "%s%s?reference=%s" % (base_url, self._redirect_url, orderid), "metadata": { "order_id": orderid, "customer": { "locale": language, "currency": currency, "last_name": name, "address1": address, "zip_code": zip, "city": town, "country": country, "phone": phone, "email": email } } } mollie_response = requests.post(url, data=json.dumps(payload), headers=headers).json() if mollie_response["status"] == "open": payment_tx = request.env['payment.transaction'].sudo().search([ ('reference', '=', orderid) ]) if not payment_tx or len(payment_tx) > 1: error_msg = ('received data for reference %s') % ( pprint.pformat(orderid)) if not payment_tx: error_msg += ('; no order found') else: error_msg += ('; multiple order found') _logger.info(error_msg) raise ValidationError(error_msg) payment_tx.write({"acquirer_reference": mollie_response["id"]}) payment_url = mollie_response["links"]["paymentUrl"] return werkzeug.utils.redirect(payment_url) return werkzeug.utils.redirect("/")