Skip to content

Python Api Wrapper update #168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
.DS_Store
**/venv
**/VivaPython.egg-info
21 changes: 21 additions & 0 deletions CreateOrder/Python/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2016 Peter Perlepes

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
54 changes: 54 additions & 0 deletions CreateOrder/Python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# VivaPayments Python API wrapper

![N|Solid](https://www.vivawallet.com/App_Themes/VivaWallet/Resources/img/viva-logo.png)

### Installation
```bash
python setup.py install
```

PyPI will be up soon :)

### Usage
```sh
from VivaPayments import client
viva_client = client.Client('MERCHANT_ID', 'API_KEY')
#for production do client.Client('MERCHANT_ID', 'API_KEY', 'production')
```
With viva_client you can call any model you require and the desired action. The tests folder can serve as an initial guideline for your API calls.
```sh
#example
order = viva_client.Order.Create(100)
order_code = order['result']['OrderCode']
```
### Models

The Python wrapper currently supports the listed calls.

* Card (CreateToken, CheckInstallments)
* Order(Create, Cancel, Get, Update)
* Source(Add)
* Transaction(Get, Create, CreateRecurring, Cance, OriginalCreditTransaction)
* Wallet(BalanceTransfer)

For some of the calls you need special permissions from Viva so consult the wiki before using.

### Testing

```sh
python setup.py test
```
For the tests to pass you need to set up the followiwng enviroment variables.:
* TEST_MERCHANT (Your demo merchant ID)
* TEST_KEY (Your demo API Key)
* WALLET_ID (Your Viva wallet ID)

License
----
MIT


### Documentation
Code is clearly documented inside the module at the moment but will be officially documented after the PyPI release.

For more information about the API usage refer to [Viva wiki](https://github.com/VivaPayments/API/wiki).
76 changes: 76 additions & 0 deletions CreateOrder/Python/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
VivaPayments Python API wrapper
===============================

.. figure:: https://www.vivawallet.com/App_Themes/VivaWallet/Resources/img/viva-logo.png
:alt: N\|Solid

N\|Solid

Installation
~~~~~~~~~~~~

.. code:: bash

python setup.py install

PyPI will be up soon :)

Usage
~~~~~

.. code:: sh

from VivaPayments import client
viva_client = client.Client('MERCHANT_ID', 'API_KEY')
#for production do client.Client('MERCHANT_ID', 'API_KEY', 'production')

With viva\_client you can call any model you require and the desired
action. The tests folder can serve as an initial guideline for your API
calls.

.. code:: sh

#example
order = viva_client.Order.Create(100)
order_code = order['result']['OrderCode']

Models
~~~~~~

The Python wrapper currently supports the listed calls.

- Card (CreateToken, CheckInstallments)
- Order(Create, Cancel, Get, Update)
- Source(Add)
- Transaction(Get, Create, CreateRecurring, Cance,
OriginalCreditTransaction)
- Wallet(BalanceTransfer)

For some of the calls you need special permissions from Viva so consult
the wiki before using.

Testing
~~~~~~~

.. code:: sh

python setup.py test

For the tests to pass you need to set up the followiwng enviroment
variables.: \* TEST\_MERCHANT (Your demo merchant ID) \* TEST\_KEY (Your
demo API Key) \* WALLET\_ID (Your Viva wallet ID)

License
-------

MIT

Documentation
~~~~~~~~~~~~~

Code is clearly documented inside the module at the moment but will be
officially documented after the PyPI release.

For more information about the API usage refer to `Viva wiki`_.

.. _Viva wiki: https://github.com/VivaPayments/API/wiki
Empty file.
144 changes: 144 additions & 0 deletions CreateOrder/Python/VivaPayments/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import json
import logging
import urllib
from base64 import b64encode
from util.http import Urllib2Client
from util.optional import allowed_parameters
from models import *

class Client(object):
"""Client responsible for constructing the API calls.

Example:
new_client = Client(merchant_id = 'TEST_ID', api_key = 'TEST_KEY')
new_client.Order.Create(100)

"""
http_client = Urllib2Client()

def __init__(self, merchant_id=None, api_key=None, enviroment=None):
"""__init__ function for Client

Args:
merchant_id (str): Defaults to None. The client's Merchant ID.
api_key (str): Defaults to None. The client's API Key.
enviroment (str): Defaults to None. The enviroment that
the client calls will be directed to. The production enviroment
will only be called if 'production' is passed.

Attributes:
url (str): URL that will be used for the API calls. Depends on the
enviroment argument.
headers (str): Authentication header that is used in every request.
Transaction (object): Transaction class instance.
Order (object): Order class instance.
Source (object): Source class instance.
Card (object): Card class instance.
Wallet (object): Wallet class instance.

Raises:
Exception: If the Client instance was initialized without Merchant ID or API Key.
"""
if not (api_key and merchant_id):
raise Exception('Client must be instantiated with Merchant ID and API Key.')

