Skip to content
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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ pip install paysgator
## Usage

```python
from paysgator import PaysgatorClient

client = PaysgatorClient(api_key="YOUR_API_KEY")
import os; from paysgator import PaysgatorClient
# WARNING: Never hardcode API keys. Use environment variables.
client = PaysgatorClient(api_key=os.getenv("PAYSGATOR_API_KEY"))

# Create a payment
payment = client.payments.create(
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ authors = [
]
description = "Official Python SDK for Paysgator API"
readme = "README.md"
requires-python = ">=3.7"
requires-python = ">=3.8"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
Expand Down
4 changes: 2 additions & 2 deletions src/paysgator/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .client import PaysgatorClient
from .client import PaysgatorClient, Payments, Subscriptions
from .exceptions import PaysgatorError, AuthenticationError, APIError

__all__ = ["PaysgatorClient", "PaysgatorError", "AuthenticationError", "APIError"]
__all__ = ["PaysgatorClient", "Payments", "Subscriptions", "PaysgatorError", "AuthenticationError", "APIError"]
9 changes: 5 additions & 4 deletions src/paysgator/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@ def get_balance(self) -> WalletBalanceResponse:
return WalletBalanceResponse(**response_data)

class PaysgatorClient:
BASE_URL = "https://paysgator.com/api/v1"

def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://paysgator.com/api/v1"

self.session = requests.Session()
self.session.headers.update({
"X-Api-Key": self.api_key,
Expand All @@ -66,11 +67,11 @@ def __init__(self, api_key: str):
self.wallet = Wallet(self)

def set_base_url(self, url: str):
self.BASE_URL = url
self.base_url = url

def request(self, method: str, endpoint: str, data: Optional[dict] = None) -> dict:
url = f"{self.BASE_URL}{endpoint}"
response = self.session.request(method, url, json=data)
url = f"{self.base_url}{endpoint}"
response = self.session.request(method, url, json=data, timeout=30)

if response.status_code >= 400:
raise APIError(response.status_code, response.text)
Expand Down
10 changes: 7 additions & 3 deletions src/paysgator/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
class PaysgatorError(Exception):
"""Base exception for Paysgator SDK"""
pass
def __init__(self, message: str = "", endpoint=None, method=None, response_body=None):
self.endpoint = endpoint
self.method = method
self.response_body = response_body
super().__init__(message)

class AuthenticationError(PaysgatorError):
"""Raised when authentication fails"""
pass

class APIError(PaysgatorError):
"""Raised when the API returns an error"""
def __init__(self, status_code: int, message: str):
def __init__(self, status_code: int, message: str, endpoint=None, method=None, response_body=None):
self.status_code = status_code
self.message = message
super().__init__(f"API Error {status_code}: {message}")
super().__init__(f"API Error {status_code}: {message}", endpoint, method, response_body)
10 changes: 5 additions & 5 deletions src/paysgator/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ class Mode(str, Enum):
TEST = "TEST"

class PaymentCreateRequest(BaseModel):
amount: float
currency: str
amount: float = Field(..., gt=0)
currency: str = Field(..., min_length=3, max_length=3)
external_transaction_id: Optional[str] = Field(None, alias="externalTransactionId")
payment_methods: Optional[List[str]] = Field(None, alias="payment_methods")
fields: Optional[List[str]] = None
Expand Down Expand Up @@ -62,8 +62,8 @@ class SubscriptionResponse(BaseModel):

class TransactionResponse(BaseModel):
id: str
amount: float
currency: str
amount: float = Field(..., gt=0)
currency: str = Field(..., min_length=3, max_length=3)
status: str
method: Optional[str] = None
description: Optional[str] = None
Expand All @@ -72,6 +72,6 @@ class TransactionResponse(BaseModel):

class WalletBalanceResponse(BaseModel):
wallet_id: str = Field(..., alias="walletId")
currency: str
currency: str = Field(..., min_length=3, max_length=3)
balance: str
mode: str
8 changes: 4 additions & 4 deletions test_sdk.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from src.paysgator.client import PaysgatorClient

from paysgator.client import PaysgatorClient
import os
#Mpesa direct charge test

api_key = "<Api Key>"
api_key = os.getenv("PAYSGATOR_API_KEY", "<Api Key>")

wallet_id = "<Wallet Id>"
wallet_id = os.getenv("PAYSGATOR_WALLET_ID", "<Wallet Id>")

client = PaysgatorClient(api_key, wallet_id)

Expand Down