kobil-payment 1.2.0__tar.gz
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.
- kobil_payment-1.2.0/PKG-INFO +53 -0
- kobil_payment-1.2.0/README.md +42 -0
- kobil_payment-1.2.0/kobil/payment/__init__.py +187 -0
- kobil_payment-1.2.0/kobil_payment.egg-info/PKG-INFO +53 -0
- kobil_payment-1.2.0/kobil_payment.egg-info/SOURCES.txt +8 -0
- kobil_payment-1.2.0/kobil_payment.egg-info/dependency_links.txt +1 -0
- kobil_payment-1.2.0/kobil_payment.egg-info/requires.txt +1 -0
- kobil_payment-1.2.0/kobil_payment.egg-info/top_level.txt +1 -0
- kobil_payment-1.2.0/pyproject.toml +20 -0
- kobil_payment-1.2.0/setup.cfg +4 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: kobil-payment
|
|
3
|
+
Version: 1.2.0
|
|
4
|
+
Summary: KOBIL Pay (mpay-merchant) client for Python with automatic OAuth token management.
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Repository, https://github.com/uveysservetoglu/kobil-sdks
|
|
7
|
+
Keywords: kobil,payment,mpay,oauth2
|
|
8
|
+
Requires-Python: >=3.8
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
Requires-Dist: kobil-core>=1.0
|
|
11
|
+
|
|
12
|
+
# kobil-payment
|
|
13
|
+
|
|
14
|
+
KOBIL Pay (mpay-merchant) client for Python, with automatic OAuth token management.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install kobil-payment
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Credentials are shared across modules and read from `KOBIL_*` env vars if omitted.
|
|
21
|
+
`merchant_id` defaults to `client_id`. Amounts are in the smallest currency unit
|
|
22
|
+
(`1300` = 13.00 EUR); timeouts in minutes.
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
from kobil.payment import PaymentClient, payment_group
|
|
26
|
+
|
|
27
|
+
payment = PaymentClient(
|
|
28
|
+
payment_base_url="https://pay.cloud.kobil.com/mpay-merchant/create/transaction",
|
|
29
|
+
merchant_name="ISPARK",
|
|
30
|
+
# credentials optional if KOBIL_* env vars are set:
|
|
31
|
+
client_id="...", client_secret="...", token_endpoint="https://idp/token",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
res = payment.create_transaction(
|
|
35
|
+
user_id=user_id,
|
|
36
|
+
amount=1300,
|
|
37
|
+
payment_content=payment_group(("Service Amount", "10.0 TL"), ("Tax Amount", "3.0 TL")),
|
|
38
|
+
)
|
|
39
|
+
# res["transactionId"], res["status"]
|
|
40
|
+
|
|
41
|
+
payment.create_pre_auth_transaction(user_id, 1300)
|
|
42
|
+
payment.post_auth(transaction_id, 40)
|
|
43
|
+
payment.get_status(transaction_id)
|
|
44
|
+
payment.cancel(transaction_id, user_id, cancellation_message="Iptal")
|
|
45
|
+
payment.refund(transaction_id, user_id, 5555, currency="USD")
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Each operation returns the decoded response dict. Failures raise
|
|
49
|
+
`kobil.payment.KobilPaymentError` (subclass of `kobil.core.KobilError`).
|
|
50
|
+
|
|
51
|
+
## License
|
|
52
|
+
|
|
53
|
+
MIT
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# kobil-payment
|
|
2
|
+
|
|
3
|
+
KOBIL Pay (mpay-merchant) client for Python, with automatic OAuth token management.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install kobil-payment
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Credentials are shared across modules and read from `KOBIL_*` env vars if omitted.
|
|
10
|
+
`merchant_id` defaults to `client_id`. Amounts are in the smallest currency unit
|
|
11
|
+
(`1300` = 13.00 EUR); timeouts in minutes.
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from kobil.payment import PaymentClient, payment_group
|
|
15
|
+
|
|
16
|
+
payment = PaymentClient(
|
|
17
|
+
payment_base_url="https://pay.cloud.kobil.com/mpay-merchant/create/transaction",
|
|
18
|
+
merchant_name="ISPARK",
|
|
19
|
+
# credentials optional if KOBIL_* env vars are set:
|
|
20
|
+
client_id="...", client_secret="...", token_endpoint="https://idp/token",
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
res = payment.create_transaction(
|
|
24
|
+
user_id=user_id,
|
|
25
|
+
amount=1300,
|
|
26
|
+
payment_content=payment_group(("Service Amount", "10.0 TL"), ("Tax Amount", "3.0 TL")),
|
|
27
|
+
)
|
|
28
|
+
# res["transactionId"], res["status"]
|
|
29
|
+
|
|
30
|
+
payment.create_pre_auth_transaction(user_id, 1300)
|
|
31
|
+
payment.post_auth(transaction_id, 40)
|
|
32
|
+
payment.get_status(transaction_id)
|
|
33
|
+
payment.cancel(transaction_id, user_id, cancellation_message="Iptal")
|
|
34
|
+
payment.refund(transaction_id, user_id, 5555, currency="USD")
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Each operation returns the decoded response dict. Failures raise
|
|
38
|
+
`kobil.payment.KobilPaymentError` (subclass of `kobil.core.KobilError`).
|
|
39
|
+
|
|
40
|
+
## License
|
|
41
|
+
|
|
42
|
+
MIT
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"""kobil.payment — KOBIL Pay (mpay-merchant) client."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import urllib.parse
|
|
6
|
+
from typing import Any, Dict, List, Optional, Sequence, Tuple
|
|
7
|
+
|
|
8
|
+
from kobil.core import (
|
|
9
|
+
DefaultTokenProvider,
|
|
10
|
+
KobilError,
|
|
11
|
+
ServiceClient,
|
|
12
|
+
TokenProvider,
|
|
13
|
+
credentials_from_env,
|
|
14
|
+
new_uuid,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
__all__ = ["PaymentClient", "KobilPaymentError", "payment_group"]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class KobilPaymentError(KobilError):
|
|
21
|
+
"""Thrown when a payment operation fails."""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def payment_group(*items: Tuple[str, Any]) -> List[List[Dict[str, Any]]]:
|
|
25
|
+
"""Builds a single group of key/value lines.
|
|
26
|
+
|
|
27
|
+
Example: payment_group(("Service Amount", "10.0 TL"), ("Tax Amount", "3.0 TL"))
|
|
28
|
+
"""
|
|
29
|
+
return [[{"key": key, "value": value} for key, value in items]]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class PaymentClient(ServiceClient):
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
*,
|
|
36
|
+
payment_base_url: str,
|
|
37
|
+
merchant_name: str,
|
|
38
|
+
token_endpoint: Optional[str] = None,
|
|
39
|
+
client_id: Optional[str] = None,
|
|
40
|
+
client_secret: Optional[str] = None,
|
|
41
|
+
token_auth_mode: Optional[str] = None,
|
|
42
|
+
merchant_id: Optional[str] = None,
|
|
43
|
+
merchant_service_uuid: Optional[str] = None,
|
|
44
|
+
tenant_id: Optional[str] = None,
|
|
45
|
+
default_currency: str = "EUR",
|
|
46
|
+
default_merchant_callback: Optional[str] = None,
|
|
47
|
+
default_transaction_timeout_minutes: int = 59,
|
|
48
|
+
version: int = 1,
|
|
49
|
+
token_provider: Optional[TokenProvider] = None,
|
|
50
|
+
) -> None:
|
|
51
|
+
credentials = credentials_from_env(
|
|
52
|
+
token_endpoint=token_endpoint,
|
|
53
|
+
client_id=client_id,
|
|
54
|
+
client_secret=client_secret,
|
|
55
|
+
token_auth_mode=token_auth_mode,
|
|
56
|
+
)
|
|
57
|
+
super().__init__(token_provider or DefaultTokenProvider(credentials))
|
|
58
|
+
|
|
59
|
+
if not payment_base_url:
|
|
60
|
+
raise KobilPaymentError("payment_base_url is required.")
|
|
61
|
+
if not merchant_name:
|
|
62
|
+
raise KobilPaymentError("merchant_name is required.")
|
|
63
|
+
|
|
64
|
+
self._base = payment_base_url.rstrip("/")
|
|
65
|
+
self._client_id = credentials.client_id
|
|
66
|
+
self._merchant_name = merchant_name
|
|
67
|
+
self._merchant_id = merchant_id
|
|
68
|
+
self._merchant_service_uuid = merchant_service_uuid
|
|
69
|
+
self._tenant_id = tenant_id
|
|
70
|
+
self._default_currency = default_currency
|
|
71
|
+
self._default_callback = default_merchant_callback
|
|
72
|
+
self._default_timeout = default_transaction_timeout_minutes
|
|
73
|
+
self._version = version
|
|
74
|
+
|
|
75
|
+
def _make_error(self, message, status_code=None, response_body=None, cause=None) -> KobilError:
|
|
76
|
+
return KobilPaymentError(message, status_code, response_body, cause)
|
|
77
|
+
|
|
78
|
+
def create_transaction(
|
|
79
|
+
self,
|
|
80
|
+
user_id: str,
|
|
81
|
+
amount: int,
|
|
82
|
+
payment_content: Optional[Sequence[Sequence[Dict[str, Any]]]] = None,
|
|
83
|
+
currency: Optional[str] = None,
|
|
84
|
+
merchant_callback: Optional[str] = None,
|
|
85
|
+
timeout_minutes: Optional[int] = None,
|
|
86
|
+
idempotency_id: Optional[str] = None,
|
|
87
|
+
) -> Dict[str, Any]:
|
|
88
|
+
return self._create(False, user_id, amount, payment_content, currency, merchant_callback, timeout_minutes, idempotency_id)
|
|
89
|
+
|
|
90
|
+
def create_pre_auth_transaction(
|
|
91
|
+
self,
|
|
92
|
+
user_id: str,
|
|
93
|
+
amount: int,
|
|
94
|
+
payment_content: Optional[Sequence[Sequence[Dict[str, Any]]]] = None,
|
|
95
|
+
currency: Optional[str] = None,
|
|
96
|
+
merchant_callback: Optional[str] = None,
|
|
97
|
+
timeout_minutes: Optional[int] = None,
|
|
98
|
+
idempotency_id: Optional[str] = None,
|
|
99
|
+
) -> Dict[str, Any]:
|
|
100
|
+
return self._create(True, user_id, amount, payment_content, currency, merchant_callback, timeout_minutes, idempotency_id)
|
|
101
|
+
|
|
102
|
+
def _create(self, pre_auth, user_id, amount, payment_content, currency, merchant_callback, timeout_minutes, idempotency_id) -> Dict[str, Any]:
|
|
103
|
+
if not user_id:
|
|
104
|
+
raise KobilPaymentError("user_id cannot be empty.")
|
|
105
|
+
body: Dict[str, Any] = {
|
|
106
|
+
"version": self._version,
|
|
107
|
+
"idempotencyId": idempotency_id or new_uuid(),
|
|
108
|
+
"userId": user_id,
|
|
109
|
+
"merchantId": self._resolve_merchant_id(),
|
|
110
|
+
"merchantServiceUUID": self._resolve_service_uuid(),
|
|
111
|
+
"merchantName": self._merchant_name,
|
|
112
|
+
"merchantCallback": merchant_callback or self._default_callback,
|
|
113
|
+
"transactionTimeout": timeout_minutes or self._default_timeout,
|
|
114
|
+
"tenantId": self._tenant_id,
|
|
115
|
+
"amount": amount,
|
|
116
|
+
"currency": (currency or self._default_currency).upper(),
|
|
117
|
+
"paymentContent": list(payment_content) if payment_content else None,
|
|
118
|
+
}
|
|
119
|
+
if pre_auth:
|
|
120
|
+
body["paymentTenantType"] = "preAuth"
|
|
121
|
+
return self.send_json("POST", self._base, body)
|
|
122
|
+
|
|
123
|
+
def post_auth(self, transaction_id: str, amount: int, merchant_callback: Optional[str] = None, idempotency_id: Optional[str] = None) -> Dict[str, Any]:
|
|
124
|
+
if not transaction_id:
|
|
125
|
+
raise KobilPaymentError("transaction_id cannot be empty.")
|
|
126
|
+
query = {
|
|
127
|
+
"id": transaction_id,
|
|
128
|
+
"idempotencyId": idempotency_id or new_uuid(),
|
|
129
|
+
"amount": str(amount),
|
|
130
|
+
}
|
|
131
|
+
callback = merchant_callback or self._default_callback
|
|
132
|
+
if callback:
|
|
133
|
+
query["merchantCallback"] = callback
|
|
134
|
+
return self.send_json("GET", f"{self._base}/postauth?{urllib.parse.urlencode(query)}")
|
|
135
|
+
|
|
136
|
+
def get_status(self, transaction_id: str, merchant_callback: Optional[str] = None) -> Dict[str, Any]:
|
|
137
|
+
if not transaction_id:
|
|
138
|
+
raise KobilPaymentError("transaction_id cannot be empty.")
|
|
139
|
+
return self.send_json("POST", f"{self._base}/status", {
|
|
140
|
+
"merchantId": self._resolve_merchant_id(),
|
|
141
|
+
"merchantCallback": merchant_callback or self._default_callback,
|
|
142
|
+
"transactionId": transaction_id,
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
def cancel(self, transaction_id: str, user_id: str, cancellation_message: Optional[str] = None,
|
|
146
|
+
merchant_callback: Optional[str] = None, timeout_minutes: Optional[int] = None,
|
|
147
|
+
idempotency_id: Optional[str] = None) -> Dict[str, Any]:
|
|
148
|
+
if not transaction_id or not user_id:
|
|
149
|
+
raise KobilPaymentError("transaction_id and user_id are required.")
|
|
150
|
+
return self.send_json("POST", f"{self._base}/void", {
|
|
151
|
+
"version": self._version,
|
|
152
|
+
"userId": user_id,
|
|
153
|
+
"idempotencyId": idempotency_id or new_uuid(),
|
|
154
|
+
"merchantServiceUUID": self._resolve_service_uuid(),
|
|
155
|
+
"merchantCallback": merchant_callback or self._default_callback,
|
|
156
|
+
"transactionTimeout": timeout_minutes or self._default_timeout,
|
|
157
|
+
"merchantId": self._resolve_merchant_id(),
|
|
158
|
+
"paymentTransactionId": transaction_id,
|
|
159
|
+
"cancellationMessage": cancellation_message,
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
def refund(self, transaction_id: str, user_id: str, amount: int, currency: Optional[str] = None,
|
|
163
|
+
cancellation_message: Optional[str] = None, merchant_callback: Optional[str] = None,
|
|
164
|
+
timeout_minutes: Optional[int] = None, idempotency_id: Optional[str] = None) -> Dict[str, Any]:
|
|
165
|
+
if not transaction_id or not user_id:
|
|
166
|
+
raise KobilPaymentError("transaction_id and user_id are required.")
|
|
167
|
+
service_uuid = self._resolve_service_uuid()
|
|
168
|
+
return self.send_json("POST", f"{self._base}/refund", {
|
|
169
|
+
"version": self._version,
|
|
170
|
+
"userId": user_id,
|
|
171
|
+
"idempotencyId": idempotency_id or new_uuid(),
|
|
172
|
+
"merchantServiceUUID": service_uuid,
|
|
173
|
+
"merchantCallback": merchant_callback or self._default_callback,
|
|
174
|
+
"transactionTimeout": timeout_minutes or self._default_timeout,
|
|
175
|
+
"merchantId": self._resolve_merchant_id(),
|
|
176
|
+
"merchantUserId": user_id,
|
|
177
|
+
"paymentTransactionId": transaction_id,
|
|
178
|
+
"amount": amount,
|
|
179
|
+
"currency": (currency or self._default_currency).upper(),
|
|
180
|
+
"merchantServiceProviderId": service_uuid,
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
def _resolve_merchant_id(self) -> str:
|
|
184
|
+
return self._merchant_id or self._client_id
|
|
185
|
+
|
|
186
|
+
def _resolve_service_uuid(self) -> str:
|
|
187
|
+
return self._merchant_service_uuid or self._resolve_merchant_id()
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: kobil-payment
|
|
3
|
+
Version: 1.2.0
|
|
4
|
+
Summary: KOBIL Pay (mpay-merchant) client for Python with automatic OAuth token management.
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Repository, https://github.com/uveysservetoglu/kobil-sdks
|
|
7
|
+
Keywords: kobil,payment,mpay,oauth2
|
|
8
|
+
Requires-Python: >=3.8
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
Requires-Dist: kobil-core>=1.0
|
|
11
|
+
|
|
12
|
+
# kobil-payment
|
|
13
|
+
|
|
14
|
+
KOBIL Pay (mpay-merchant) client for Python, with automatic OAuth token management.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install kobil-payment
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Credentials are shared across modules and read from `KOBIL_*` env vars if omitted.
|
|
21
|
+
`merchant_id` defaults to `client_id`. Amounts are in the smallest currency unit
|
|
22
|
+
(`1300` = 13.00 EUR); timeouts in minutes.
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
from kobil.payment import PaymentClient, payment_group
|
|
26
|
+
|
|
27
|
+
payment = PaymentClient(
|
|
28
|
+
payment_base_url="https://pay.cloud.kobil.com/mpay-merchant/create/transaction",
|
|
29
|
+
merchant_name="ISPARK",
|
|
30
|
+
# credentials optional if KOBIL_* env vars are set:
|
|
31
|
+
client_id="...", client_secret="...", token_endpoint="https://idp/token",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
res = payment.create_transaction(
|
|
35
|
+
user_id=user_id,
|
|
36
|
+
amount=1300,
|
|
37
|
+
payment_content=payment_group(("Service Amount", "10.0 TL"), ("Tax Amount", "3.0 TL")),
|
|
38
|
+
)
|
|
39
|
+
# res["transactionId"], res["status"]
|
|
40
|
+
|
|
41
|
+
payment.create_pre_auth_transaction(user_id, 1300)
|
|
42
|
+
payment.post_auth(transaction_id, 40)
|
|
43
|
+
payment.get_status(transaction_id)
|
|
44
|
+
payment.cancel(transaction_id, user_id, cancellation_message="Iptal")
|
|
45
|
+
payment.refund(transaction_id, user_id, 5555, currency="USD")
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Each operation returns the decoded response dict. Failures raise
|
|
49
|
+
`kobil.payment.KobilPaymentError` (subclass of `kobil.core.KobilError`).
|
|
50
|
+
|
|
51
|
+
## License
|
|
52
|
+
|
|
53
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
kobil-core>=1.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
kobil
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "kobil-payment"
|
|
7
|
+
version = "1.2.0"
|
|
8
|
+
description = "KOBIL Pay (mpay-merchant) client for Python with automatic OAuth token management."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
requires-python = ">=3.8"
|
|
12
|
+
keywords = ["kobil", "payment", "mpay", "oauth2"]
|
|
13
|
+
dependencies = ["kobil-core>=1.0"]
|
|
14
|
+
|
|
15
|
+
[project.urls]
|
|
16
|
+
Repository = "https://github.com/uveysservetoglu/kobil-sdks"
|
|
17
|
+
|
|
18
|
+
[tool.setuptools.packages.find]
|
|
19
|
+
include = ["kobil*"]
|
|
20
|
+
namespaces = true
|