self.api_key = api_key
self.merchant_id = merchant_id
self.url = 'https://www.vivapayments.com/api/' if enviroment in [
'production'] else 'http://demo.vivapayments.com/api/'
self.enviroment = 'demo' if 'demo' in self.url else 'production'
self.headers = 'Basic {}'.format(
b64encode(self.merchant_id + ':' + self.api_key))

self.Transaction = Transaction(self)
self.Order = Order(self)
self.Source = Source(self)
self.Card = Card(self)
self.Wallet = Wallet(self)

def __repr__(self):
return 'Vivapayments {} Client object with api_key: {} , merchant_id: {} '.format(self.enviroment, self.api_key, self.merchant_id)

def call_api(self, method, path, params=None, data=None, headers=None, optional_parameters = None):
"""Function that formats the API request.

The call_api function is used for every request done to API, it formats the request parameters,
request body and optional parameters if expected and optional headers passed. Finally uses the
http_client to fullfill the request.

Args:
method (str): The HTTP method that will be used.
path (str): The path that the request is directed to.
params (dict): Defaults to None. URL parameters to be used in the API call.
data (dict): Defaults to None. Data to be used in the request's body if the
appropriate method is used.
headers (dict): Defaults to None. Optional headers that will be used along with
the Basic Auth for the API.
optional_parameters (dict): Defaults to None. Any optional parameter that could be
passed in the request's body.

Raises:
Exception: HTTP method not supported by the API.

"""
headers = headers if headers else {}
headers['Authorization'] = self.headers

request_url = self.url + path

if params:
request_url = request_url + '?' + urllib.urlencode(self._pack(params))

if data and method not in ['POST', 'PUT', 'PATCH', 'DELETE']:
raise Exception('Incorrect HTTP method for arguments: ' + data)
elif data:
headers['Content-type'] = 'application/json'
if optional_parameters:
self._check_allowed(optional_parameters)
data = json.dumps(self._pack(data, optional_parameters = optional_parameters))

return self.http_client.make_request(method, request_url, headers, post_data = data)


def _pack(self, data, optional_parameters = None):
"""Function to merge the standard with optional params in the request.

The _pack function is used to add the optional parameters along with the standard, in the
body of the request. It is also used to remove None values from body and URL params.

Args:
data (dict): The standard data to be passed in the URL body.
optional_parameters (dict): Any optional parameters that the user added.

Returns:
merged_data (dict): Dictionary stripped of the None valued keys, along with
any optional parameters merged.

Example:
data = {'OrderCode':'1234', 'date': None}
optional_parameters = {'TransactionId': '5678'}
merged_data = _pack(data, optional_parameters)
'{'OrderCode':'1234', 'TransactionId': '5678'}'

"""
data = dict((key,value) for key, value in data.iteritems() if value != None)
merged_data = data.copy()
if optional_parameters: merged_data.update(optional_parameters)
return merged_data

def _check_allowed(self, optional_parameters):
"""Function that checks the validity of the optional parameters passed.

The _check_allowed function, checks if the optional parameteres that were
passed in the request, are valid based on the online documentation and warns
the user using the logging module.

Args:
optional_parameters (dict): The optional parameters to be passed in the request.

"""
for key in optional_parameters.keys():
if key not in allowed_parameters.keys():
logging.warn('Parameter {} is most likely not supported by the API.'.format(key))


5 changes: 5 additions & 0 deletions CreateOrder/Python/VivaPayments/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from order import Order
from source import Source
from transaction import Transaction
from card import Card
from wallet import Wallet
50 changes: 50 additions & 0 deletions CreateOrder/Python/VivaPayments/models/card.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from datetime import datetime


class Card(object):

def __init__(self, config):
self.config = config

def CreateToken(self, public_key, cc_id, cvc, expiration_date, cardholder_name):
"""Function used to generate a credit card token.

Args:
public_key (str): The user's public API key.
cc_id (int): The credit card number.
cvc (int): The credit card CVC/CVV.
expiration_date (str) or (datetime): The credit card's
expiration date.
cardholder_name: The cardholder name of the card.

"""
if isinstance(expiration_date, datetime):
expiration_date = date.strftime('%Y-%m-%d')
elif expiration_date:
expiration_date = expiration_date[:10]

params = {
'key': public_key
}
headers = {
'NativeCheckoutVersion': '230'
}
data = {
'Number': cc_id,
'CVC': cvc,
'ExpirationDate': expiration_date,
'CardHolderName': cardholder_name
}
return self.config.call_api('POST', 'cards', params=params, data=data)

def CheckInstallments(self, cc_id):
"""Function used to check the installments limit of a credit card.

Args:
cc_id (int): The credit card number to be checked.

"""
headers = {
'CardNumber': cc_id
}
return self.config.call_api('GET', 'cards/installments', headers=headers)
Loading