Files
odoo_source/addons/adyen_platforms/util.py
T
Antoine Prieels 9ed73b23d7 [ADD] adyen_platforms,pos_adyen: Add support for Adyen for Platforms
The goal is to add a nice payment solution to our users.

- Why Adyen?
  - Worldwide
  - Manages local payment solutions
  - Easy onboarding
  - For both PoS and eCommerce

- Why Adyen for Platforms?
  - The onboarding will be done directly from the customer's DB.
  - It's quite complicated for SMEs to get a partnership with Adyen as
  they have high requirements for transaction volume. By registering
  Odoo as a Platform with Adyen Marketpay, we allow our users to
  register as sub-merchants under a common account, removing this
  constraint.

As all users are grouped under a common account, all requests need to
provide the same API key. As this key cannot be shared, all requests to
the Adyen API will need to be proxied. A new proxy will be created on
`paymentproxy.odoo.com`.

To initiate a payment, 3 values are required:
  - `account_holder_code`: This code is provided by Adyen and is used to
  identify the sub-merchant under the common account.
  - `adyen_uuid`: This ID is used internally to identify the user.
  - `proxy_token`: This token is generated by the proxy during the
  account creation and is used to sign all requests.

The DB of the customer is the only host who has all the information
required to modify the sub-merchant info or initiate a payment. If
this information leak, the `proxy_token` can be reset on the proxy to
revoke all access to the API.

Before accessing the form to create an account, users will be
redirected to www.odoo.com where they will be asked to log in. This
ensures that we have contact information for this sub-merchant.

TaskID: 2129218
2020-09-29 04:25:44 +00:00

43 lines
1.4 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
import hashlib
import hmac
import json
import requests
import time
import werkzeug.urls
class AdyenProxyAuth(requests.auth.AuthBase):
def __init__(self, adyen_account_id):
super(AdyenProxyAuth, self).__init__()
self.adyen_account_id = adyen_account_id
def __call__(self, request):
h = hmac.new(self.adyen_account_id.proxy_token.encode('utf-8'), digestmod=hashlib.sha256)
# Craft the message (timestamp|url path|query params|body content)
msg_timestamp = int(time.time())
parsed_url = werkzeug.urls.url_parse(request.path_url)
body = request.body
if isinstance(body, bytes):
body = body.decode('utf-8')
body = json.loads(body)
message = '%s|%s|%s|%s' % (
msg_timestamp, # timestamp
parsed_url.path, # url path
json.dumps(werkzeug.urls.url_decode(parsed_url.query), sort_keys=True), # url query params sorted by key
json.dumps(body, sort_keys=True)) # request body
h.update(message.encode('utf-8')) # digest the message
request.headers.update({
'oe-adyen-uuid': self.adyen_account_id.adyen_uuid,
'oe-signature': base64.b64encode(h.digest()),
'oe-timestamp': msg_timestamp,
})
return request