inttegro 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
inttegro/__init__.py ADDED
@@ -0,0 +1,21 @@
1
+ from .client import InttegroClient
2
+ from .errors import (
3
+ InttegroError,
4
+ NetworkError,
5
+ TimeoutError,
6
+ APIError,
7
+ AuthenticationError,
8
+ RateLimitError,
9
+ )
10
+ from .enums import * # noqa: F401,F403
11
+ from .enums import __all__ as _enum_exports
12
+
13
+ __all__ = [
14
+ "InttegroClient",
15
+ "InttegroError",
16
+ "NetworkError",
17
+ "TimeoutError",
18
+ "APIError",
19
+ "AuthenticationError",
20
+ "RateLimitError",
21
+ ] + _enum_exports
inttegro/client.py ADDED
@@ -0,0 +1,157 @@
1
+ from __future__ import annotations
2
+
3
+ from .http_client import HttpClient
4
+ from .resources.balance_transactions import BalanceTransactions
5
+ from .resources.chimes import Chimes
6
+ from .resources.customers import Customers
7
+ from .resources.schedules import Schedules
8
+ from .resources.broadcasts import Broadcasts
9
+ from .resources.message_templates import MessageTemplates
10
+ from .resources.financial_accounts import FinancialAccounts
11
+ from .resources.files import Files
12
+ from .resources.file_links import FileLinks
13
+ from .resources.file_references import FileReferences
14
+ from .resources.keys import Keys
15
+ from .resources.otp import Otp
16
+ from .resources.orders import Orders
17
+ from .resources.payment_methods import PaymentMethods
18
+ from .resources.payouts import Payouts
19
+ from .resources.products import Products
20
+ from .resources.prices import Prices
21
+ from .resources.purchase_intents import PurchaseIntents
22
+ from .resources.refunds import Refunds
23
+ from .resources.spec import Spec
24
+ from .resources.balances import Balances
25
+ from .resources.upload_requests import UploadRequests
26
+ from .resources.apps import Apps
27
+
28
+
29
+ class InttegroClient:
30
+ """
31
+ Main SDK client for the Inttegro API.
32
+
33
+ The Inttegro client provides access to all API resources including orders,
34
+ payment methods, payouts, financial accounts, and more. Initialize with
35
+ your API key from the Inttegro dashboard.
36
+
37
+ Attributes:
38
+ orders: Orders resource for creating and managing orders, processing payments
39
+ payment_methods: Payment methods resource for tokenizing and managing payment instruments
40
+ payouts: Payouts resource for scheduling and managing fund transfers
41
+ balance_transactions: Balance transactions resource for viewing account activity
42
+ financial_accounts: Financial accounts resource for connecting bank and mobile money accounts
43
+ customers: Customers resource for creating and managing customers
44
+ products: Products resource for managing catalog products
45
+ prices: Prices resource for managing catalog prices
46
+ refunds: Refunds resource for creating and managing refunds
47
+ chimes: Chimes resource for sending transactional notifications
48
+ schedules: Schedules resource for looking up and canceling scheduled chimes
49
+ broadcasts: Broadcasts resource for looking up and canceling broadcasts
50
+ otp: OTP resource for one-time password verification
51
+ apps: Apps resource for creating, looking up, and updating applications
52
+ spec: Spec resource for retrieving supported countries and currencies
53
+
54
+ Example:
55
+ ```python
56
+ import os
57
+ from inttegro import InttegroClient
58
+
59
+ # Initialize client with API key
60
+ client = InttegroClient(api_key=os.environ["INTTEGRO_API_KEY"])
61
+
62
+ # Create and process an order
63
+ result = client.orders.create({
64
+ "customer_data": {
65
+ "name": "Akua Asantewaa",
66
+ "phone_number": "+233541234567",
67
+ "email_address": "akua@example.com"
68
+ },
69
+ "line_items": [{
70
+ "type": "product",
71
+ "product": {
72
+ "type": "digital",
73
+ "name": "Premium Subscription",
74
+ "quantity": 1,
75
+ "price": {"currency": "ghs", "value": 5000}
76
+ }
77
+ }],
78
+ "billing_details": {
79
+ "name": "Akua Asantewaa",
80
+ "phone_number": "+233541234567"
81
+ },
82
+ "execute_payment": True
83
+ })
84
+ ```
85
+
86
+ Thread Safety:
87
+ The client is thread-safe after initialization and can be safely shared
88
+ across multiple threads.
89
+ """
90
+
91
+ def __init__(
92
+ self,
93
+ api_key: str,
94
+ base_url: str = "https://api.inttegro.com",
95
+ timeout: float = 30.0,
96
+ transport=None,
97
+ ):
98
+ """
99
+ Initialize a new Inttegro client.
100
+
101
+ Args:
102
+ api_key: Your Inttegro API key (required). Get this from your dashboard
103
+ at https://studio.inttegro.com/settings/keys. Use test keys (sk_test_...)
104
+ for development and live keys (sk_live_...) for production.
105
+ base_url: API base URL. Defaults to production (https://api.inttegro.com).
106
+ Override for testing or staging environments.
107
+ timeout: Request timeout in seconds. Defaults to 30.0. Increase for
108
+ long-running operations or slow networks.
109
+ transport: Custom HTTP transport adapter. Pass a requests.Session or
110
+ custom transport for connection pooling, retries, or proxies.
111
+
112
+ Raises:
113
+ ValueError: If api_key is empty or invalid
114
+
115
+ Example:
116
+ ```python
117
+ # Production usage
118
+ client = InttegroClient(api_key="sk_live_...")
119
+
120
+ # Development with custom timeout
121
+ client = InttegroClient(
122
+ api_key="sk_test_...",
123
+ timeout=60.0
124
+ )
125
+
126
+ # Testing with mock server
127
+ client = InttegroClient(
128
+ api_key="sk_test_...",
129
+ base_url="http://localhost:8080"
130
+ )
131
+ ```
132
+ """
133
+ self.http = HttpClient(api_key=api_key, base_url=base_url, timeout=timeout, transport=transport)
134
+
135
+ self.orders = Orders(self.http)
136
+ self.payment_methods = PaymentMethods(self.http)
137
+ self.payouts = Payouts(self.http)
138
+ self.balance_transactions = BalanceTransactions(self.http)
139
+ self.financial_accounts = FinancialAccounts(self.http)
140
+ self.files = Files(self.http)
141
+ self.file_links = FileLinks(self.http)
142
+ self.file_references = FileReferences(self.http)
143
+ self.customers = Customers(self.http)
144
+ self.products = Products(self.http)
145
+ self.prices = Prices(self.http)
146
+ self.purchase_intents = PurchaseIntents(self.http)
147
+ self.refunds = Refunds(self.http)
148
+ self.chimes = Chimes(self.http)
149
+ self.schedules = Schedules(self.http)
150
+ self.broadcasts = Broadcasts(self.http)
151
+ self.message_templates = MessageTemplates(self.http)
152
+ self.otp = Otp(self.http)
153
+ self.apps = Apps(self.http)
154
+ self.keys = Keys(self.http)
155
+ self.spec = Spec(self.http)
156
+ self.balances = Balances(self.http)
157
+ self.upload_requests = UploadRequests(self.http)
inttegro/enums.py ADDED
@@ -0,0 +1,401 @@
1
+ """Typed string constants for enums published by the Inttegro API."""
2
+
3
+ from enum import Enum
4
+
5
+
6
+ class WireEnum(str, Enum):
7
+ """A JSON-compatible string enum used on the Inttegro API wire."""
8
+
9
+ def __str__(self) -> str:
10
+ return self.value
11
+
12
+
13
+ class AppManagementRole(WireEnum):
14
+ PARENT = "parent"
15
+ CHILD = "child"
16
+
17
+
18
+ class AppCredentialOwner(WireEnum):
19
+ CHILD = "child"
20
+ PARENT = "parent"
21
+
22
+
23
+ class AppRelationshipKind(WireEnum):
24
+ PLACEMENT = "placement"
25
+
26
+
27
+ class AppRelationshipStatus(WireEnum):
28
+ ACTIVE = "active"
29
+ INACTIVE = "inactive"
30
+ SUSPENDED = "suspended"
31
+ REVOKED = "revoked"
32
+
33
+
34
+ class SecretKeyTokenType(WireEnum):
35
+ BEARER = "bearer"
36
+
37
+
38
+ class SecretKeyStatus(WireEnum):
39
+ ACTIVE = "active"
40
+ REVOKED = "revoked"
41
+ EXPIRED = "expired"
42
+
43
+
44
+ class SecretKeyAuthResult(WireEnum):
45
+ SUCCEEDED = "succeeded"
46
+ FAILED = "failed"
47
+
48
+
49
+ class FileStatus(WireEnum):
50
+ UPLOADING = "uploading"
51
+ PROCESSING = "processing"
52
+ AVAILABLE = "available"
53
+ FAILED = "failed"
54
+ DELETED = "deleted"
55
+
56
+
57
+ class FileDisposition(WireEnum):
58
+ ATTACHMENT = "attachment"
59
+ INLINE = "inline"
60
+
61
+
62
+ class FileDelivery(WireEnum):
63
+ STREAM = "stream"
64
+ REDIRECT = "redirect"
65
+
66
+
67
+ class FileScanStatus(WireEnum):
68
+ PENDING = "pending"
69
+ PASSED = "passed"
70
+ FAILED = "failed"
71
+ SKIPPED = "skipped"
72
+
73
+
74
+ class FileSourceType(WireEnum):
75
+ DIRECT = "direct"
76
+ UPLOAD_REQUEST = "upload_request"
77
+ SERVICE = "service"
78
+
79
+
80
+ class FileStorageEncoding(WireEnum):
81
+ IDENTITY = "identity"
82
+ BROTLI = "br"
83
+
84
+
85
+ class FileLinkStatus(WireEnum):
86
+ ACTIVE = "active"
87
+ REVOKED = "revoked"
88
+ EXPIRED = "expired"
89
+ DISABLED = "disabled"
90
+
91
+
92
+ class FileLinkKind(WireEnum):
93
+ PUBLIC = "public"
94
+
95
+
96
+ class FileLinkDeliveryMode(WireEnum):
97
+ REDIRECT = "redirect"
98
+ DOWNLOAD = "download"
99
+ INLINE = "inline"
100
+
101
+
102
+ class UploadRequestStatus(WireEnum):
103
+ PENDING = "pending"
104
+ UPLOADING = "uploading"
105
+ FULFILLED = "fulfilled"
106
+ EXPIRED = "expired"
107
+ CANCELED = "canceled"
108
+ FAILED = "failed"
109
+
110
+
111
+ class UploadReviewDecision(WireEnum):
112
+ APPROVED = "approved"
113
+ REJECTED = "rejected"
114
+
115
+
116
+ class UploadReviewType(WireEnum):
117
+ AUTOMATIC = "automatic"
118
+ MANUAL = "manual"
119
+
120
+
121
+ class PaymentNextActionType(WireEnum):
122
+ CONFIRM_PAYMENT = "confirm_payment"
123
+ EXECUTE = "execute"
124
+ REDIRECT = "redirect"
125
+ AUTHORIZE = "authorize"
126
+ NONE = "none"
127
+
128
+
129
+ class PaymentConfirmationChannel(WireEnum):
130
+ SMS = "sms"
131
+ EMAIL = "email"
132
+ PUSH = "push"
133
+
134
+
135
+ class PaymentMethodType(WireEnum):
136
+ MOBILE_MONEY = "mobile_money"
137
+ BANK_ACCOUNT = "bank_account"
138
+ CARD = "card"
139
+ MOTITO = "motito"
140
+
141
+
142
+ class MobileMoneyNetwork(WireEnum):
143
+ AIRTEL = "airtel"
144
+ MTN = "mtn"
145
+ TELECEL = "telecel"
146
+ VODAFONE = "vodafone"
147
+
148
+
149
+ class ProductType(WireEnum):
150
+ PHYSICAL = "physical"
151
+ DIGITAL = "digital"
152
+ SERVICE = "service"
153
+ VOUCHER = "voucher"
154
+ CUSTOM = "custom"
155
+ CAUSE = "cause"
156
+
157
+
158
+ class ProductShipmentType(WireEnum):
159
+ DELIVERY = "delivery"
160
+ DOWNLOAD = "download"
161
+ RENDER = "render"
162
+ SERVICE = "service"
163
+ STREAM = "stream"
164
+
165
+
166
+ class ProductShipmentInputType(WireEnum):
167
+ DELIVERY = "delivery"
168
+ DOWNLOAD = "download"
169
+ RENDER = "render"
170
+ STREAM = "stream"
171
+
172
+
173
+ class LineItemType(WireEnum):
174
+ PRODUCT = "product"
175
+ FEE = "fee"
176
+ SHIPPING = "shipping"
177
+
178
+
179
+ class PurchaseIntentStatus(WireEnum):
180
+ ACTIVE = "active"
181
+ EXPIRED = "expired"
182
+ INACTIVE = "inactive"
183
+ USED = "used"
184
+
185
+
186
+ class PurchaseIntentActivityType(WireEnum):
187
+ EXPIRED_VIEWED = "expired_viewed"
188
+ ORDER_CREATED = "order_created"
189
+ PAYMENT_FAILED = "payment_failed"
190
+ PAYMENT_STARTED = "payment_started"
191
+ VIEWED = "viewed"
192
+
193
+
194
+ class FinancialAccountType(WireEnum):
195
+ WALLET = "wallet"
196
+ BANK_ACCOUNT = "bank_account"
197
+ DOSH_ACCOUNT = "dosh_account"
198
+
199
+
200
+ class WalletType(WireEnum):
201
+ MOBILE_MONEY = "mobile_money"
202
+
203
+
204
+ class BankAccountType(WireEnum):
205
+ GHANA_BANK_ACCOUNT = "ghana_bank_account"
206
+
207
+
208
+ class MessageTemplateChannel(WireEnum):
209
+ SMS = "sms"
210
+ EMAIL = "email"
211
+
212
+
213
+ class MessageTemplateStatus(WireEnum):
214
+ DRAFT = "draft"
215
+ PUBLISHED = "published"
216
+ ARCHIVED = "archived"
217
+
218
+
219
+ class MessageTemplateVariableType(WireEnum):
220
+ STRING = "string"
221
+ NUMBER = "number"
222
+ INTEGER = "integer"
223
+ BOOLEAN = "boolean"
224
+ URL = "url"
225
+ EMAIL = "email"
226
+ PHONE = "phone"
227
+ DATE = "date"
228
+ DATETIME = "datetime"
229
+ ARRAY = "array"
230
+
231
+
232
+ class MessageTemplateVariableItemType(WireEnum):
233
+ STRING = "string"
234
+ NUMBER = "number"
235
+ INTEGER = "integer"
236
+ BOOLEAN = "boolean"
237
+ URL = "url"
238
+ EMAIL = "email"
239
+ PHONE = "phone"
240
+ DATE = "date"
241
+ DATETIME = "datetime"
242
+
243
+
244
+ class ContentSafetyStatus(WireEnum):
245
+ ALLOWED = "allowed"
246
+ REJECTED = "rejected"
247
+ QUARANTINED = "quarantined"
248
+
249
+
250
+ class OrderDocumentKind(WireEnum):
251
+ INVOICE = "invoice"
252
+ RECEIPT = "receipt"
253
+
254
+
255
+ class DeliveryChannel(WireEnum):
256
+ EMAIL = "email"
257
+ SMS = "sms"
258
+
259
+
260
+ class CheckoutOrderStatus(WireEnum):
261
+ PREPARING = "preparing"
262
+ REQUIRES_PAYMENT = "requires_payment"
263
+ COMPLETED = "completed"
264
+ CANCELED = "canceled"
265
+ EXPIRED = "expired"
266
+
267
+
268
+ class OrderStatus(WireEnum):
269
+ PREPARING = "preparing"
270
+ REQUIRES_PAYMENT = "requires_payment"
271
+ PAID = "paid"
272
+ COMPLETED = "completed"
273
+ CANCELED = "canceled"
274
+ EXPIRED = "expired"
275
+ UNKNOWN = "unknown"
276
+
277
+
278
+ class OrderPaymentStatus(WireEnum):
279
+ INITIATED = "initiated"
280
+ REQUIRES_ACTION = "requires_action"
281
+ OVERDUE = "overdue"
282
+ EXECUTED = "executed"
283
+ PAID = "paid"
284
+ CANCELED = "canceled"
285
+ EXPIRED = "expired"
286
+ FAILED = "failed"
287
+ UNKNOWN = "unknown"
288
+
289
+
290
+ class PaymentAttemptStatus(WireEnum):
291
+ INITIATED = "initiated"
292
+ EXECUTED = "executed"
293
+ SUCCEEDED = "succeeded"
294
+ CANCELED = "canceled"
295
+ EXPIRED = "expired"
296
+ FAILED = "failed"
297
+ UNKNOWN = "unknown"
298
+
299
+
300
+ class CheckoutPaymentStatus(WireEnum):
301
+ REQUIRES_ACTION = "requires_action"
302
+ PROCESSING = "processing"
303
+ SUCCEEDED = "succeeded"
304
+ FAILED = "failed"
305
+ CANCELLED = "cancelled"
306
+
307
+
308
+ class PaymentResponseStatus(WireEnum):
309
+ PENDING = "pending"
310
+ REQUIRES_CONFIRMATION = "requires_confirmation"
311
+ PROCESSING = "processing"
312
+ SUCCEEDED = "succeeded"
313
+ FAILED = "failed"
314
+
315
+
316
+ class OrderCreatedFromResourceType(WireEnum):
317
+ PURCHASE_INTENT = "purchase_intent"
318
+
319
+
320
+ class RefundReason(WireEnum):
321
+ REQUESTED_BY_CUSTOMER = "requested_by_customer"
322
+ DUPLICATE = "duplicate"
323
+ FRAUDULENT = "fraudulent"
324
+ ORDER_CANCELED = "order_canceled"
325
+ ITEM_RETURNED = "item_returned"
326
+ ITEM_DAMAGED = "item_damaged"
327
+ ITEM_NOT_RECEIVED = "item_not_received"
328
+ ITEM_NOT_AS_DESCRIBED = "item_not_as_described"
329
+ CUSTOM = "custom"
330
+
331
+
332
+ class RefundStatus(WireEnum):
333
+ CANCELED = "canceled"
334
+ FAILED = "failed"
335
+ PENDING = "pending"
336
+ PROCESSING = "processing"
337
+ SUCCEEDED = "succeeded"
338
+
339
+
340
+ class BalanceTransactionType(WireEnum):
341
+ PAYMENT = "payment"
342
+ REFUND = "refund"
343
+
344
+
345
+ class PayoutStatus(WireEnum):
346
+ INITIALIZED = "initialized"
347
+ SCHEDULED = "scheduled"
348
+ PROCESSING = "processing"
349
+ EXECUTING = "executing"
350
+ SUCCEEDED = "succeeded"
351
+ INVALID = "invalid"
352
+ CANCELED = "canceled"
353
+
354
+
355
+ class ChimeRecipientType(WireEnum):
356
+ PHONE = "phone"
357
+ EMAIL = "email"
358
+
359
+
360
+ class ChimeTransport(WireEnum):
361
+ SMS = "sms"
362
+ EMAIL = "email"
363
+
364
+
365
+ class ChimeEmailSchemaKind(WireEnum):
366
+ GMAIL_VIEW_ACTION = "gmail_view_action"
367
+ SCHEMA_ORG_ORDER = "schema_org_order"
368
+ SCHEMA_ORG_INVOICE = "schema_org_invoice"
369
+
370
+
371
+ class OTPAlphabetType(WireEnum):
372
+ NUMERIC = "numeric"
373
+ ALPHA = "alpha"
374
+ ALPHANUMERIC = "alphanumeric"
375
+
376
+
377
+ class OTPStatus(WireEnum):
378
+ CANCELED = "canceled"
379
+ EXPIRED = "expired"
380
+ PENDING = "pending"
381
+ PENDING_DELIVERY = "pending_delivery"
382
+ PENDING_VERIFICATION = "pending_verification"
383
+ VERIFIED = "verified"
384
+
385
+
386
+ class OTPTransmissionStatus(WireEnum):
387
+ DELIVERED = "delivered"
388
+ FAILED = "failed"
389
+ SUBMITTED = "submitted"
390
+
391
+
392
+ class OTPVerificationVerdict(WireEnum):
393
+ FAIL = "fail"
394
+ PASS = "pass"
395
+
396
+
397
+ __all__ = [
398
+ name
399
+ for name, value in globals().items()
400
+ if isinstance(value, type) and issubclass(value, WireEnum)
401
+ ]
inttegro/errors.py ADDED
@@ -0,0 +1,78 @@
1
+ class InttegroError(Exception):
2
+ """Base error for the Inttegro SDK."""
3
+
4
+
5
+ class NetworkError(InttegroError):
6
+ """Raised for network connectivity errors."""
7
+
8
+ def __init__(self, message: str, original: Exception | None = None):
9
+ super().__init__(message)
10
+ self.original = original
11
+
12
+
13
+ class TimeoutError(NetworkError):
14
+ """Raised when a request times out."""
15
+
16
+
17
+ class APIError(InttegroError):
18
+ """Raised for API errors (HTTP >= 400)."""
19
+
20
+ def __init__(
21
+ self,
22
+ message: str,
23
+ status: int,
24
+ code: str | None = None,
25
+ error_type: str | None = None,
26
+ url: str | None = None,
27
+ detail: str | None = None,
28
+ fix_code: str | None = None,
29
+ cause: str | None = None,
30
+ body=None,
31
+ data=None,
32
+ ):
33
+ super().__init__(message)
34
+ self.status = status
35
+ self.code = code
36
+ self.type = error_type
37
+ self.url = url
38
+ self.detail = detail
39
+ self.fix_code = fix_code
40
+ self.cause = cause
41
+ self.body = body
42
+ self.data = data
43
+
44
+
45
+ class AuthenticationError(APIError):
46
+ """Raised on 401 responses."""
47
+
48
+
49
+ class RateLimitError(APIError):
50
+ """Raised on 429 responses."""
51
+
52
+ def __init__(
53
+ self,
54
+ message: str,
55
+ status: int,
56
+ code: str | None = None,
57
+ error_type: str | None = None,
58
+ url: str | None = None,
59
+ detail: str | None = None,
60
+ fix_code: str | None = None,
61
+ cause: str | None = None,
62
+ body=None,
63
+ data=None,
64
+ retry_after: int | None = None,
65
+ ):
66
+ super().__init__(
67
+ message,
68
+ status=status,
69
+ code=code,
70
+ error_type=error_type,
71
+ url=url,
72
+ detail=detail,
73
+ fix_code=fix_code,
74
+ cause=cause,
75
+ body=body,
76
+ data=data,
77
+ )
78
+ self.retry_after = retry_after