source: main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/paypal/rest.py @ 17945

Last change on this file since 17945 was 17241, checked in by Henrik Bettermann, 23 months ago

Ease customization.

File size: 4.2 KB
Line 
1## $Id$
2##
3## Copyright (C) 2022 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18import json
19import requests
20import uuid
21from zope.component import getUtility, queryUtility
22from kofacustom.nigeria.paypal.interfaces import IPaypalConfig
23
24
25PAYPAL_REST_URLS = {
26        'sandbox': 'https://api-m.sandbox.paypal.com',
27        'live':    'https://api-m.paypal.com'}
28
29
30def get_auth_token():
31    """Get an authentication token from paypal
32
33    Requests to paypal must provide an authorization token, which can be
34    retrieved by sending REST credentials (`client_id` and `client_secret`) as
35    provided in your Paypal developer account.
36
37    During livespan of tokens, this call will not create new ones.
38    """
39    config = getUtility(IPaypalConfig)
40    url = "%s/v1/oauth2/token" % PAYPAL_REST_URLS[config['mode']]
41    auth = requests.auth.HTTPBasicAuth(
42            config['client_id'], config['client_secret'])
43    headers = {"content-type": "application/x-www-form-urlencoded"}
44    params = [("grant_type", "client_credentials"), ]
45    response = requests.post(url, auth=auth, headers=headers, params=params)
46    response.raise_for_status()
47    result = response.json()
48    return result["access_token"]
49
50
51def create_order(
52        purchase_units, return_url, cancel_url,
53        request_id=None, notify_url=None):
54    token = get_auth_token()
55    if request_id is None:
56        request_id = str(uuid.uuid4())
57    headers = {
58        "content-type": "application/json",
59        "authorization": "Bearer %s" % token,
60        "paypal-request-id": request_id
61    }
62
63    json_data = {
64            "intent": "CAPTURE",
65            "payment_source": {
66                "paypal": {
67                    "experience_context": {
68                        "landing_page": "NO_PREFERENCE",
69                        "user_action": "CONTINUE",
70                        "brand_name": "WAeUP",
71                        "shipping_preference": "NO_SHIPPING",
72                        "cancel_url": cancel_url,
73                        "return_url": return_url}
74                    }
75                },
76            "purchase_units": []
77        }
78    units = [x.json() for x in purchase_units]
79    for n, unit in enumerate(units):
80        unit["reference_id"] = n
81        json_data["purchase_units"].append(unit)
82    if notify_url:
83        json_data["payment_source"]["paypal"][
84                "experience_context"]["notify_url"] = notify_url
85    config = getUtility(IPaypalConfig)
86    url = "%s/v2/checkout/orders" % PAYPAL_REST_URLS[config['mode']]
87    response = requests.post(url,
88            headers=headers, json=json_data)
89    try:
90        response.raise_for_status()
91    except requests.HTTPError as err:
92        data = err.response.json()
93        return None, None, request_id, data
94    data = response.json()
95    order_id = data['id']  # order token
96    payment_link = [x for x in data['links']
97            if x["rel"] == "payer-action"][0]["href"]
98    return order_id, payment_link, request_id, data
99
100
101def capture_order(order_id, request_id=None):
102    config = getUtility(IPaypalConfig)
103    token = get_auth_token()
104    headers = {
105        "content-type": "application/json",
106        "authorization": "Bearer %s" % token,
107        "paypal-request-id": request_id
108    }
109    if request_id is not None:
110        headers["paypal-request-id"] = request_id
111    url = "%s/v2/checkout/orders/%s/capture" % (
112        PAYPAL_REST_URLS[config['mode']], order_id)
113    response = requests.post(url, headers=headers)
114    response.raise_for_status()
115    data = response.json()
116    return data
Note: See TracBrowser for help on using the repository browser.