_return_url = '/payment/paypal/dpn/'
_cancel_url = '/payment/paypal/cancel/'
+ def _get_return_url(self, **post):
+ """ Extract the return URL from the data coming from paypal. """
+ return_url = post.pop('return_url', '')
+ if not return_url:
+ custom = json.loads(post.pop('custom', '{}'))
+ return_url = custom.get('return_url', '/')
+ return return_url
+
def paypal_validate_data(self, **post):
""" Paypal IPN: three steps validation to ensure data correctness
urequest = urllib2.Request("https://www.sandbox.paypal.com/cgi-bin/webscr", urllib.urlencode(new_post))
uopen = urllib2.urlopen(urequest)
resp = uopen.read()
- if resp.text == 'VERIFIED':
+ if resp == 'VERIFIED':
_logger.info('Paypal: validated data')
cr, uid, context = request.cr, request.uid, request.context
res = request.registry['payment.transaction'].form_feedback(cr, uid, post, 'paypal', context=context)
- elif resp.text == 'INVALID':
+ elif resp == 'INVALID':
_logger.warning('Paypal: answered INVALID on data verification')
else:
_logger.warning('Paypal: unrecognized paypal answer, received %s instead of VERIFIED or INVALID' % resp.text)
@website.route([
'/payment/paypal/ipn/',
- ], type='http', auth='public')
+ ], type='http', auth='public', methods=['POST'])
def paypal_ipn(self, **post):
""" Paypal IPN. """
_logger.info('Beginning Paypal IPN form_feedback with post data %s', pprint.pformat(post)) # debug
@website.route([
'/payment/paypal/dpn',
- ], type='http', auth="public")
+ ], type='http', auth="public", methods=['POST'])
def paypal_dpn(self, **post):
""" Paypal DPN """
_logger.info('Beginning Paypal DPN form_feedback with post data %s', pprint.pformat(post)) # debug
- return_url = post.pop('return_url', '')
- if not return_url:
- custom = json.loads(post.pop('custom', '{}'))
- return_url = custom.pop('return_url', '/')
+ return_url = self._get_return_url(**post)
self.paypal_validate_data(**post)
return request.redirect(return_url)
'/payment/paypal/cancel',
], type='http', auth="public")
def paypal_cancel(self, **post):
- """ TODO
- """
+ """ When the user cancels its Paypal payment: GET on this route """
cr, uid, context = request.cr, request.uid, request.context
- print 'Entering paypal_cancel with post', post
-
- return_url = post.pop('return_url', '/')
- print 'return_url', return_url
+ _logger.info('Beginning Paypal cancel with post data %s', pprint.pformat(post)) # debug
+ return_url = self._get_return_url(**post)
return request.redirect(return_url)
_columns = {
'paypal_email_id': fields.char('Email ID', required_if_provider='paypal'),
- 'paypal_username': fields.char('Username', required_if_provider='paypal'),
+ 'paypal_seller_id': fields.char('Seller ID', required_if_provider='paypal'),
'paypal_use_ipn': fields.boolean('Use IPN'),
# Server 2 server
'paypal_api_enabled': fields.boolean('Use Rest API'),
return self.browse(cr, uid, tx_ids[0], context=context)
def _paypal_form_get_invalid_parameters(self, cr, uid, tx, data, context=None):
- # TODO: txn_id: shoudl be false at draft, set afterwards, and verified with txn details
invalid_parameters = []
- if data.get('notify_version')[0] != '2.6':
+ if data.get('notify_version')[0] != '3.4':
_logger.warning(
'Received a notification from Paypal with version %s instead of 2.6. This could lead to issues when managing it.' %
data.get('notify_version')
_logger.warning(
'Received a notification from Paypal using sandbox'
),
+
+ # TODO: txn_id: shoudl be false at draft, set afterwards, and verified with txn details
+ if tx.acquirer_reference and data.get('txn_id') != tx.acquirer_reference:
+ invalid_parameters.append(('txn_id', data.get('txn_id'), tx.acquirer_reference))
# check what is buyed
- if float_compare(float(data.get('mc_gross', '0.0')), tx.amount, 2) != 0:
- invalid_parameters.append(('mc_gross', data.get('mc_gross'), '%.2f' % tx.amount))
+ if float_compare(float(data.get('mc_gross', '0.0')), (tx.amount + tx.fees), 2) != 0:
+ invalid_parameters.append(('mc_gross', data.get('mc_gross'), '%.2f' % tx.amount)) # mc_gross is amount + fees
if data.get('mc_currency') != tx.currency_id.name:
- invalid_parameters.append(('mc_currency', data.get('mc_currency'), tx.currency_id.name))
- # if parameters.get('payment_fee') != tx.payment_fee:
- # invalid_parameters.append(('payment_fee', tx.payment_fee))
- # if parameters.get('quantity') != tx.quantity:
- # invalid_parameters.append(('mc_currency', tx.quantity))
- # if parameters.get('shipping') != tx.shipping:
- # invalid_parameters.append(('shipping', tx.shipping))
+ invalid_parameters.append(('mc_currency', data.get('mc_currency'), tx.currency_id.name))
+ if 'handling_amount' in data and float_compare(float(data.get('handling_amount')), tx.fees, 2) != 0:
+ invalid_parameters.append(('handling_amount', data.get('handling_amount'), tx.fees))
# check buyer
- # if parameters.get('payer_id') != tx.payer_id:
- # invalid_parameters.append(('mc_gross', tx.payer_id))
- # if parameters.get('payer_email') != tx.payer_email:
- # invalid_parameters.append(('payer_email', tx.payer_email))
+ if tx.partner_reference and data.get('payer_id') != tx.partner_reference:
+ invalid_parameters.append(('payer_id', data.get('payer_id'), tx.partner_reference))
# check seller
- # if parameters.get('receiver_email') != tx.receiver_email:
- # invalid_parameters.append(('receiver_email', tx.receiver_email))
- # if parameters.get('receiver_id') != tx.receiver_id:
- # invalid_parameters.append(('receiver_id', tx.receiver_id))
+ if data.get('receiver_email') != tx.acquirer_id.paypal_email_id:
+ invalid_parameters.append(('receiver_email', data.get('receiver_email'), tx.acquirer_id.paypal_email_id))
+ if data.get('receiver_id') != tx.acquirer_id.paypal_seller_id:
+ invalid_parameters.append(('receiver_id', data.get('receiver_id'), tx.acquirer_id.paypal_seller_id))
return invalid_parameters
def _paypal_form_validate(self, cr, uid, tx, data, context=None):
status = data.get('payment_status')
+ data = {
+ 'acquirer_reference': data.get('txn_id'),
+ 'paypal_txn_type': data.get('payment_type'),
+ 'partner_reference': data.get('payer_id')
+ }
if status in ['Completed', 'Processed']:
_logger.info('Validated Paypal payment for tx %s: set as done' % (tx.reference))
- tx.write({
- 'state': 'done',
- 'date_validate': data.get('payment_date', fields.datetime.now()),
- 'paypal_txn_id': data['txn_id'],
- 'paypal_txn_type': data.get('express_checkout'),
- })
- return True
+ data.update(state='done', date_validate=data.get('payment_date', fields.datetime.now()))
+ return tx.write(data)
elif status in ['Pending', 'Expired']:
_logger.info('Received notification for Paypal payment %s: set as pending' % (tx.reference))
- tx.write({
- 'state': 'pending',
- 'state_message': data.get('pending_reason', ''),
- 'paypal_txn_id': data['txn_id'],
- 'paypal_txn_type': data.get('express_checkout'),
- })
- return True
+ data.udpate(state='pending', state_message=data.get('pending_reason', ''))
+ return tx.write(data)
else:
error = 'Received unrecognized status for Paypal payment %s: %s, set as error' % (tx.reference, status)
_logger.info(error)
- tx.write({
- 'state': 'error',
- 'state_message': error,
- 'paypal_txn_id': data['txn_id'],
- 'paypal_txn_type': data.get('express_checkout'),
- })
- return False
+ data.update(state='error', state_message=error)
+ return tx.write(data)
# --------------------------------------------------
# SERVER2SERVER RELATED METHODS