diff --git a/openpix/__init__.py b/openpix/__init__.py new file mode 100644 index 0000000..f30cf6f --- /dev/null +++ b/openpix/__init__.py @@ -0,0 +1,8 @@ +""" +Module: woovi/__init__.py +""" +from openpix.sdk import SDK as createClient + +__all__ = ( + 'createClient', +) \ No newline at end of file diff --git a/openpix/http/__init__.py b/openpix/http/__init__.py new file mode 100644 index 0000000..9f5d9f2 --- /dev/null +++ b/openpix/http/__init__.py @@ -0,0 +1,8 @@ +""" +Module: http/__init__.py +""" +from openpix.http.http_client import HttpClient + +__all__ = ( + 'HttpClient', +) \ No newline at end of file diff --git a/openpix/http/http_client.py b/openpix/http/http_client.py new file mode 100644 index 0000000..36e662a --- /dev/null +++ b/openpix/http/http_client.py @@ -0,0 +1,105 @@ +import requests +from requests.adapters import HTTPAdapter +from urllib3.util import Retry +from urllib.parse import urlencode, urljoin + +class HttpClient: + """ + Default implementation to call all REST API's + """ + + def __init__(self, app_id): + self._app_id = app_id + self.base_url = "https://api.openpix.com.br" + + def request(self, method, path, query, maxretries=None, data = None, **kwargs): + """Makes a call to the API. + + All **kwargs are passed verbatim to ``requests.request``. + """ + if(query): + query_string = urlencode({k: v for k, v in query.items() if v is not None}) + url = urljoin(self.base_url + path, '?' + query_string) + else: + url = self.base_url + path + + if(data): + data = {k: v for k, v in data.items() if v is not None} + + headers = kwargs.get('headers', {}) + headers['Authorization'] = self._app_id + kwargs['headers'] = headers + + retry_strategy = Retry( + total=maxretries, + status_forcelist=[429, 500, 502, 503, 504] + ) + http = requests.Session() + http.mount("https://", HTTPAdapter(max_retries=retry_strategy)) + + with http as session: + api_result = session.request(method, url, data=data,**kwargs) + + response = api_result.json() + if api_result.status_code > 299: + raise ValueError(response) + + return response + + def get(self, path, query = None, params=None, timeout=None, maxretries=None): + """Makes a GET request to the API""" + return self.request( + method="GET", + path=path, + query=query, + params=params, + timeout=timeout, + maxretries=maxretries, + ) + + def post(self, path, query = None, data=None, params=None, timeout=None, maxretries=None): + """Makes a POST request to the API""" + return self.request( + method="POST", + path=path, + query=query, + data=data, + params=params, + timeout=timeout, + maxretries=maxretries, + ) + + def patch(self, path, query = None, data=None, params=None, timeout=None, maxretries=None): + """Makes a PATCH request to the API""" + return self.request( + method="PATCH", + path=path, + query=query, + data=data, + params=params, + timeout=timeout, + maxretries=maxretries, + ) + + def put(self, path, query = None, data=None, params=None, timeout=None, maxretries=None): + """Makes a PUT request to the API""" + return self.request( + method="PUT", + path=path, + query=query, + data=data, + params=params, + timeout=timeout, + maxretries=maxretries, + ) + + def delete(self, path, query = None, params=None, timeout=None, maxretries=None): + """Makes a DELETE request to the API""" + return self.request( + method="DELETE", + path=path, + query=query, + params=params, + timeout=timeout, + maxretries=maxretries, + ) \ No newline at end of file diff --git a/openpix/resources/__init__.py b/openpix/resources/__init__.py new file mode 100644 index 0000000..2c00afe --- /dev/null +++ b/openpix/resources/__init__.py @@ -0,0 +1,36 @@ +""" +Module: resources/__init__.py +""" +from openpix.http.http_client import HttpClient + +from openpix.resources.account import Account +from openpix.resources.cashback_fidelity import CashbackFidelity +from openpix.resources.charge_refund import ChargeRefund +from openpix.resources.charge import Charge +from openpix.resources.customer import Customer +from openpix.resources.partner import Partner +from openpix.resources.payment import Payment +from openpix.resources.pix_qr_code import PixQrCode +from openpix.resources.refund import Refund +from openpix.resources.sub_account import SubAccount +from openpix.resources.subscription import Subscription +from openpix.resources.transactions import Transactions +from openpix.resources.transfer import Transfer +from openpix.resources.webhook import Webhook + +__all__ = ( + 'Account', + 'CashbackFidelity', + 'ChargeRefund', + 'Charge', + 'Customer', + 'Partner', + 'Payment', + 'PixQrCode', + 'Refund', + 'SubAccount', + 'Subscription', + 'Transactions', + 'Transfer', + 'Webhook' +) \ No newline at end of file diff --git a/openpix/resources/account.py b/openpix/resources/account.py new file mode 100644 index 0000000..1f9a985 --- /dev/null +++ b/openpix/resources/account.py @@ -0,0 +1,41 @@ +""" + Module: account +""" +from openpix.http import HttpClient +import openpix.resources.account_types as account_types +from openpix.types import PagePayload + +class Account: + """ + Access to Accounts + + [Click here for more info](https://developers.woovi.com/api#tag/account) # pylint: disable=line-too-long + """ + def __init__(self, HttpClient: HttpClient): + self._client = HttpClient + + """Get one account. + Args: + accountId (str): the account unique identifier + [Click here for more info](https://developers.woovi.com/api#tag/account) + """ + def get(self, accountId: str) -> account_types.AccountInfo: + return self._client.get(path=f'/api/v1/account/{accountId}') + + """Get a list of accounts. + Args: + limit (int): number of content per page + skip (int): number of how many contents will be ignored + [Click here for more info](https://developers.woovi.com/api#tag/account/paths/~1api~1v1~1account~1/get) + """ + def list(self, page: PagePayload = PagePayload()) -> account_types.AccountList: + return self._client.get(path=f'/api/v1/account', query={"limit": page.limit, "skip": page.skip}) + + """Make a withdraw. + Args: + accountId (str): the account unique identifier + value (int): the value for the withdraw + [Click here for more info](https://developers.woovi.com/api#tag/account/paths/~1api~1v1~1account~1%7BaccountId%7D~1withdraw/post) + """ + def withdraw(self, accountId: str, value: int) -> account_types.AccountWithdraw: + return self._client.post(path=f'/api/v1/account/{accountId}', data={value: value}) \ No newline at end of file diff --git a/openpix/resources/account_types.py b/openpix/resources/account_types.py new file mode 100644 index 0000000..467b37e --- /dev/null +++ b/openpix/resources/account_types.py @@ -0,0 +1,38 @@ +from openpix.types import PageInfo +from typing import List + +class BalanceInfo: + def __init__(self, total: int, blocked: int, available: int): + self.total = total + self.blocked = blocked + self.available = available + +class AccountInfo: + def __init__(self, accountId: str, isDefault: bool, balance: BalanceInfo): + self.accountId = accountId + self.balance = balance + self.isDefault = isDefault + +class TransactionInfo: + def __init__(self, endToEndId: str, value: int): + self.endToEndId = endToEndId + self.value = value + +class WithdrawInfo: + def __init__(self, account: AccountInfo, transaction: TransactionInfo): + self.account = account + self.transaction = transaction + +class AccountGet: + def __init__(self, account: AccountInfo): + self.account = account + + +class AccountList: + def __init__(self, pageInfo: PageInfo, accounts: List[AccountInfo]): + self.pageInfo = pageInfo + self.accounts = accounts + +class AccountWithdraw: + def __init__(self, withdraw: WithdrawInfo): + self.withdraw = withdraw \ No newline at end of file diff --git a/openpix/resources/cashback_fidelity.py b/openpix/resources/cashback_fidelity.py new file mode 100644 index 0000000..597ad5b --- /dev/null +++ b/openpix/resources/cashback_fidelity.py @@ -0,0 +1,31 @@ +""" + Module: cashback_fidelity +""" +from openpix.http import HttpClient +import openpix.resources.cashback_fidelity_types as cashback_fidelity_types + +class CashbackFidelity: + """ + Access to CashbackFidelity + + [Click here for more info](https://developers.woovi.com/api#tag/cashback-fidelity) # pylint: disable=line-too-long + """ + def __init__(self, HttpClient: HttpClient): + self._client = HttpClient + + """Get one fidelity. + Args: + taxID (str): the user's tax id document + [Click here for m ore info](https://developers.woovi.com/api#tag/cashback-fidelity/paths/~1api~1v1~1cashback-fidelity~1balance~1%7BtaxID%7D/get) + """ + def get(self, taxID: str) -> cashback_fidelity_types.CashbackGet: + return self._client.get(path=f'/api/v1/cashback-fidelity/balance/{taxID}') + + """Create one fidelity. + Args: + taxID (str): the user's tax id document + value (int): the fidelity value + [Click here for more info](https://developers.woovi.com/api#tag/cashback-fidelity/paths/~1api~1v1~1cashback-fidelity/post) + """ + def create(self, taxID: str, value: int) -> cashback_fidelity_types.CashbackCreate: + return self._client.post(path=f'/api/v1/cashback-fidelity', data={value: value, taxID: taxID}) \ No newline at end of file diff --git a/openpix/resources/cashback_fidelity_types.py b/openpix/resources/cashback_fidelity_types.py new file mode 100644 index 0000000..55a8481 --- /dev/null +++ b/openpix/resources/cashback_fidelity_types.py @@ -0,0 +1,13 @@ +class CashbackInfo: + def __init__(self, value: int): + self.value: value + +class CashbackGet: + def __init__(self, balance: int, status: str): + self.balance = balance + self.status = status + +class CashbackCreate: + def __init__(self, cashback: CashbackInfo, message: str): + self.cashback = cashback + self.message = message \ No newline at end of file diff --git a/openpix/resources/charge.py b/openpix/resources/charge.py new file mode 100644 index 0000000..5569f8a --- /dev/null +++ b/openpix/resources/charge.py @@ -0,0 +1,103 @@ +""" + Module: charge +""" +from openpix.http import HttpClient +import openpix.resources.charge_types as charge_types +from typing import List, Optional +from openpix.types import PagePayload + +class Charge: + """ + Access to Charge + + [Click here for more info](https://developers.woovi.com/api#tag/charge) # pylint: disable=line-too-long + """ + def __init__(self, HttpClient: HttpClient): + self._client = HttpClient + + """Get a charge + Args: + id (str): charge ID or correlation ID. + [Click here for more info](https://developers.woovi.com/api#tag/charge/paths/~1api~1v1~1charge~1%7Bid%7D/delete) + """ + def get(self, id: str) -> charge_types.ChargeGet: + return self._client.get(path=f'/api/v1/charge/{id}') + + """Get a list of charges. + Args: + start (str): Start date used in the query. Complies with RFC 3339.. + end (str): End date used in the query. Complies with RFC 3339. + status (str): Enum: "ACTIVE" "COMPLETED" "EXPIRED" + customer (str): Customer Correlation ID + limit (int): number of content per page + skip (int): number of how many contents will be ignored + [Click here for more info](https://developers.woovi.com/api#tag/charge/paths/~1api~1v1~1charge/get) + """ + def list(self, start: str = None, end: str = None, status: str = None, customer: str = None, page: PagePayload = PagePayload()) -> charge_types.ChargeList: + return self._client.get(path=f'/api/v1/charge/', query={"limit": page.limit, "skip": page.skip, start: start, end: end, status: status, customer: customer}) + + """Delete one charge request + Args: + id (str): charge ID or correlation ID. + [Click here for more info](https://developers.woovi.com/api#tag/charge/paths/~1api~1v1~1charge~1%7Bid%7D/delete) + """ + def delete(self, id:str) -> charge_types.ChargeDelete: + return self._client.delete(path=f'/api/v1/charge/{id}') + + """create a charge + Args: + return_existing (bool, optional): Make the endpoint idempotent, will return an existent charge if already has a one with the correlationID. + + correlationID (str): Your correlation ID to keep track of this charge. + value (int): Value in cents of this charge. + type (str, optional): Charge type. Enum: "DYNAMIC" "OVERDUE". Determines whether a charge will have a deadline, fines, and interests. + comment (str, optional): Comment to be added in infoPagador. + identifier (str, optional): Custom identifier for EMV. + expiresIn (int, optional): Expires the charge in seconds (minimum is 15 minutes). + expiresDate (str, optional): Expiration date of the charge. Only in ISO 8601 format. + customer (CustomerPayload, optional): Customer information. + daysForDueDate (int, optional): Time in days until the charge hits the deadline so fines and interests start applying. Only considered for charges of type OVERDUE. + daysAfterDueDate (int, optional): Time in days that a charge is still payable after the deadline. Only considered for charges of type OVERDUE. + interests (Interests, optional): Interests configuration. Only considered for charges of type OVERDUE. + fines (Fines, optional): Fines configuration. Only considered for charges of type OVERDUE. + discountSettings (dict, optional): Discount settings for the charge. Only considered for charges of type OVERDUE. + additionalInfo (List[AdditionalInfoItem], optional): Additional info of the charge. + enableCashbackPercentage (bool, optional): True to enable cashback and false to disable. + enableCashbackExclusivePercentage (bool, optional): True to enable fidelity cashback and false to disable. + [Click here for more info](https://developers.woovi.com/api#tag/charge/paths/~1api~1v1~1charge/post) + """ + def create(self, return_existing: bool = True, correlationID: str = "", value: int = 0, type: Optional[str] = None, comment: Optional[str] = None, + identifier: Optional[str] = None, expiresIn: Optional[int] = None, expiresDate: Optional[str] = None, + customer: Optional[charge_types.CustomerPayload] = None, daysForDueDate: Optional[int] = None, + daysAfterDueDate: Optional[int] = None, interests: Optional[charge_types.Interests] = None, + fines: Optional[charge_types.Fines] = None, discountSettings: Optional[dict] = None, + additionalInfo: Optional[List[charge_types.AdditionalInfoItem]] = None, enableCashbackPercentage: Optional[bool] = None, + enableCashbackExclusivePercentage: Optional[bool] = None) -> charge_types.ChargeCreate: + return self._client.post(path=f'/api/v1/charge/', query={"return_existing": return_existing}, data={ + correlationID: correlationID, + value: value, + type: type, + comment: comment, + identifier: identifier, + expiresIn: expiresIn, + expiresDate: expiresDate, + customer: customer, + daysAfterDueDate: daysAfterDueDate, + daysForDueDate: daysForDueDate, + fines: fines, + interests: interests, + discountSettings: discountSettings, + additionalInfo: additionalInfo, + enableCashbackExclusivePercentage: enableCashbackExclusivePercentage, + enableCashbackPercentage: enableCashbackPercentage + }) + + + """Get the qr code from a charge + Args: + id (str): charge link payment ID. + size (int): Size for the image. This size should be between 600 and 4096. if the size parameter was not passed, the default value will be 1024. + [Click here for more info](https://developers.woovi.com/api#tag/charge/paths/~1openpix~1charge~1brcode~1image~1%7B:id%7D.png?size=1024/get) + """ + def getQrImage(self, id: str, size: int = 1024) -> str: + return f'https://api.woovi.com/openpix/charge/brcode/image/{id}.png?size={size}' \ No newline at end of file diff --git a/openpix/resources/charge_refund.py b/openpix/resources/charge_refund.py new file mode 100644 index 0000000..7ac330b --- /dev/null +++ b/openpix/resources/charge_refund.py @@ -0,0 +1,36 @@ +""" + Module: charge_refund +""" +from openpix.http import HttpClient +import openpix.resources.charge_refund_types as charge_refund_types +from openpix.types import PagePayload + +class ChargeRefund: + """ + Access to ChargeRefund + + [Click here for more info](https://developers.woovi.com/api#tag/charge-refund) # pylint: disable=line-too-long + """ + def __init__(self, HttpClient: HttpClient): + self._client = HttpClient + + """Get a list of charge refunds. + Args: + id (str): The correlation ID of the charge. + limit (int): number of content per page + skip (int): number of how many contents will be ignored + [Click here for more info](https://developers.woovi.com/api#tag/charge-refund/paths/~1api~1v1~1charge~1%7Bid%7D~1refund/get) + """ + def list(self, id: str, page: PagePayload = PagePayload()) -> charge_refund_types.ChargeRefundList: + return self._client.get(path=f'/api/v1/charge/{id}/refund', query={"limit": page.limit, "skip": page.skip}) + + """Create a new refund for a charge + Args: + id (str): The correlation ID of the charge. + correlationID (str): Your correlation ID to keep track for this refund + value (int): Value in cents for this refund + comment (str): Comment for this refund. Maximum length of 140 characters. + [Click here for more info](https://developers.woovi.com/api#tag/charge-refund/paths/~1api~1v1~1charge~1%7Bid%7D~1refund/post) + """ + def create(self, id: str, correlationID: str, value: int, comment: str) -> charge_refund_types.ChargeRefundCreate: + return self._client.post(path=f'/api/v1/charge/{id}/refund', data={value: value, correlationID: correlationID, comment: comment}) \ No newline at end of file diff --git a/openpix/resources/charge_refund_types.py b/openpix/resources/charge_refund_types.py new file mode 100644 index 0000000..63bb97a --- /dev/null +++ b/openpix/resources/charge_refund_types.py @@ -0,0 +1,28 @@ +from openpix.types import PageInfo +from typing import List + +class ChargeRefund: + def __init__(self, status: str, value: int, correlationID: str, endToEndId: str, time: str): + self.status = status + self.value = value + self.correlationID = correlationID + self.endToEndId = endToEndId + self.time = time + +class ChargeRefundCreate: + def __init__(self, status: str, value: int, correlationID: str, endToEndId: str, time: str, comment: str): + self.status = status + self.value = value + self.correlationID = correlationID + self.endToEndId = endToEndId + self.time = time + self.comment = comment + +class ChargeRefundList: + def __init__(self, pageInfo: PageInfo, refunds: List[ChargeRefund]): + self.pageInfo = pageInfo + self.refunds = refunds + +class ChargeRefundCreate: + def __init__(self, refund: ChargeRefundCreate): + self.refund = refund \ No newline at end of file diff --git a/openpix/resources/charge_types.py b/openpix/resources/charge_types.py new file mode 100644 index 0000000..6ff1e23 --- /dev/null +++ b/openpix/resources/charge_types.py @@ -0,0 +1,145 @@ +from openpix.types import PageInfo +from typing import List, Union, Optional + +class ChargeDelete: + def __init__(self, status: str, id: str): + self.status = status + self.id = id + +class CustomerPayload: + def __init__(self, name: str, taxID: Optional[str] = None, email: Optional[str] = None, phone: Optional[str] = None): + self.name = name + self.taxID = taxID + self.email = email + self.phone = phone + +class Interests: + def __init__(self, value: int): + self.value = value + +class Fines: + def __init__(self, value: int): + self.value = value + +class DiscountFixedDate: + def __init__(self, daysActive: int, value: int): + self.daysActive = daysActive + self.value = value + + +class DiscountSettings: + def __init__(self, modality: str, discountFixedDate: DiscountFixedDate): + self.modality = modality + self.discountFixedDate = discountFixedDate + +class AdditionalInfoItem: + def __init__(self, key: str, value: str): + self.key = key + self.value = value + +class ChargeCreate: + def __init__(self, correlationID: str, value: int, type: Optional[str] = None, comment: Optional[str] = None, + identifier: Optional[str] = None, expiresIn: Optional[int] = None, expiresDate: Optional[str] = None, + customer: Optional[CustomerPayload] = None, daysForDueDate: Optional[int] = None, + daysAfterDueDate: Optional[int] = None, interests: Optional[Interests] = None, + fines: Optional[Fines] = None, discountSettings: Optional[DiscountSettings] = None, + additionalInfo: Optional[List[AdditionalInfoItem]] = None, enableCashbackPercentage: Optional[bool] = None, + enableCashbackExclusivePercentage: Optional[bool] = None): + self.correlationID = correlationID + self.value = value + self.type = type + self.comment = comment + self.identifier = identifier + self.expiresIn = expiresIn + self.expiresDate = expiresDate + self.customer = customer + self.daysForDueDate = daysForDueDate + self.daysAfterDueDate = daysAfterDueDate + self.interests = interests + self.fines = fines + self.discountSettings = discountSettings + self.additionalInfo = additionalInfo + self.enableCashbackPercentage = enableCashbackPercentage + self.enableCashbackExclusivePercentage = enableCashbackExclusivePercentage + +class TaxID: + def __init__(self, taxID: str, type: str): + self.taxID = taxID + self.type = type + +class Address: + def __init__(self, zipcode: str, street: str, number: str, neighborhood: str, city: str, state: str, complement: str, country: str): + self.zipcode = zipcode + self.street = street + self.number = number + self.neighborhood = neighborhood + self.city = city + self.state = state + self.complement = complement + self.country = country + +class Customer: + def __init__(self, name: str, email: str, phone: str, taxID: TaxID, correlationID: str, address: Address): + self.name = name + self.email = email + self.phone = phone + self.taxID = taxID + self.correlationID = correlationID + self.address = address + +class AdditionalInfoItem: + def __init__(self, key: str, value: str): + self.key = key + self.value = value + +class Charge: + def __init__(self, value: int, customer: Customer, comment: str, brCode: str, status: str, + correlationID: str, paymentLinkID: str, paymentLinkUrl: str, globalID: str, + transactionID: str, identifier: str, qrCodeImage: str, additionalInfo: List[AdditionalInfoItem], + pixKey: str, createdAt: str, updatedAt: str, expiresIn: str): + self.value = value + self.customer = customer + self.comment = comment + self.brCode = brCode + self.status = status + self.correlationID = correlationID + self.paymentLinkID = paymentLinkID + self.paymentLinkUrl = paymentLinkUrl + self.globalID = globalID + self.transactionID = transactionID + self.identifier = identifier + self.qrCodeImage = qrCodeImage + self.additionalInfo = additionalInfo + self.pixKey = pixKey + self.createdAt = createdAt + self.updatedAt = updatedAt + self.expiresIn = expiresIn + +class EasyCharge: + def __init__(self, value: int, customer: Customer, comment: str, brCode: str, status: str, + correlationID: str, paymentLinkID: str, paymentLinkUrl: str, qrCodeImage: str, additionalInfo: List[AdditionalInfoItem], createdAt: str, updatedAt: str, expiresIn: str, expiresDate: str): + self.status = status + self.value = value + self.customer = customer + self.comment = comment + self.paymentLinkID = paymentLinkID + self.correlationID = correlationID + self.paymentLinkUrl = paymentLinkUrl + self.qrCodeImage = qrCodeImage + self.brCode = brCode + self.additionalInfo = additionalInfo + + self.expiresDate = expiresDate + self.createdAt = createdAt + self.updatedAt = updatedAt + self.expiresIn = expiresIn + + +class ChargeGet: + def __init__(self, charge: Charge): + self.charge = charge + +class ChargeList: + def __init__(self, pageInfo: PageInfo, charges: List[EasyCharge]): + self.pageInfo = pageInfo + self.charges = charges \ No newline at end of file diff --git a/openpix/resources/customer.py b/openpix/resources/customer.py new file mode 100644 index 0000000..e222d9d --- /dev/null +++ b/openpix/resources/customer.py @@ -0,0 +1,108 @@ +""" + Module: customer +""" +from openpix.http import HttpClient +from openpix.types import PagePayload +import openpix.resources.customer_types as customer_types + +class Customer: + """ + Access to Customer + + [Click here for more info](https://developers.woovi.com/api#tag/customer) # pylint: disable=line-too-long + """ + def __init__(self, HttpClient: HttpClient): + self._client = HttpClient + + """get a customer + Args: + id (str): identifier of your customer. + + [Click here for more info](https://developers.openpix.com.br/api#tag/customer/paths/~1api~1v1~1customer~1%7Bid%7D/get) + """ + def get(self, id: str) -> customer_types.CustomerGet: + return self._client.get(path=f'/api/v1/customer/{id}') + + """list customers + Args: + page (PageInfo): A class for page info object containing limit and skip + + [Click here for more info](https://developers.openpix.com.br/api#tag/customer/paths/~1api~1v1~1customer~1%7Bid%7D/get) + """ + def list(self, page: PagePayload = PagePayload()) -> customer_types.CustomerList: + return self._client.get(path=f'/api/v1/customer', query={"limit": page.limit, "skip": page.skip}) + + """create a customer + Args: + name (str): name of the customer. + email (str): email of the customer. + phone (str): phone number of your customer. + taxID (str): personal document of your customer. + correlationID (str): Your correlation ID, unique identifier refund. + address (Address): + - zipcode: string + - street: string + - number: string + - neighborhood: string + - city: string + - state: string + - complement: string + - country: string + + [Click here for more info](https://developers.openpix.com.br/api#tag/customer/paths/~1api~1v1~1customer/post) + """ + def create(self, name: str, email: str, phone: str, taxID: str, address: customer_types.Address) -> customer_types.CustomerCreate: + return self._client.post(path=f'/api/v1/customer', data={ + 'name': name, + 'phone': phone, + 'taxID': taxID, + 'email': email, + 'address': { + 'zipcode': address.zipcode, + 'street': address.street, + 'number': address.number, + 'neighborhood': address.neighborhood, + 'city': address.city, + 'state': address.state, + 'complement': address.complement, + 'country': address.country, + } + }) + + """update a customer + Args: + correlationID (str): Your correlation ID, unique identifier refund. + name (str): name of the customer. + email (str): email of the customer. + phone (str): phone number of your customer. + taxID (str): personal document of your customer. + address (Address): + - zipcode: string + - street: string + - number: string + - neighborhood: string + - city: string + - state: string + - complement: string + - country: string + + [Click here for more info](https://developers.openpix.com.br/api#tag/customer/paths/~1api~1v1~1customer/post) + """ + def update(self, correlationID: str, name: str, email: str, phone: str, taxID: str, address: customer_types.Address) -> customer_types.CustomerUpdate: + return self._client.patch(path=f'/api/v1/customer/{correlationID}', data={ + 'name': name, + 'phone': phone, + 'taxID': taxID, + 'email': email, + 'address': { + 'zipcode': address.zipcode, + 'street': address.street, + 'number': address.number, + 'neighborhood': address.neighborhood, + 'city': address.city, + 'state': address.state, + 'complement': address.complement, + 'country': address.country, + } + }) + \ No newline at end of file diff --git a/openpix/resources/customer_types.py b/openpix/resources/customer_types.py new file mode 100644 index 0000000..e1aa38c --- /dev/null +++ b/openpix/resources/customer_types.py @@ -0,0 +1,44 @@ +from openpix.types import PageInfo +from typing import List + +class TaxID: + def __init__(self, taxID: str, type: str): + self.taxID = taxID + self.type = type + +class Address: + def __init__(self, zipcode: str, street: str, number: str, neighborhood: str, city: str, state: str, complement: str, country: str): + self.zipcode = zipcode + self.street = street + self.number = number + self.neighborhood = neighborhood + self.city = city + self.state = state + self.complement = complement + self.country = country + +class Customer: + def __init__(self, name: str, email: str, phone: str, taxID: TaxID, correlationID: str, address: Address): + self.name = name + self.email = email + self.phone = phone + self.taxID = taxID + self.correlationID = correlationID + self.address = address + +class CustomerGet: + def __init__(self, customer: Customer): + self.customer = customer + +class CustomerUpdate: + def __init__(self, customer: Customer): + self.customer = customer + +class CustomerCreate: + def __init__(self, customer: Customer): + self.customer = customer + +class CustomerList: + def __init__(self, pageInfo: PageInfo, customers: List[Customer]): + self.pageInfo = pageInfo + self.customers = customers diff --git a/openpix/resources/partner.py b/openpix/resources/partner.py new file mode 100644 index 0000000..73cefb8 --- /dev/null +++ b/openpix/resources/partner.py @@ -0,0 +1,93 @@ +""" + Module: partner +""" +from openpix.http import HttpClient +import openpix.resources.partner_types as partner_types +from openpix.types import PagePayload + +class Partner: + """ + Access to Partner + + [Click here for more info](https://developers.woovi.com/api#tag/partner-(request-access)) # pylint: disable=line-too-long + """ + def __init__(self, HttpClient: HttpClient): + self._client = HttpClient + + """Get an specific preregistration via taxID param. + Args: + taxID (str): The raw tax ID from the preregistration that you want to get + + [Click here for more info](https://developers.openpix.com.br/api#tag/partner-(request-access)/paths/~1api~1v1~1partner~1company~1%7BtaxID%7D/get) + """ + def get(self, taxID: str) -> partner_types.PartnerGet: + return self._client.get(path=f'/api/v1/partner/company/{taxID}') + + """Get every preregistration that is managed by you. + Args: + page (PageInfo): A class for page info object containing limit and skip + + [Click here for more info](https://developers.openpix.com.br/api#tag/partner-(request-access)/paths/~1api~1v1~1partner~1company/get) + """ + def list(self, page: PagePayload = PagePayload()) -> partner_types.PartnerList: + return self._client.get(path=f'/api/v1/partner/company', query={"limit": page.limit, "skip": page.skip}) + + """Create a pre registration with a partner reference (your company) + Args: + preRegistration (preRegistration): + - name: str + - website: str + - taxID: + - taxID: str + - type: str + + user (user): + - firstName: str + - lastName: str + - email: str + - phone: str + + [Click here for more info](https://developers.openpix.com.br/api#tag/partner-(request-access)/paths/~1api~1v1~1partner~1company/post) + """ + def createPreRegistration(self, preRegistration: partner_types.PreRegistrationCreate, user: partner_types.PreRegistrationUserObject): + return self._client.post(path=f'/api/v1/partner/company', data={ + "preRegistration": { + "name": preRegistration.name, + "taxID": { + "taxID": preRegistration.taxID.taxID, + "type": preRegistration.taxID.type + }, + "website": preRegistration.website + }, + "user": { + "firstName": user.firstName, + "lastName": user.lastName, + "email": user.email, + "phone": user.phone + } + }) + + """Create a new application to some of your preregistration's company. + Args: + application (application): + - name: str + - type: str + + taxID (taxID): + - taxID: str + - type: str + + [Click here for more info](https://developers.openpix.com.br/api#tag/partner-(request-access)/paths/~1api~1v1~1partner~1application/post) + """ + def createApplication(self, application: partner_types.Application, taxID: partner_types.TaxId): + return self._client.post(path=f'/api/v1/partner/application', data={ + "application": { + "name": application.name, + "type": application.type + }, + "taxID": { + "taxID": taxID.taxID, + "type": taxID.type + + } + }) \ No newline at end of file diff --git a/openpix/resources/partner_types.py b/openpix/resources/partner_types.py new file mode 100644 index 0000000..1dd4865 --- /dev/null +++ b/openpix/resources/partner_types.py @@ -0,0 +1,66 @@ +from openpix.types import PageInfo +from typing import List + +class TaxIDObjectPayload: + def __init__(self, taxID: str, type: str): + self.taxID = taxID + self.type = type + +class PreRegistrationUserObject: + def __init__(self, firstName: str, lastName: str, email: str, phone: str): + self.firstName = firstName + self.lastName = lastName + self.email = email + self.phone = phone + +class CompanyObjectPayload: + def __init__(self, id: str, name: str, taxID: TaxIDObjectPayload): + self.id = id + self.name = name + self.taxID = taxID + +class AccountObjectPayload: + def __init__(self, clientId: str): + self.clientId = clientId + +class PreRegistrationObjectPayload: + def __init__(self, name: str, taxID: TaxIDObjectPayload, user: PreRegistrationUserObject, + company: CompanyObjectPayload, account: AccountObjectPayload): + self.name = name + self.taxID = taxID + self.user = user + self.company = company + self.account = account + +class Application: + def __init__(self, name: str, type: str): + self.name = name + self.type = type + + +class TaxId: + def __init__(self, taxID: str, type: str): + self.taxID = taxID + self.type = type + +class PreRegistrationCreate: + def __init__(self, name: str, website: str, taxID: TaxId): + self.name = name + self.taxID = taxID + self.website = website + +class PreRegistration: + def __init__(self, preRegistration: PreRegistrationObjectPayload, user: PreRegistrationUserObject, company: CompanyObjectPayload, account: AccountObjectPayload): + self.preRegistration = preRegistration + self.user = user + self.company = company + account = account + +class PartnerGet: + def __init__(self, preRegistration: PreRegistration): + self.preRegistration = preRegistration + +class PartnerList: + def __init__(self, pageInfo: PageInfo, preRegistrations: List[PreRegistration]): + self.pageInfo = pageInfo + self.preRegistrations = preRegistrations diff --git a/openpix/resources/payment.py b/openpix/resources/payment.py new file mode 100644 index 0000000..d764765 --- /dev/null +++ b/openpix/resources/payment.py @@ -0,0 +1,65 @@ +""" + Module: payment +""" +from openpix.http import HttpClient +import openpix.resources.payment_types as payment_types +from openpix.types import PagePayload + +class Payment: + """ + Access to Payment + + [Click here for more info](https://developers.woovi.com/api#tag/payment-(request-access)) # pylint: disable=line-too-long + """ + def __init__(self, HttpClient: HttpClient): + self._client = HttpClient + + """get a payment + Args: + id (str): identifier of your payment. + + [Click here for more info](https://developers.openpix.com.br/api#tag/payment-(request-access)/paths/~1api~1v1~1payment~1%7Bid%7D/get) + """ + def get(self, id: str) -> payment_types.PaymentGet: + return self._client.get(path=f'/api/v1/payment/{id}') + + """list payments + Args: + page (PageInfo): A class for page info object containing limit and skip + + [Click here for more info](https://developers.openpix.com.br/api#tag/payment-(request-access)/paths/~1api~1v1~1payment~1%7Bid%7D/get) + """ + def list(self, page: PagePayload = PagePayload()) -> payment_types.PaymentList: + return self._client.get(path=f'/api/v1/payment', query={"limit": page.limit, "skip": page.skip}) + + """approve a payment + Args: + correlationID (str): the correlation ID of the payment to be approved + + [Click here for more info](https://developers.openpix.com.br/api#tag/payment-(request-access)/paths/~1api~1v1~1payment~1approve/post) + """ + def approve(self, correlationID: str) -> payment_types.PaymentApprove: + return self._client.post(path=f'/api/v1/payment/approve', data={ + "correlationID": correlationID + }) + + """create a payment + Args: + To a pix key: + value (int): value of the requested payment in cents + destinationAlias (str): the pix key the payment should be sent to + destinationAliasType (str): the type of the pix key the payment should be sent to + correlationID (str): an unique identifier for your payment + comment (str): the comment that will be send alongisde your payment + sourceAccountId (str): an optional id for the source account of the payment, if not informed will assume the default account + + To a qr code: + qrCode (int): the QR Code to be paid + correlationID (str): an unique identifier for your payment + comment (str): the comment that will be send alongisde your payment + sourceAccountId (str): an optional id for the source account of the payment, if not informed will assume the default account + + [Click here for more info](https://developers.openpix.com.br/api#tag/payment-(request-access)/paths/~1api~1v1~1payment/post) + """ + def create(self, payload) -> payment_types.PaymentCreate: + return self._client.post(path=f'/api/v1/payment', data=payload) \ No newline at end of file diff --git a/openpix/resources/payment_types.py b/openpix/resources/payment_types.py new file mode 100644 index 0000000..018fda9 --- /dev/null +++ b/openpix/resources/payment_types.py @@ -0,0 +1,52 @@ +from openpix.types import PageInfo +from typing import List + +class PaymentDestination: + def __init__(self, name: str, taxID: str, pixKey: str, bank: str, branch: str, account: str): + self.name = name + self.taxID = taxID + self.pixKey = pixKey + self.bank = bank + self.branch = branch + self.account = account + +class PaymentTransaction: + def __init__(self, value: int, endToEndId: str, time: str): + self.value = value + self.endToEndId = endToEndId + self.time = time + +class Payment: + def __init__(self, value: int, destinationAlias: str, destinationAliasType: str, qrCode: str, correlationID: str, + comment: str, status: str, sourceAccountId: str, transaction: PaymentTransaction, destination: PaymentDestination): + self.value = value + self.destinationAlias = destinationAlias + self.destinationAliasType = destinationAliasType + self.qrCode = qrCode + self.correlationID = correlationID + self.comment = comment + self.status = status + self.sourceAccountId = sourceAccountId + self.transaction = transaction + self.destination = destination + +class PaymentGet: + def __init__(self, payment: Payment, transaction: PaymentTransaction, destination: PaymentDestination): + self.payment = payment + self.transaction = transaction + self.destination = destination + +class PaymentList: + def __init__(self, pageInfo: PageInfo, payments: List[PaymentGet]): + self.pageInfo = pageInfo + self.payments = payments + +class PaymentApprove: + def __init__(self, payment: Payment, transaction: PaymentTransaction, destination: PaymentDestination): + self.payment = payment + self.transaction = transaction + self.destination = destination + +class PaymentCreate: + def __init__(self, payment: Payment): + self.payment = payment \ No newline at end of file diff --git a/openpix/resources/pix_qr_code.py b/openpix/resources/pix_qr_code.py new file mode 100644 index 0000000..ea8df78 --- /dev/null +++ b/openpix/resources/pix_qr_code.py @@ -0,0 +1,50 @@ +""" + Module: pix-qr-code +""" +from openpix.http import HttpClient +import openpix.resources.pix_qr_code_types as pix_qr_code_types +from openpix.types import PagePayload + +class PixQrCode(): + """ + Access to PixQrCode + + [Click here for more info](https://developers.woovi.com/api#tag/pixQrCode) # pylint: disable=line-too-long + """ + def __init__(self, HttpClient: HttpClient): + self._client = HttpClient + + """Get one Pix QrCode. + Args: + id (str): pixQrCode ID, correlation ID or emv identifier. + + [Click here for more info](https://developers.openpix.com.br/api#tag/pixQrCode/paths/~1api~1v1~1qrcode-static~1%7Bid%7D/get) + """ + def get(self, id: str) -> pix_qr_code_types.PixQrCodeList: + return self._client.get(path=f'/api/v1/qrcode-static/{id}') + + """Get a list of Pix QrCodes. + Args: + page (PageInfo): A class for page info object containing limit and skip + + [Click here for more info](https://developers.openpix.com.br/api#tag/pixQrCode/paths/~1api~1v1~1qrcode-static/get) + """ + def list(self, page: PagePayload = PagePayload()) -> pix_qr_code_types.PixQrCodeList: + return self._client.get(path=f'/api/v1/partner/qrcode-static', query={"limit": page.limit, "skip": page.skip}) + + """Create a new Pix QrCode Static + Args: + name (str): Name of this pix qrcode + correlationID (str): Your correlation ID to keep track of this qrcode + value (int): Value in cents of this qrcode + comment (str): Comment to be added in infoPagador + + [Click here for more info](https://developers.openpix.com.br/api#tag/pixQrCode/paths/~1api~1v1~1qrcode-static/post) + """ + def create(self, name: str, correlationID: str, value: int, comment: str) -> pix_qr_code_types.PixQrCodeCreate: + return self._client.post(path=f'/api/v1/partner/qrcode-static', data={ + "name": name, + "correlationID": correlationID, + "value": value, + "comment": comment + }) \ No newline at end of file diff --git a/openpix/resources/pix_qr_code_types.py b/openpix/resources/pix_qr_code_types.py new file mode 100644 index 0000000..5c4b5ab --- /dev/null +++ b/openpix/resources/pix_qr_code_types.py @@ -0,0 +1,30 @@ +from openpix.types import PageInfo +from typing import List + +class PixQrCode: + def __init__(self, name: str, value: str, comment: str, brCode: str, correlationID: str, + paymentLinkID: str, paymentLinkUrl: str, qrCodeImage: str, createdAt: str, updatedAt: str): + self.name = name + self.value = value + self.comment = comment + self.brCode = brCode + self.correlationID = correlationID + self.paymentLinkID = paymentLinkID + self.paymentLinkUrl = paymentLinkUrl + self.qrCodeImage = qrCodeImage + self.createdAt = createdAt + self.updatedAt = updatedAt + + +class PixQrCodeGet: + def __init__(self, pixQrCode: PixQrCode): + self.pixQrCode = pixQrCode + +class PixQrCodeList: + def __init__(self, pageInfo: PageInfo, pixQrCodes: List[PixQrCode]): + self.pageInfo = pageInfo + self.pixQrCodes = pixQrCodes + +class PixQrCodeCreate: + def __init__(self, pixQrCode: PixQrCode): + self.pixQrCode = pixQrCode diff --git a/openpix/resources/refund.py b/openpix/resources/refund.py new file mode 100644 index 0000000..4be66b0 --- /dev/null +++ b/openpix/resources/refund.py @@ -0,0 +1,50 @@ +""" + Module: refund +""" +from openpix.http import HttpClient +import openpix.resources.refund_types as refund_types +from openpix.types import PagePayload + +class Refund: + """ + Access to Refund + + [Click here for more info](https://developers.woovi.com/api#tag/refund) # pylint: disable=line-too-long + """ + def __init__(self, HttpClient: HttpClient): + self._client = HttpClient + + """get a refund + Args: + id (str): identifier of your refund. + + [Click here for more info](https://developers.openpix.com.br/api#tag/refund/paths/~1api~1v1~1refund~1%7Bid%7D/get) + """ + def get(self, id: str) -> refund_types.RefundGet: + return self._client.get(path=f'/api/v1/refund/{id}') + + """list refunds + Args: + page (PageInfo): A class for page info object containing limit and skip + + [Click here for more info](https://developers.openpix.com.br/api#tag/refund/paths/~1api~1v1~1refund/get) + """ + def list(self, page: PagePayload = PagePayload()) -> refund_types.RefundList: + return self._client.get(path=f'/api/v1/refund', query={"limit": page.limit, "skip": page.skip}) + + """create a refund + Args: + value (int): value of the refund. + transactionEndToEndId (str): Your transaction ID, or endToEnd ID, to keep track of this refund + correlationID (str): Your correlation ID, unique identifier refund + comment (str): Comment of this refund. Maximum length of 140 characters. + + [Click here for more info](https://developers.openpix.com.br/api#tag/refund/paths/~1api~1v1~1refund/post) + """ + def create(self, value: int, transactionEndToEndId: str, correlationID: str, comment: str) -> refund_types.RefundCreate: + return self._client.post(path=f'/api/v1/refund', data={ + 'comment': comment, + 'correlationID': correlationID, + 'transactionEndToEndId': transactionEndToEndId, + 'value': value + }) \ No newline at end of file diff --git a/openpix/resources/refund_types.py b/openpix/resources/refund_types.py new file mode 100644 index 0000000..a1ce9f8 --- /dev/null +++ b/openpix/resources/refund_types.py @@ -0,0 +1,24 @@ +from openpix.types import PageInfo +from typing import List + +class Refund: + def __init__(self, value: int, status: str, correlationID: str, refundId: str, time: str, comment: str): + self.value = value + self.status = status + self.correlationID = correlationID + self.refundId = refundId + self.time = time + self.comment = comment + +class RefundGet: + def __init__(self, pixTransactionRefund: Refund): + self.pixTransactionRefund = pixTransactionRefund + +class RefundCreate: + def __init__(self, refund: Refund): + self.refund = refund + +class RefundList: + def __init__(self, pageInfo: PageInfo, refunds: List[Refund]): + self.pageInfo = pageInfo + self.refunds = refunds diff --git a/openpix/resources/sub_account.py b/openpix/resources/sub_account.py new file mode 100644 index 0000000..2b3daea --- /dev/null +++ b/openpix/resources/sub_account.py @@ -0,0 +1,76 @@ +""" + Module: sub-account +""" +from openpix.http import HttpClient +import openpix.resources.sub_account_types as sub_account_types +from openpix.types import PagePayload + +class SubAccount(): + """ + Access to SubAccount + + [Click here for more info](https://developers.woovi.com/api#tag/sub-account-(request-access)) # pylint: disable=line-too-long + """ + def __init__(self, HttpClient: HttpClient): + self._client = HttpClient + + """Get subaccount details + Args: + id (str): pix key registered to the subaccount + + [Click here for more info](https://developers.openpix.com.br/api#tag/sub-account-(request-access)/paths/~1api~1v1~1subaccount~1%7Bid%7D/get) + """ + def get(self, id: str) -> sub_account_types.SubAccountGet: + return self._client.get(path=f'/api/v1/subaccount/{id}') + + """Get a list of subaccounts + Args: + page (PageInfo): A class for page info object containing limit and skip + + [Click here for more info](https://developers.openpix.com.br/api#tag/sub-account-(request-access)/paths/~1api~1v1~1subaccount/get) + """ + def list(self, page: PagePayload = PagePayload()) -> sub_account_types.SubAccountList: + return self._client.get(path=f'/api/v1/subaccount', query={"limit": page.limit, "skip": page.skip}) + + """Create a subaccount + Args: + id (str): pix key registered to the subaccount + + [Click here for more info](https://developers.openpix.com.br/api#tag/sub-account-(request-access)/paths/~1api~1v1~1subaccount~1%7Bid%7D~1withdraw/post) + """ + def withdraw(self, id: str) -> sub_account_types.WithdrawCreate: + return self._client.post(path=f'/api/v1/subaccount/{id}/withdraw') + + """Create a subaccount + Args: + pixKey (str): The pix key for the sub account + name (str): Name of the sub account + + [Click here for more info](https://developers.openpix.com.br/api#tag/sub-account-(request-access)/paths/~1api~1v1~1subaccount/post) + """ + def create(self, pixKey: str, name: str) -> sub_account_types.SubAccountCreate: + return self._client.post(path=f'/api/v1/subaccount', data={ + "pixKey": pixKey, + "name": name + }) + + """Transfer between subaccounts + Args: + value (int): The value of the transfer in cents + fromPixKey (str): The transfer origin pix key + fromPixKeyType (str): The transfer origin pix key type. Enum: "CPF" "CNPJ" "EMAIL" "PHONE" "RANDOM" + toPixKey (str): The transfer destination pix key + toPixKeyType (str): The transfer destination pix key type. Enum: "CPF" "CNPJ" "EMAIL" "PHONE" "RANDOM" + correlationID (str): Your correlation ID to keep track of this transfer + + [Click here for more info](https://developers.openpix.com.br/api#tag/sub-account-(request-access)/paths/~1api~1v1~1subaccount~1transfer/post) + """ + def transfer(self, value: int, fromPixKey: str, fromPixKeyType: str, toPixKey: str, toPixKeyType: str, correlationID: str) -> sub_account_types.TransferCreate: + return self._client.post(path=f'/api/v1/subaccount/transfer', data={ + "value": value, + "fromPixKey": fromPixKey, + "fromPixKeyType": fromPixKeyType, + "toPixKey": toPixKey, + "toPixKeyType": toPixKeyType, + "correlationID": correlationID, + }) \ No newline at end of file diff --git a/openpix/resources/sub_account_types.py b/openpix/resources/sub_account_types.py new file mode 100644 index 0000000..2af9ef5 --- /dev/null +++ b/openpix/resources/sub_account_types.py @@ -0,0 +1,56 @@ +from openpix.types import PageInfo +from typing import List + +class SubAccount: + def __init__(self, name: str, pixKey: str, balance: int): + self.name = name + self.pixKey = pixKey + self.balance = balance + +class Transaction: + def __init__(self, status: str, value: int, correlationID: str, destinationAlias: str, comment: str): + self.status = status + self.value = value + self.correlationID = correlationID + self.destinationAlias = destinationAlias + self.comment = comment + +class SubAccountCreate: + def __init__(self, name: str, pixKey: str): + self.name = name + self.pixKey = pixKey + +class DestinationSubaccount: + def __init__(self, name: str, pixKey: str, value: int): + self.name = name + self.pixKey = pixKey + self.value = value + +class OriginSubaccount: + def __init__(self, name: str, pixKey: str, value: int): + self.name = name + self.pixKey = pixKey + self.value = value + +class SubAccountGet: + def __init__(self, SubAccount: SubAccount): + self.SubAccount = SubAccount + +class SubAccountList: + def __init__(self, pageInfo: PageInfo, subAccounts: List[SubAccount]): + self.pageInfo = pageInfo + self.subAccounts = subAccounts + +class WithdrawCreate: + def __init__(self, transaction: Transaction): + self.transaction = transaction + +class SubAccountCreate: + def __init__(self, SubAccount: SubAccountCreate): + self.SubAccount = SubAccount + +class TransferCreate: + def __init__(self, value: int, destinationSubaccount: DestinationSubaccount, originSubaccount: OriginSubaccount): + self.value = value + self.destinationSubaccount = destinationSubaccount + self.originSubaccount = originSubaccount diff --git a/openpix/resources/subscription.py b/openpix/resources/subscription.py new file mode 100644 index 0000000..852b3f2 --- /dev/null +++ b/openpix/resources/subscription.py @@ -0,0 +1,65 @@ +""" + Module: subscription +""" +from openpix.http import HttpClient +import openpix.resources.subscription_types as subscription_types +from typing import List + +class Subscription: + """ + Access to Subscription + + [Click here for more info](https://developers.woovi.com/api#tag/subscription) # pylint: disable=line-too-long + """ + def __init__(self, HttpClient: HttpClient): + self._client = HttpClient + + """Get one subscription + Args: + id (str): The globalID or correlationID of the subscription. + + [Click here for more info](https://developers.openpix.com.br/api#tag/subscription/paths/~1api~1v1~1subscriptions~1%7Bid%7D/get) + """ + def get(self, id: str) -> subscription_types.SubscriptionGet: + return self._client.get(path=f'/api/v1/subscriptions/{id}') + + """Get one subscription + Args: + customer (customer): + - name: str + - email: str + - phone: str + - taxID: + - taxID: str + - type: str + + value (int): Value in cents of this subscription + comment (str): Comment to be added in infoPagador + additionalInfo (list(additionalInfo)): + [ + - key: str + - value: str + ] + dayGenerateCharge (int): Day of the month that the charges will be generated. Maximum of 31. + chargeType (str): The charge type is used to determine whether charges generated by the subscription will have fines and interests + dayDue (int): Days that the charge will take to expire from the generation day. + correlationID (int): Your correlation ID to keep track of this subscription + + [Click here for more info](https://developers.openpix.com.br/api#tag/subscription/paths/~1api~1v1~1subscriptions/post) + """ + def create(self, customer: subscription_types.Customer, value: int, comment: str, additionalInfo: List[subscription_types.AditionalInfo], dayGenerateCharge: int, chargeType: str, dayDue: str, correlationID: str): + return self._client.post(path=f'/api/v1/subscriptions', data={ + "value": value, + "customer": { + "name": customer.name, + "taxID": customer.taxID.taxID, + "email": customer.email, + "phone": customer.phone, + }, + "dayGenerateCharge": dayGenerateCharge, + "chargeType": chargeType, + "comment": comment, + "additionalInfo": additionalInfo, + "dayDue": dayDue, + "correlationID": correlationID + }) \ No newline at end of file diff --git a/openpix/resources/subscription_types.py b/openpix/resources/subscription_types.py new file mode 100644 index 0000000..1a073dc --- /dev/null +++ b/openpix/resources/subscription_types.py @@ -0,0 +1,45 @@ +class TaxID: + def __init__(self, taxID: str, type: str): + self.taxID = taxID + self.type = type + +class Address: + def __init__(self, zipcode: str, street: str, number: str, neighborhood: str, city: str, state: str, complement: str, country: str): + self.zipcode = zipcode + self.street = street + self.number = number + self.neighborhood = neighborhood + self.city = city + self.state = state + self.complement = complement + self.country = country + +class Customer: + def __init__(self, name: str, email: str, phone: str, taxID: TaxID, address: Address): + self.name = name + self.email = email + self.phone = phone + self.taxID = taxID + self.address = address + +class Subscription: + def __init__(self, globalID: str, value: int, customer: Customer, dayGenerateCharge: int, status: str, correlationID: str): + self.globalID = globalID + self.value = value + self.customer = customer + self.dayGenerateCharge = dayGenerateCharge + self.status = status + self.correlationID = correlationID + +class AditionalInfo: + def __init__(self, key: str, value: str): + self.key = key + self.value = value + +class SubscriptionGet: + def __init__(self, subscription: Subscription): + self.subscription = subscription + +class SubscriptionCreate: + def __init__(self, subscription: Subscription): + self.subscription = subscription diff --git a/openpix/resources/transactions.py b/openpix/resources/transactions.py new file mode 100644 index 0000000..dbcdf8b --- /dev/null +++ b/openpix/resources/transactions.py @@ -0,0 +1,39 @@ +""" + Module: transactions +""" +from openpix.http import HttpClient +import openpix.resources.transactions_type as transactions_type +from openpix.types import PagePayload + +class Transactions: + """ + Access to Transactions + + [Click here for more info](https://developers.woovi.com/api#tag/transactions) # pylint: disable=line-too-long + """ + def __init__(self, HttpClient: HttpClient): + self._client = HttpClient + + """Get a Transaction + Args: + id (str): you can use the transaction id from openpix or the endToEndId of transaction from bank + + [Click here for more info](https://developers.openpix.com.br/api#tag/transactions/paths/~1api~1v1~1transaction~1%7Bid%7D/get) + """ + def get(self, id: str) -> transactions_type.TransactionsGet: + return self._client.get(path=f'/api/v1/transaction/{id}') + + """Get a list of transactions + Args: + start (str): Start date used in the query. Complies with RFC 3339. + end (str): End date used in the query. Complies with RFC 3339. + charge (str): You can use the charge ID or correlation ID or transaction ID of charge to get a list of transactions related of this transaction + pixQrCode (str): You can use the QrCode static ID or correlation ID or identifier field of QrCode static to get a list of QrCode related of this transaction + withdrawal (str): You can use the ID or EndToEndId of a withdrawal transaction to get all transactions related to the withdrawal + + page (PageInfo): A class for page info object containing limit and skip + + [Click here for more info](https://developers.openpix.com.br/api#tag/transactions/paths/~1api~1v1~1transaction/get) + """ + def list(self, start: str, end: str, charge: str, pixQrCode: str, withdrawal: str, page: PagePayload = PagePayload()) -> transactions_type.TransactionsList: + return self._client.get(path=f'/api/v1/transaction', query={"start": start, "end": end, "charge": charge, "pixQrCode": pixQrCode, "withdrawal": withdrawal, "limit": page.limit, "skip": page.skip}) diff --git a/openpix/resources/transactions_type.py b/openpix/resources/transactions_type.py new file mode 100644 index 0000000..b3e5110 --- /dev/null +++ b/openpix/resources/transactions_type.py @@ -0,0 +1,102 @@ +from openpix.types import PageInfo +from typing import List + +class TaxID: + def __init__(self, taxID: str, type: str): + self.taxID = taxID + self.type = type + +class Address: + def __init__(self, zipcode: str, street: str, number: str, neighborhood: str, city: str, state: str, complement: str, country: str): + self.zipcode = zipcode + self.street = street + self.number = number + self.neighborhood = neighborhood + self.city = city + self.state = state + self.complement = complement + self.country = country + +class Customer: + def __init__(self, name: str, email: str, phone: str, taxID: TaxID, address: Address): + self.name = name + self.email = email + self.phone = phone + self.taxID = taxID + self.address = address + +class AdditionalInfo: + def __init__(self, key: str, value: str): + self.key = key + self.value = value + +class PixQrCode: + def __init__(self, name: str, value: str, comment: str, brCode: str, correlationID: str, + paymentLinkID: str, paymentLinkUrl: str, qrCodeImage: str, createdAt: str, updatedAt: str): + self.name = name + self.value = value + self.comment = comment + self.brCode = brCode + self.correlationID = correlationID + self.paymentLinkID = paymentLinkID + self.paymentLinkUrl = paymentLinkUrl + self.qrCodeImage = qrCodeImage + self.createdAt = createdAt + self.updatedAt = updatedAt + +class Charge: + def __init__(self, value: int, customer: Customer, type: str, comment: str, brCode: str, status: str, correlationID: str, + paymentLinkID: str, paymentLinkUrl: str, globalID: str, transactionID: str, identifier: str, qrCodeImage: str, + additionalInfo: list, pixKey: str, createdAt: str, updatedAt: str, expiresIn: str): + self.value = value + self.customer = customer + self.type = type + self.comment = comment + self.brCode = brCode + self.status = status + self.correlationID = correlationID + self.paymentLinkID = paymentLinkID + self.paymentLinkUrl = paymentLinkUrl + self.globalID = globalID + self.transactionID = transactionID + self.identifier = identifier + self.qrCodeImage = qrCodeImage + self.additionalInfo = additionalInfo + self.pixKey = pixKey + self.createdAt = createdAt + self.updatedAt = updatedAt + self.expiresIn = expiresIn + +class Subscription: + def __init__(self, globalID: str, value: int, customer: Customer, dayGenerateCharge: int, status: str, correlationID: str): + self.globalID = globalID + self.value = value + self.customer = customer + self.dayGenerateCharge = dayGenerateCharge + self.status = status + self.correlationID = correlationID + +class Transaction: + def __init__(self, charge: Charge, value: int, time: str, endToEndID: str, transactionID: str, infoPagador: str, + customer: Customer, withdraw: dict, payer: Customer, type: str, globalID: str, pixQrCode: PixQrCode): + self.charge = charge + self.value = value + self.time = time + self.endToEndID = endToEndID + self.transactionID = transactionID + self.infoPagador = infoPagador + self.customer = customer + self.withdraw = withdraw + self.payer = payer + self.type = type + self.globalID = globalID + self.pixQrCode = pixQrCode + +class TransactionsGet: + def __init__(self, transaction: Transaction): + self.transaction = transaction + +class TransactionsList: + def __init__(self, pageInfo: PageInfo, transactions: List[Transaction]): + self.pageInfo = pageInfo + self.transactions = transactions diff --git a/openpix/resources/transfer.py b/openpix/resources/transfer.py new file mode 100644 index 0000000..410ad10 --- /dev/null +++ b/openpix/resources/transfer.py @@ -0,0 +1,17 @@ +""" + Module: transfer +""" +from openpix.http import HttpClient +import openpix.resources.transfer_types as transfer_types + +class Transfer: + """ + Access to Transfer + + [Click here for more info](https://developers.woovi.com/api#tag/transfer-(request-access)) # pylint: disable=line-too-long + """ + def __init__(self, HttpClient: HttpClient): + self._client = HttpClient + + def create(self, value: str, fromPixKey: str, toPixKey: str) -> transfer_types.Transfer: + return self._client.post(path=f'/api/v1/transfer', data={value: value, fromPixKey: fromPixKey, toPixKey: toPixKey}) \ No newline at end of file diff --git a/openpix/resources/transfer_types.py b/openpix/resources/transfer_types.py new file mode 100644 index 0000000..71626fa --- /dev/null +++ b/openpix/resources/transfer_types.py @@ -0,0 +1,10 @@ +class Transfer: + def __init__(self, value: int, time: str, correlationID: str): + self.value = value + self.time = time + self.correlationID = correlationID + +class TransferCreate: + def __init__(self, transaction: Transfer): + self.transaction = transaction + \ No newline at end of file diff --git a/openpix/resources/webhook.py b/openpix/resources/webhook.py new file mode 100644 index 0000000..ff871b7 --- /dev/null +++ b/openpix/resources/webhook.py @@ -0,0 +1,64 @@ +""" + Module: webhook +""" +from openpix.http import HttpClient +import openpix.resources.webhook_types as webhook_types +from openpix.types import PagePayload + +class Webhook: + """ + Access to Webhook + + [Click here for more info](https://developers.woovi.com/api#tag/webhook) # pylint: disable=line-too-long + """ + def __init__(self, HttpClient: HttpClient): + self._client = HttpClient + + """Get a list of webhook IPs + Args: + page (PageInfo): A class for page info object containing limit and skip + + [Click here for more info](https://developers.openpix.com.br/api#tag/webhook/paths/~1api~1v1~1webhook~1ips/get) + """ + def list_ips(self, page: PagePayload = PagePayload()) -> webhook_types.WebhookListIps: + return self._client.get(path=f'/api/v1/webhook/ips', query={"limit": page.limit, "skip": page.skip}) + + """Get a list of webhooks + Args: + page (PageInfo): A class for page info object containing limit and skip + + [Click here for more info](https://developers.openpix.com.br/api#tag/webhook/paths/~1api~1v1~1webhook/get) + """ + def list(self, page: PagePayload = PagePayload()) -> webhook_types.WebhookList: + return self._client.get(path=f'/api/v1/webhook', query={"limit": page.limit, "skip": page.skip}) + + """Delete a Webhook + Args: + id (str): A class for page info object containing limit and skip + + [Click here for more info](https://developers.openpix.com.br/api#tag/webhook/paths/~1api~1v1~1webhook~1%7Bid%7D/delete) + """ + def delete(self, id: str) -> webhook_types.WebhookDelete: + return self._client.delete(path=f'/api/v1/webhook/{id}') + + """Create a new Webhook + Args: + id (str): identifier of the webhook + name (str): the name of the webhook + event (str): Available events to register a webhook to listen to. If no one selected anyone the default event will be OPENPIX:TRANSACTION_RECEIVED. + url (str): webhook endpoint to be called + isActive (bool): if the endpoint is active + authorization (str): authorization to your endpoint + + [Click here for more info](https://developers.openpix.com.br/api#tag/webhook/paths/~1api~1v1~1webhook/post) + """ + def create(self, name: str, event: str, url: str, authorization: str, isActive: bool) -> webhook_types.WebhookCreate: + return self._client.post(path=f'/api/v1/webhook', data={ + "webhook": { + "name": name, + "event": event, + "url": url, + "isActive": isActive, + "authorization": "authorization" + } + }) diff --git a/openpix/resources/webhook_types.py b/openpix/resources/webhook_types.py new file mode 100644 index 0000000..dbed091 --- /dev/null +++ b/openpix/resources/webhook_types.py @@ -0,0 +1,30 @@ +from openpix.types import PageInfo +from typing import List + +class Webhook: + def __init__(self, id: str, name: str, event: str, url: str, authorization: str, isActive: bool, createdAt: str, updatedAt: str): + self.id = id + self.name = name + self.event = event + self.url = url + self.authorization = authorization + self.isActive = isActive + self.createdAt = createdAt + self.updatedAt = updatedAt + +class WebhookListIps: + def __init__(self, ips: List[str]): + self.ips = ips + +class WebhookList: + def __init__(self, pageInfo: PageInfo, webhooks: List[Webhook]): + self.pageInfo = pageInfo + self.webhooks = webhooks + +class WebhookDelete: + def __init__(self, status: str): + self.status = status + +class WebhookCreate: + def __init__(self, webhook: Webhook): + self.webhook = webhook diff --git a/openpix/sdk.py b/openpix/sdk.py new file mode 100644 index 0000000..ba5a832 --- /dev/null +++ b/openpix/sdk.py @@ -0,0 +1,148 @@ +""" +Module: sdk +""" +from openpix.http import HttpClient +from openpix.resources import ( + Account, + CashbackFidelity, + Charge, + ChargeRefund, + Customer, + Partner, + PixQrCode, + Payment, + Refund, + SubAccount, + Subscription, + Transactions, + Transfer, + Webhook +) + +class SDK: + """Generate access to all API' modules, which are: + + 1. Account + 2. CashbackFidelity + 3. Charge + 4. ChargeRefund + 5. Customer + 6. Partner + 7: PixQrCode + 8: Payment + 9: Refund + 10: SubAccount + 11: Subscription + 12: Transactions + 13: Transfer + 14: Webhook + """ + + def __init__( + self, + app_id: str, + ): + """Construct ur SDK Object to have access to all APIs modules. + Args: + app_id (str): A string representing the application ID, which serves as the API key. + [Click here for more info](https://developers.woovi.com/docs/apis/api-getting-started) + """ + self._http_client = HttpClient(app_id=app_id) + + @property + def account(self): + """ + Returns the attribute value of the function + """ + return Account(self._http_client) + + @property + def cashback(self): + """ + Returns the attribute value of the function + """ + return CashbackFidelity(self._http_client) + + @property + def charge(self): + """ + Returns the attribute value of the function + """ + return Charge(self._http_client) + + @property + def chargeRefund(self): + """ + Returns the attribute value of the function + """ + return ChargeRefund(self._http_client) + + @property + def customer(self): + """ + Returns the attribute value of the function + """ + return Customer(self._http_client) + + @property + def partner(self): + """ + Returns the attribute value of the function + """ + return Partner(self._http_client) + + @property + def pixQrCode(self): + """ + Returns the attribute value of the function + """ + return PixQrCode(self._http_client) + + @property + def payment(self): + """ + Returns the attribute value of the function + """ + return Payment(self._http_client) + + @property + def refund(self): + """ + Returns the attribute value of the function + """ + return Refund(self._http_client) + + @property + def subAccount(self): + """ + Returns the attribute value of the function + """ + return SubAccount(self._http_client) + + @property + def subscription(self): + """ + Returns the attribute value of the function + """ + return Subscription(self._http_client) + + @property + def transactions(self): + """ + Returns the attribute value of the function + """ + return Transactions(self._http_client) + + @property + def transfer(self): + """ + Returns the attribute value of the function + """ + return Transfer(self._http_client) + + @property + def webhook(self): + """ + Returns the attribute value of the function + """ + return Webhook(self._http_client) \ No newline at end of file diff --git a/openpix/types.py b/openpix/types.py new file mode 100644 index 0000000..a8f3083 --- /dev/null +++ b/openpix/types.py @@ -0,0 +1,12 @@ +class PageInfo: + def __init__(self, skip: int, limit: int, totalCount: int, hasPreviousPage: bool, hasNextPage: bool): + self.skip = skip + self.limit = limit + self.totalCount = totalCount + self.hasPreviousPage = hasPreviousPage + self.hasNextPage = hasNextPage + +class PagePayload: + def __init__(self, limit: int = 10, skip:int = 0): + self.limit = limit + self.skip = skip \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 82b4464..2a61def 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,6 +3,7 @@ name = "python-sdk" version = "0.1.0" description = "SDK for integration with the Woovi API" authors = [ + "Ytalo da Silva Batalha ", "Camilo Cunha de Azevedo ", "woovi " ] diff --git a/python_sdk/__init__.py b/tests/test_account.py similarity index 100% rename from python_sdk/__init__.py rename to tests/test_account.py diff --git a/tests/test_cashback_fidelity.py b/tests/test_cashback_fidelity.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_charge.py b/tests/test_charge.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_charge_refund.py b/tests/test_charge_refund.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_customer.py b/tests/test_customer.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_partner.py b/tests/test_partner.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_payment.py b/tests/test_payment.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_pix_qr_code.py b/tests/test_pix_qr_code.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_refund.py b/tests/test_refund.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_sub_account.py b/tests/test_sub_account.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_subscription.py b/tests/test_subscription.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_transactions.py b/tests/test_transactions.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_transfer.py b/tests/test_transfer.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_webhook.py b/tests/test_webhook.py new file mode 100644 index 0000000..e69de29