Skip to content

Commit

Permalink
Merge 05ce88a into 4c277db
Browse files Browse the repository at this point in the history
  • Loading branch information
rogelioLpz committed Sep 3, 2019
2 parents 4c277db + 05ce88a commit ebf0843
Show file tree
Hide file tree
Showing 16 changed files with 1,346 additions and 27 deletions.
196 changes: 195 additions & 1 deletion arcus/exc.py
Expand Up @@ -62,7 +62,9 @@ def __init__(self, code: str, transaction_id: Union[int, str]):


class InvalidAmount(UnprocessableEntity):
pass
def __init__(self, code: str, amount: float):
message = f'Invalid amount: {amount}'
super().__init__(code, message)


class AlreadyPaid(UnprocessableEntity):
Expand Down Expand Up @@ -92,3 +94,195 @@ def __init__(self, code: str, amount: float):

class Forbidden(ArcusException):
"""Method Not Allowed"""


class UnexpectedError(UnprocessableEntity):
def __init__(self, code: str):
message = f'Unexpected error. Failed to make the consult'
super().__init__(code, message)


class InvalidOrMissingParameters(UnprocessableEntity):
def __init__(self, code: str):
message = f'Invalid or missing parameters'
super().__init__(code, message)


class InvalidBalance(UnprocessableEntity):
def __init__(self, code: str):
message = f'Account Balance is 0 or not enough'
super().__init__(code, message)


class FailedConsult(UnprocessableEntity):
def __init__(self, code: str):
message = f'Failed to make the consult, please try again later'
super().__init__(code, message)


class LimitExceeded(UnprocessableEntity):
def __init__(self, code: str):
message = f'Limit of transactions exceeded'
super().__init__(code, message)


class BillerMaintenance(UnprocessableEntity):
def __init__(self, code: str):
message = f'Biller maintenance in progress, please try again later'
super().__init__(code, message)


class ReversalNotSupported(UnprocessableEntity):
def __init__(self, code: str):
message = f'Reversal not supported'
super().__init__(code, message)


class BillerConnection(UnprocessableEntity):
def __init__(self, code: str):
message = f'Timeout from biller'
super().__init__(code, message)


class CancellationError(UnprocessableEntity):
def __init__(self, code: str):
message = f'Error with performing the cancellation'
super().__init__(code, message)


class OverdueBill(UnprocessableEntity):
def __init__(self, code: str):
message = f'Overdue Bill'
super().__init__(code, message)


class InvalidPhone(UnprocessableEntity):
def __init__(self, code: str):
message = f'Invalid Phone Number'
super().__init__(code, message)


class FraudSuspected(UnprocessableEntity):
def __init__(self, code: str):
message = f'Fraud suspected'
super().__init__(code, message)


class InvalidCurrency(UnprocessableEntity):
def __init__(self, code: str):
message = f'Invalid Currency'
super().__init__(code, message)


class InvalidCompany(UnprocessableEntity):
def __init__(self, code: str):
message = f'Invalid company'
super().__init__(code, message)


class InvalidBarCode(UnprocessableEntity):
def __init__(self, code: str):
message = f'Invalid Barcode Format.'
super().__init__(code, message)


class InvalidCustomerStatus(UnprocessableEntity):
def __init__(self, code: str):
message = f'Invalid Customer Status.'
super().__init__(code, message)


class DailyPaymentsLimit(UnprocessableEntity):
def __init__(self, code: str):
message = f'The maximum number of payments on this day was reached'
super().__init__(code, message)


class BalanceNotFound(UnprocessableEntity):
def __init__(self, code: str):
message = f'Can\'t get balance.'
super().__init__(code, message)


class InvalidSubscription(UnprocessableEntity):
def __init__(self, code: str):
message = f'Invalid Subscription ID. Verify the ID or create a new'
super().__init__(code, message)


class InvalidPOS(UnprocessableEntity):
def __init__(self, code: str):
message = f'POS number is invalid'
super().__init__(code, message)


class AccessDenied(UnprocessableEntity):
def __init__(self, code: str):
message = f'Processor Access Denied'
super().__init__(code, message)


