## $Id$ ## ## Copyright (C) 2022 Uli Fouquet & Henrik Bettermann ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## import json import requests import uuid from zope.component import getUtility, queryUtility from kofacustom.nigeria.paypal.interfaces import IPaypalConfig PAYPAL_REST_URLS = { 'sandbox': 'https://api-m.sandbox.paypal.com', 'live': 'https://api-m.paypal.com'} def get_auth_token(): """Get an authentication token from paypal Requests to paypal must provide an authorization token, which can be retrieved by sending REST credentials (`client_id` and `client_secret`) as provided in your Paypal developer account. During livespan of tokens, this call will not create new ones. """ config = getUtility(IPaypalConfig) url = "%s/v1/oauth2/token" % PAYPAL_REST_URLS[config['mode']] auth = requests.auth.HTTPBasicAuth( config['client_id'], config['client_secret']) headers = {"content-type": "application/x-www-form-urlencoded"} params = [("grant_type", "client_credentials"), ] response = requests.post(url, auth=auth, headers=headers, params=params) response.raise_for_status() result = response.json() return result["access_token"] def create_order( purchase_units, return_url, cancel_url, request_id=None, notify_url=None): token = get_auth_token() if request_id is None: request_id = str(uuid.uuid4()) headers = { "content-type": "application/json", "authorization": "Bearer %s" % token, "paypal-request-id": request_id } json_data = { "intent": "CAPTURE", "payment_source": { "paypal": { "experience_context": { "landing_page": "NO_PREFERENCE", "user_action": "CONTINUE", "brand_name": "WAeUP", "shipping_preference": "NO_SHIPPING", "cancel_url": cancel_url, "return_url": return_url} } }, "purchase_units": [] } units = [x.json() for x in purchase_units] for n, unit in enumerate(units): unit["reference_id"] = n json_data["purchase_units"].append(unit) if notify_url: json_data["payment_source"]["paypal"][ "experience_context"]["notify_url"] = notify_url config = getUtility(IPaypalConfig) url = "%s/v2/checkout/orders" % PAYPAL_REST_URLS[config['mode']] response = requests.post(url, headers=headers, json=json_data) try: response.raise_for_status() except requests.HTTPError as err: data = err.response.json() return None, None, request_id, data data = response.json() order_id = data['id'] # order token payment_link = [x for x in data['links'] if x["rel"] == "payer-action"][0]["href"] return order_id, payment_link, request_id, data def capture_order(order_id, request_id=None): config = getUtility(IPaypalConfig) token = get_auth_token() headers = { "content-type": "application/json", "authorization": "Bearer %s" % token, "paypal-request-id": request_id } if request_id is not None: headers["paypal-request-id"] = request_id url = "%s/v2/checkout/orders/%s/capture" % ( PAYPAL_REST_URLS[config['mode']], order_id) response = requests.post(url, headers=headers) response.raise_for_status() data = response.json() return data