Skip to content
This repository was archived by the owner on Jun 26, 2025. It is now read-only.

Commit 159e308

Browse files
nuhamozainiecleel
authored andcommitted
Initial version of Python lib (#1)
* docs provided for the special attribute __doc__ * requirements.txt added * code refactoring * Refactoring: PEP 8 compliance * Packaging * Project structure changes * refactoring.. * refactoring.. 2 * payment code rewrite, other modifications * Library design change. * requirements.txt update * clean up * Delete .DS_Store * clean up * clean up * clean up * documentation * documentation * documentation * Constructed new class Source, a parent of Sadad and CreditCard + changes for Source * small logical change * Test suite added * modifications to mock request * test cases for invoice + code quality modifications * invoice test * invoice test mods * moyasar tests * payment tests * pass payment.source instead of payment to build() * overrode __init__ to build the source * file rename. * Constructor class
1 parent f3cd117 commit 159e308

26 files changed

Lines changed: 981 additions & 0 deletions

README.rst

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
===============
2+
Moyasar-Python
3+
===============
4+
5+
Moyasar Python language wrapper
6+
7+
--------------
8+
Documentation
9+
--------------
10+
11+
12+
13+
14+
See the `Python API docs. <https://moyasar.com/docs/api/?python>`_
15+
16+
-------------
17+
Requirements
18+
-------------
19+
20+
* Python +2.7 or +3.x
21+
22+
--------------
23+
Installation
24+
--------------
25+
26+
.. code-block:: bash
27+
28+
pip install moyasar
29+
30+
31+
-------
32+
Usage
33+
-------
34+
35+
36+
.. code-block:: python
37+
38+
import moyasar
39+
moyasar.api_key = '<moyasar key>'
40+
fetch_invoice = moyasar.Invoice.fetch('<invoice id>')
41+
fetch_invoice.cancel()
42+
43+
-------------
44+
Contributing
45+
-------------
46+
47+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/moyasar. This project is intended to be a safe, welcoming space for collaboration.
48+
49+
50+
--------
51+
License
52+
--------
53+
54+
55+
The library is available as open source under the terms of the `MIT License. <https://opensource.org/licenses/MIT>`_

moyasar/__init__.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import base64
2+
3+
import requests
4+
import json
5+
from moyasar.payment import Payment
6+
from moyasar.invoice import Invoice
7+
8+
api_key = None
9+
api_version = 'v1'
10+
api_url = f'https://api.moyasar.com/{api_version}'
11+
12+
13+
def resource_url(resource_name):
14+
return f'{api_url}/{resource_name}s'
15+
16+
17+
def fill_object(object, data):
18+
for key in data:
19+
object.__setattr__(key, data[key])
20+
21+
22+
def request(http_verb, url, data, key=None):
23+
moyasar_key = key or api_key
24+
25+
if moyasar_key is None:
26+
raise Exception('API key must be provided')
27+
28+
request = {
29+
'method': http_verb.upper(),
30+
'url': url,
31+
'auth': (api_key, ''),
32+
'headers': {
33+
'Content-Type': 'application/json'
34+
}
35+
}
36+
if data is not None:
37+
if http_verb.upper() == 'GET':
38+
request['params'] = data
39+
else:
40+
request['data'] = json.dumps(data)
41+
42+
res = requests.request(**request)
43+
if 400 <= res.status_code <= 404:
44+
json_string = res.text
45+
json_dict = json.loads(json_string)
46+
json_dict["http_code"] = res.status_code
47+
raise Exception(f'{json.dumps(json_dict)}')
48+
if 500 <= res.status_code <= 504:
49+
raise Exception(f'API Error with status code: {res.status_code}')
50+
return res

moyasar/actions/__init__.py

Whitespace-only changes.

moyasar/actions/cancel.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import moyasar
2+
import json
3+
4+
5+
class Cancel:
6+
def cancel_url(self, id):
7+
return f'{moyasar.resource_url(self.__class__.__name__)}/{id}/cancel'.lower()
8+
9+
def cancel(self):
10+
response = moyasar.request('PUT', self.cancel_url(self.id), None)
11+
response = json.loads(response.text)
12+
moyasar.fill_object(self, response)
13+
return response

moyasar/actions/create.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import moyasar
2+
import json
3+
from moyasar.constructor import Constructor
4+
5+
6+
class Create(Constructor):
7+
def __init__(self, data):
8+
super().__init__(data)
9+
10+
@classmethod
11+
def create_url(cls):
12+
return f'{moyasar.resource_url(cls.__name__)}'.lower()
13+
14+
@classmethod
15+
def create(cls, data):
16+
response = moyasar.request('POST', cls.create_url(), data)
17+
response = json.loads(response.text)
18+
return cls(response)

moyasar/actions/fetch.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import moyasar
2+
import json
3+
from moyasar.constructor import Constructor
4+
5+
6+
class Fetch(Constructor):
7+
def __init__(self, data):
8+
super().__init__(data)
9+
10+
@classmethod
11+
def fetch_url(cls, id):
12+
return f'{moyasar.resource_url(cls.__name__)}/{id}'.lower()
13+
14+
@classmethod
15+
def fetch(cls, id):
16+
response = moyasar.request('GET', cls.fetch_url(id), None)
17+
response = json.loads(response.text)
18+
return cls(response)

moyasar/actions/list.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import moyasar
2+
import json
3+
from moyasar.constructor import Constructor
4+
5+
6+
class List(Constructor):
7+
def __init__(self, data):
8+
super().__init__(data)
9+
10+
@classmethod
11+
def list_url(cls):
12+
return f'{moyasar.resource_url(cls.__name__)}'.lower()
13+
14+
@classmethod
15+
def list(cls, data=None):
16+
response = moyasar.request('GET', cls.list_url(), data)
17+
response = json.loads(response.text)
18+
field_name = f'{cls.__name__}s'.lower()
19+
resource_list = []
20+
for resource in response[field_name]:
21+
resource_list.append(cls(resource))
22+
23+
return resource_list

moyasar/actions/refund.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import moyasar
2+
import json
3+
4+
5+
class Refund:
6+
def refund_url(self, id):
7+
return f'{moyasar.resource_url(self.__class__.__name__)}/{id}/refund'.lower()
8+
9+
def refund(self, amount=None):
10+
data = None
11+
if amount is not None:
12+
data = {'amount': amount}
13+
14+
response = moyasar.request('POST', self.refund_url(self.id), data)
15+
response = json.loads(response.text)
16+
moyasar.fill_object(self, response)

moyasar/actions/update.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import moyasar
2+
import json
3+
4+
5+
class Update:
6+
def update_url(self, id):
7+
return f'{moyasar.resource_url(self.__class__.__name__)}/{id}'.lower()
8+
9+
def update(self, data):
10+
response = moyasar.request('PUT', self.update_url(self.id), data)
11+
return response

moyasar/constructor.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class Constructor:
2+
3+
def __init__(self, **kwargs):
4+
for key in kwargs:
5+
setattr(self, key, kwargs[key])

0 commit comments

Comments
 (0)