def RaiseCustomArcusException(
ex: UnprocessableEntity,
account_number: str,
biller_id: int,
amount: Optional[float] = 0):
if ex.code in {'R1', 'R2', 'R4', 'R5', 'R10', 'R28', 'R29'}:
raise InvalidAccountNumber(
ex.code, account_number, biller_id)
elif ex.code in {'R3', 'R11', 'R41'}:
raise IncompleteAmount(ex.code, amount=amount)
elif ex.code in {'R6', 'R19', 'R20', 'R21'}:
raise InvalidBiller(biller_id)
elif ex.code in {'R7', 'R37'}:
raise RecurrentPayments(ex.code)
elif ex.code in {'R8', 'R12'}:
raise AlreadyPaid(ex.code)
elif ex.code in {'R9', 'R99', 'R299'}:
raise UnexpectedError(ex.code)
elif ex.code in {'R13'}:
raise InvalidOrMissingParameters(ex.code)
elif ex.code in {'R14', 'R17', 'R32', 'R102', 'R114'}:
raise InvalidAmount(ex.code, amount)
elif ex.code in {'R15', 'R42', 'R100'}:
raise InvalidBalance(ex.code)
elif ex.code in {'R16', 'R35'}:
raise FailedConsult(ex.code)
elif ex.code in {'R18'}:
raise LimitExceeded(ex.code)
elif ex.code in {'R22'}:
raise BillerMaintenance(ex.code)
elif ex.code in {'R23', 'R26', 'R103', 'R105'}:
raise ReversalNotSupported(ex.code)
elif ex.code in {'R24', 'R47', 'R48'}:
raise BillerConnection(ex.code)
elif ex.code in {'R25'}:
raise CancellationError(ex.code)
elif ex.code in {'R27'}:
raise OverdueBill(ex.code)
elif ex.code in {'R30', 'R117'}:
raise InvalidCompany(ex.code)
elif ex.code in {'R31'}:
raise InvalidPhone(ex.code)
elif ex.code in {'R33'}:
raise FraudSuspected(ex.code)
elif ex.code in {'R34'}:
raise InvalidCurrency(ex.code)
elif ex.code in {'R36'}:
raise DuplicatedPayment(ex.code, amount=amount)
elif ex.code in {'R43'}:
raise InvalidBarCode(ex.code)
elif ex.code in {'R44'}:
raise InvalidCustomerStatus(ex.code)
elif ex.code in {'R45'}:
raise DailyPaymentsLimit(ex.code)
elif ex.code in {'R46', 'R101', 'R121', 'R122', 'R202'}:
raise BalanceNotFound(ex.code)
elif ex.code in {'R104'}:
raise InvalidSubscription(ex.code)
elif ex.code in {'R117'}:
raise InvalidPOS(ex.code)
elif ex.code in {'R201'}:
raise AccessDenied(ex.code)
else:
raise
22 changes: 5 additions & 17 deletions arcus/resources/bills.py
Expand Up @@ -5,7 +5,8 @@
from arcus.exc import (
AlreadyPaid, DuplicatedPayment, IncompleteAmount,
InvalidAccountNumber, InvalidAmount, InvalidBiller,
NotFound, RecurrentPayments, UnprocessableEntity)
NotFound, RecurrentPayments, UnprocessableEntity, UnexpectedError,
RaiseCustomArcusException)

from .base import Resource
from .transactions import Transaction
Expand Down Expand Up @@ -43,10 +44,7 @@ def create(cls, biller_id: Union[int, str], account_number: str):
except NotFound:
raise InvalidBiller(biller_id)
except UnprocessableEntity as ex:
if ex.code in {'R1', 'R2', 'R29'}:
raise InvalidAccountNumber(ex.code, account_number, biller_id)
else:
raise
RaiseCustomArcusException(ex, account_number, biller_id)
return cls(**bill_dict)

def pay(self, amount: Optional[float] = None) -> Transaction:
Expand All @@ -60,16 +58,6 @@ def pay(self, amount: Optional[float] = None) -> Transaction:
transaction_dict = self._client.post(
f'{self._endpoint}/{self.id}/pay', data)
except UnprocessableEntity as ex:
if ex.code == 'R102':
raise InvalidAmount(ex.code, ex.message, amount=amount)
elif ex.code in {'R3', 'R11', 'R41'}:
raise IncompleteAmount(ex.code, amount=amount)
elif ex.code == 'R7':
raise RecurrentPayments(ex.code)
elif ex.code == 'R36':
raise DuplicatedPayment(ex.code, amount=amount)
elif ex.code in {'R12', 'R8'}:
raise AlreadyPaid(ex.code)
else:
raise
RaiseCustomArcusException(
ex, self.account_number, self.biller_id, amount)
return Transaction(**transaction_dict)
8 changes: 3 additions & 5 deletions arcus/resources/topups.py
Expand Up @@ -2,7 +2,8 @@
from dataclasses import dataclass, field
from typing import Optional

from arcus.exc import InvalidAccountNumber, UnprocessableEntity
from arcus.exc import InvalidAccountNumber, UnprocessableEntity,\
RaiseCustomArcusException

from .base import Resource

Expand Down Expand Up @@ -61,10 +62,7 @@ def create(
topup_dict = cls._client.post(
cls._endpoint, data, api_version=TOPUP_API_VERSION)
except UnprocessableEntity as ex:
if ex.code in {'R2', 'R5'}:
raise InvalidAccountNumber(ex.code, account_number, biller_id)
else:
raise
RaiseCustomArcusException(ex, account_number, biller_id, amount)
return Topup(**topup_dict)

@classmethod
Expand Down
97 changes: 97 additions & 0 deletions tests/resources/cassettes/test_biller_connection.yaml
@@ -0,0 +1,97 @@
interactions:
- request:
body: '{"biller_id": 40, "account_number": "501000000007"}'
headers:
Accept:
- application/vnd.regalii.v3.1+json
Accept-Encoding:
- gzip, deflate
Authorization:
- APIAuth 88879c1b066dc9aea6201f27be2bbba9:mzDq57CXdpeA/0Rp9Vz5FuEItb8=
Connection:
- keep-alive
Content-Length:
- '51'
Content-MD5:
- PtZUYQ9bmh3ULNV0W7ZNdw==
Content-Type:
- application/json
Date:
- Tue, 03 Sep 2019 05:04:59 GMT
User-Agent:
- python-requests/2.21.0
method: POST
uri: https://api.casiregalii.com/bills
response:
body:
string: '{"type":"bill","id":8390,"biller_id":40,"account_number":"501000000007","name_on_account":null,"due_date":"2019-09-03T00:00:00Z","balance":-10.0,"balance_currency":"MXN","balance_updated_at":"2019-09-03T05:04:59Z","error_code":null,"error_message":null,"status":"linked","migrated_at":null,"mfa_challenges":[]}'
headers:
Cache-Control:
- max-age=0, private, must-revalidate
Connection:
- keep-alive
Content-Type:
- application/json; charset=utf-8
Date:
- Tue, 03 Sep 2019 05:05:00 GMT
ETag:
- W/"81b45e45be5697991fdf737582edf850"
Strict-Transport-Security:
- max-age=31536000; includeSubDomains
Transfer-Encoding:
- chunked
X-Request-Id:
- 8c599b21-7ed4-4014-a7da-7b9b5a0fe3ca
X-Runtime:
- '1.070474'
status:
code: 200
message: OK
- request:
body: '{"amount": -10.0, "currency": "MXN"}'
headers:
Accept:
- application/vnd.regalii.v3.1+json
Accept-Encoding:
- gzip, deflate
Authorization:
- APIAuth 88879c1b066dc9aea6201f27be2bbba9:LP7v2s6Ddeu/qX2XU0WL5jdK+jk=
Connection:
- keep-alive
Content-Length:
- '36'
Content-MD5:
- mg1MPY2yXLf8n26ugdpxLw==
Content-Type:
- application/json
Date:
- Tue, 03 Sep 2019 05:05:00 GMT
User-Agent:
- python-requests/2.21.0
method: POST
uri: https://api.casiregalii.com/bills/8390/pay
response:
body:
string: '{"code":"R102","message":"Parameter amount cannot be less than 0.1:
amount"}'
headers:
Cache-Control:
- no-cache
Connection:
- keep-alive
Content-Type:
- application/json; charset=utf-8
Date:
- Tue, 03 Sep 2019 05:05:01 GMT
Strict-Transport-Security:
- max-age=31536000; includeSubDomains
Transfer-Encoding:
- chunked
X-Request-Id:
- 014c674f-b234-422e-9e09-32976a81ed0f
X-Runtime:
- '0.094961'
status:
code: 400
message: Bad Request
version: 1

0 comments on commit ebf0843

Please sign in to comment.