payme-pkg 2.6.7__py3-none-any.whl → 3.0.17__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.
Potentially problematic release.
This version of payme-pkg might be problematic. Click here for more details.
- payme/__init__.py +1 -0
- payme/admin.py +12 -6
- payme/apps.py +0 -4
- payme/classes/cards.py +203 -0
- payme/classes/client.py +30 -0
- payme/classes/http.py +107 -0
- payme/classes/initializer.py +82 -0
- payme/classes/receipts.py +298 -0
- payme/const.py +12 -0
- payme/exceptions/__init__.py +5 -0
- payme/exceptions/general.py +275 -0
- payme/exceptions/webhook.py +125 -0
- payme/models.py +113 -46
- payme/types/response/__init__.py +4 -0
- payme/types/response/cards.py +110 -0
- payme/types/response/receipts.py +215 -0
- payme/types/response/webhook.py +136 -0
- payme/urls.py +2 -2
- payme/util.py +26 -0
- payme/views.py +287 -113
- payme_pkg-3.0.17.dist-info/METADATA +193 -0
- payme_pkg-3.0.17.dist-info/RECORD +29 -0
- payme_pkg-3.0.17.dist-info/top_level.txt +1 -0
- core/asgi.py +0 -16
- core/settings.py +0 -133
- core/urls.py +0 -25
- core/wsgi.py +0 -16
- my_app/admin.py +0 -3
- my_app/apps.py +0 -6
- my_app/models.py +0 -3
- my_app/tests.py +0 -3
- my_app/views.py +0 -16
- payme/cards/__init__.py +0 -1
- payme/cards/subscribe_cards.py +0 -166
- payme/decorators/__init__.py +0 -0
- payme/decorators/decorators.py +0 -34
- payme/errors/__init__.py +0 -0
- payme/errors/exceptions.py +0 -89
- payme/methods/__init__.py +0 -0
- payme/methods/cancel_transaction.py +0 -54
- payme/methods/check_perform_transaction.py +0 -26
- payme/methods/check_transaction.py +0 -43
- payme/methods/create_transaction.py +0 -68
- payme/methods/generate_link.py +0 -83
- payme/methods/get_statement.py +0 -65
- payme/methods/perform_transaction.py +0 -47
- payme/migrations/0001_initial.py +0 -48
- payme/receipts/__init__.py +0 -1
- payme/receipts/subscribe_receipts.py +0 -217
- payme/serializers.py +0 -86
- payme/utils/__init__.py +0 -0
- payme/utils/get_params.py +0 -24
- payme/utils/logging.py +0 -9
- payme/utils/make_aware_datetime.py +0 -21
- payme/utils/support.py +0 -8
- payme/utils/to_json.py +0 -13
- payme_pkg-2.6.7.dist-info/METADATA +0 -13
- payme_pkg-2.6.7.dist-info/RECORD +0 -48
- payme_pkg-2.6.7.dist-info/top_level.txt +0 -3
- {core → payme/classes}/__init__.py +0 -0
- {my_app → payme/types}/__init__.py +0 -0
- {my_app/migrations → payme/types/request}/__init__.py +0 -0
- {payme_pkg-2.6.7.dist-info → payme_pkg-3.0.17.dist-info}/LICENSE.txt +0 -0
- {payme_pkg-2.6.7.dist-info → payme_pkg-3.0.17.dist-info}/WHEEL +0 -0
payme/__init__.py
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from payme.classes.client import Payme # noqa
|
payme/admin.py
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
from django.contrib import admin
|
|
2
2
|
|
|
3
|
-
from payme.models import CUSTOM_ORDER
|
|
4
|
-
from payme.models import Order as DefaultOrderModel
|
|
5
3
|
|
|
6
|
-
from payme.models import
|
|
4
|
+
from payme.models import PaymeTransactions
|
|
7
5
|
|
|
8
|
-
if not CUSTOM_ORDER:
|
|
9
|
-
admin.site.register(DefaultOrderModel)
|
|
10
6
|
|
|
11
|
-
admin.
|
|
7
|
+
class PaymeTransactionsUI(admin.ModelAdmin):
|
|
8
|
+
"""
|
|
9
|
+
Custom admin interface for PaymeTransactions model.
|
|
10
|
+
"""
|
|
11
|
+
list_display = ('id', 'state', 'cancel_reason', 'created_at')
|
|
12
|
+
list_filter = ('state', 'cancel_reason', 'created_at')
|
|
13
|
+
search_fields = ('transaction_id', 'account__id')
|
|
14
|
+
ordering = ('-created_at',)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
admin.site.register(PaymeTransactions, PaymeTransactionsUI)
|
payme/apps.py
CHANGED
payme/classes/cards.py
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from payme.classes.http import HttpClient
|
|
4
|
+
from payme.types.response import cards as response
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
ALLOWED_METHODS = {
|
|
8
|
+
"cards.create": response.CardsCreateResponse,
|
|
9
|
+
"cards.get_verify_code": response.GetVerifyResponse,
|
|
10
|
+
"cards.verify": response.VerifyResponse,
|
|
11
|
+
"cards.remove": response.RemoveResponse,
|
|
12
|
+
"cards.check": response.CheckResponse
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Cards:
|
|
17
|
+
"""
|
|
18
|
+
The Cards class provides a simple interface to interact with Paycom card
|
|
19
|
+
services. It allows you to create new cards and retrieve verification
|
|
20
|
+
codes for existing cards.
|
|
21
|
+
"""
|
|
22
|
+
def __init__(self, url: str, payme_id: str) -> "Cards":
|
|
23
|
+
"""
|
|
24
|
+
Initialize the Cards client.
|
|
25
|
+
|
|
26
|
+
:param payme_id: The Paycom ID used for authentication.
|
|
27
|
+
:param url: The base URL for the Paycom card service API.
|
|
28
|
+
"""
|
|
29
|
+
headers = {
|
|
30
|
+
"X-Auth": payme_id,
|
|
31
|
+
"Content-Type": "application/json"
|
|
32
|
+
}
|
|
33
|
+
self.http = HttpClient(url, headers)
|
|
34
|
+
|
|
35
|
+
def create(self, number: str, expire: str, save: bool = False,
|
|
36
|
+
timeout: int = 10) -> response.CardsCreateResponse:
|
|
37
|
+
"""
|
|
38
|
+
Create a new card.
|
|
39
|
+
|
|
40
|
+
:param number: The card number.
|
|
41
|
+
:param expire: The expiration date of the card in MMYY format.
|
|
42
|
+
:param save: A boolean indicating whether to save the card for future
|
|
43
|
+
use (default is False).
|
|
44
|
+
:param timeout: The request timeout duration in seconds (default is
|
|
45
|
+
10 seconds).
|
|
46
|
+
:return: A CardsCreateResponse object containing the response data.
|
|
47
|
+
"""
|
|
48
|
+
method = "cards.create"
|
|
49
|
+
params = {"card": {"number": number, "expire": expire}, "save": save}
|
|
50
|
+
return self._post_request(method, params, timeout)
|
|
51
|
+
|
|
52
|
+
def get_verify_code(self, token: str, timeout: int = 10) -> \
|
|
53
|
+
response.GetVerifyResponse:
|
|
54
|
+
"""
|
|
55
|
+
Retrieve a verification code for a specified token.
|
|
56
|
+
|
|
57
|
+
:param token: The token associated with the card.
|
|
58
|
+
:param timeout: The request timeout duration in seconds (default is
|
|
59
|
+
10 seconds).
|
|
60
|
+
:return: A GetVerifyResponse object containing the response data.
|
|
61
|
+
"""
|
|
62
|
+
method = "cards.get_verify_code"
|
|
63
|
+
params = {"token": token}
|
|
64
|
+
return self._post_request(method, params, timeout)
|
|
65
|
+
|
|
66
|
+
def verify(self, token: str, code: str, timeout: int = 10) -> \
|
|
67
|
+
response.VerifyResponse:
|
|
68
|
+
"""
|
|
69
|
+
Verify a verification code for a specified token.
|
|
70
|
+
|
|
71
|
+
:param token: The token associated with the card.
|
|
72
|
+
:param code: The verification code to be verified.
|
|
73
|
+
:param timeout: The request timeout duration in seconds (default is
|
|
74
|
+
10 seconds).
|
|
75
|
+
:return: A VerifyResponse object containing the response data.
|
|
76
|
+
"""
|
|
77
|
+
method = "cards.verify"
|
|
78
|
+
params = {"token": token, "code": code}
|
|
79
|
+
return self._post_request(method, params, timeout)
|
|
80
|
+
|
|
81
|
+
def remove(self, token: str, timeout: int = 10) -> response.RemoveResponse:
|
|
82
|
+
"""
|
|
83
|
+
Remove a card from the Paycom system.
|
|
84
|
+
|
|
85
|
+
:param token: The token associated with the card.
|
|
86
|
+
:param timeout: The request timeout duration in seconds (default is
|
|
87
|
+
10 seconds).
|
|
88
|
+
:return: A RemoveResponse object containing the response data.
|
|
89
|
+
"""
|
|
90
|
+
method = "cards.remove"
|
|
91
|
+
params = {"token": token}
|
|
92
|
+
return self._post_request(method, params, timeout)
|
|
93
|
+
|
|
94
|
+
def check(self, token: str, timeout: int = 10) -> response.CheckResponse:
|
|
95
|
+
"""
|
|
96
|
+
Check the status of a card.
|
|
97
|
+
|
|
98
|
+
:param token: The token associated with the card.
|
|
99
|
+
:param timeout: The request timeout duration in seconds (default is
|
|
100
|
+
10 seconds).
|
|
101
|
+
:return: A CheckResponse object containing the response data.
|
|
102
|
+
"""
|
|
103
|
+
method = "cards.check"
|
|
104
|
+
params = {"token": token}
|
|
105
|
+
return self._post_request(method, params, timeout)
|
|
106
|
+
|
|
107
|
+
def _post_request(self, method: str, params: dict,
|
|
108
|
+
timeout: int = 10) -> response.Common:
|
|
109
|
+
"""
|
|
110
|
+
Helper method to post requests to the HTTP client.
|
|
111
|
+
|
|
112
|
+
:param method: The API method to be called.
|
|
113
|
+
:param params: The parameters to be sent with the request.
|
|
114
|
+
:param timeout: The request timeout duration in seconds (default is
|
|
115
|
+
10 seconds).
|
|
116
|
+
:return: A response object corresponding to the method called.
|
|
117
|
+
"""
|
|
118
|
+
json = {"method": method, "params": params}
|
|
119
|
+
dict_result = self.http.post(json, timeout)
|
|
120
|
+
response_class = ALLOWED_METHODS[method]
|
|
121
|
+
return response_class.from_dict(dict_result)
|
|
122
|
+
|
|
123
|
+
def test(self):
|
|
124
|
+
"""
|
|
125
|
+
Run a comprehensive test suite for card functionalities including
|
|
126
|
+
creation, verification, status check, and removal.
|
|
127
|
+
"""
|
|
128
|
+
# Expected values for verification
|
|
129
|
+
number = "8600495473316478"
|
|
130
|
+
expire = "0399"
|
|
131
|
+
|
|
132
|
+
expected_number = "860049******6478"
|
|
133
|
+
expected_expire = "03/99"
|
|
134
|
+
verify_code = "666666"
|
|
135
|
+
|
|
136
|
+
# Step 1: Create Card
|
|
137
|
+
create_response = self.create(number=number, expire=expire)
|
|
138
|
+
token = create_response.result.card.token
|
|
139
|
+
|
|
140
|
+
# Validate card creation response
|
|
141
|
+
self._assert_and_print(
|
|
142
|
+
create_response.result.card.number == expected_number,
|
|
143
|
+
"Card number matched.",
|
|
144
|
+
test_case="Card Creation - Number Validation"
|
|
145
|
+
)
|
|
146
|
+
self._assert_and_print(
|
|
147
|
+
create_response.result.card.expire == expected_expire,
|
|
148
|
+
"Expiration date matched.",
|
|
149
|
+
test_case="Card Creation - Expiration Date Validation"
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
# Step 2: Get Verification Code
|
|
153
|
+
get_verify_response = self.get_verify_code(token=token)
|
|
154
|
+
self._assert_and_print(
|
|
155
|
+
get_verify_response.result.sent is True,
|
|
156
|
+
"Verification code requested successfully.",
|
|
157
|
+
test_case="Verification Code Request"
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# Step 3: Verify Code
|
|
161
|
+
verify_response = self.verify(token=token, code=verify_code)
|
|
162
|
+
self._assert_and_print(
|
|
163
|
+
verify_response.result.card.verify is True,
|
|
164
|
+
"Verification code validated successfully.",
|
|
165
|
+
test_case="Code Verification"
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
# Step 4: Check Card Status
|
|
169
|
+
check_response = self.check(token=token)
|
|
170
|
+
self._assert_and_print(
|
|
171
|
+
check_response.result.card.verify is True,
|
|
172
|
+
"Card status verified successfully.",
|
|
173
|
+
test_case="Card Status Check"
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
# Step 5: Remove Card
|
|
177
|
+
remove_response = self.remove(token=token)
|
|
178
|
+
self._assert_and_print(
|
|
179
|
+
remove_response.result.success is True,
|
|
180
|
+
"Card removed successfully.",
|
|
181
|
+
test_case="Card Removal"
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
def _assert_and_print(self, condition: bool, success_message: str,
|
|
185
|
+
test_case: Optional[str] = None):
|
|
186
|
+
"""
|
|
187
|
+
Assertion helper that prints success or failure messages based on
|
|
188
|
+
test outcomes.
|
|
189
|
+
|
|
190
|
+
:param condition: The test condition to check.
|
|
191
|
+
:param success_message: Message to print upon successful test.
|
|
192
|
+
:param test_case: A description of the test case (optional).
|
|
193
|
+
"""
|
|
194
|
+
try:
|
|
195
|
+
assert condition, "Assertion failed!"
|
|
196
|
+
print(f"Success: {success_message}")
|
|
197
|
+
except AssertionError as exc:
|
|
198
|
+
error_message = (
|
|
199
|
+
f"Test Case Failed: {test_case or 'Unknown Test Case'}\n"
|
|
200
|
+
f"Error Details: {str(exc)}"
|
|
201
|
+
)
|
|
202
|
+
print(error_message)
|
|
203
|
+
raise AssertionError(error_message) from exc
|
payme/classes/client.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
from typing import Union
|
|
3
|
+
|
|
4
|
+
from payme.const import Networks
|
|
5
|
+
from payme.classes.cards import Cards
|
|
6
|
+
from payme.classes.receipts import Receipts
|
|
7
|
+
from payme.classes.initializer import Initializer
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Payme:
|
|
11
|
+
"""
|
|
12
|
+
The payme class provides a simple interface
|
|
13
|
+
"""
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
payme_id: str,
|
|
17
|
+
fallback_id: Union[str, None] = None,
|
|
18
|
+
payme_key: Union[str, None] = None,
|
|
19
|
+
is_test_mode: bool = False
|
|
20
|
+
):
|
|
21
|
+
|
|
22
|
+
# initialize payme network
|
|
23
|
+
url = Networks.PROD_NET.value
|
|
24
|
+
|
|
25
|
+
if is_test_mode is True:
|
|
26
|
+
url = Networks.TEST_NET.value
|
|
27
|
+
|
|
28
|
+
self.cards = Cards(url=url, payme_id=payme_id)
|
|
29
|
+
self.initializer = Initializer(payme_id=payme_id, fallback_id=fallback_id)
|
|
30
|
+
self.receipts = Receipts(url=url, payme_id=payme_id, payme_key=payme_key) # noqa
|
payme/classes/http.py
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
|
|
3
|
+
from payme.exceptions import general as exc
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
networking_errors = (
|
|
7
|
+
requests.exceptions.Timeout,
|
|
8
|
+
requests.exceptions.HTTPError,
|
|
9
|
+
requests.exceptions.ConnectionError,
|
|
10
|
+
requests.exceptions.TooManyRedirects,
|
|
11
|
+
requests.exceptions.URLRequired,
|
|
12
|
+
requests.exceptions.MissingSchema,
|
|
13
|
+
requests.exceptions.InvalidURL,
|
|
14
|
+
requests.exceptions.InvalidHeader,
|
|
15
|
+
requests.exceptions.JSONDecodeError,
|
|
16
|
+
requests.exceptions.ConnectTimeout,
|
|
17
|
+
requests.exceptions.ReadTimeout,
|
|
18
|
+
requests.exceptions.SSLError,
|
|
19
|
+
requests.exceptions.ProxyError,
|
|
20
|
+
requests.exceptions.ChunkedEncodingError,
|
|
21
|
+
requests.exceptions.StreamConsumedError,
|
|
22
|
+
requests.exceptions.RequestException
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class HttpClient:
|
|
27
|
+
"""
|
|
28
|
+
A simple HTTP client to handle requests to a specified URL.
|
|
29
|
+
It provides methods for sending GET, POST, PUT, and DELETE requests
|
|
30
|
+
with error handling.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(self, url: str, headers: dict = None):
|
|
34
|
+
"""
|
|
35
|
+
Initialize the HttpClient.
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
url : str
|
|
40
|
+
The base URL for the API (e.g., 'https://checkout.paycom.uz/api').
|
|
41
|
+
headers : dict, optional
|
|
42
|
+
Optional default headers to include in all requests.
|
|
43
|
+
These headers will be sent with every request unless overridden.
|
|
44
|
+
"""
|
|
45
|
+
self.url = url
|
|
46
|
+
self.headers = headers
|
|
47
|
+
|
|
48
|
+
def post(self, json: dict, timeout: int = 10):
|
|
49
|
+
"""
|
|
50
|
+
Send a POST request to the specified URL with the provided JSON data.
|
|
51
|
+
|
|
52
|
+
Parameters
|
|
53
|
+
----------
|
|
54
|
+
json : dict
|
|
55
|
+
The JSON data payload for the POST request. This will be sent
|
|
56
|
+
as the request body.
|
|
57
|
+
timeout : int, optional
|
|
58
|
+
The request timeout duration in seconds (default is 10 seconds).
|
|
59
|
+
|
|
60
|
+
Returns
|
|
61
|
+
-------
|
|
62
|
+
dict
|
|
63
|
+
A dictionary containing the response data if the request was
|
|
64
|
+
successful, or an error message if an error occurred.
|
|
65
|
+
"""
|
|
66
|
+
try:
|
|
67
|
+
response = requests.post(
|
|
68
|
+
url=self.url,
|
|
69
|
+
headers=self.headers,
|
|
70
|
+
json=json,
|
|
71
|
+
timeout=timeout
|
|
72
|
+
)
|
|
73
|
+
response.raise_for_status()
|
|
74
|
+
response_data = response.json()
|
|
75
|
+
|
|
76
|
+
# Check if the response contains a specific error format
|
|
77
|
+
if "error" in response_data:
|
|
78
|
+
return self.handle_payme_error(response_data["error"])
|
|
79
|
+
|
|
80
|
+
return response_data
|
|
81
|
+
|
|
82
|
+
except networking_errors as exc_data:
|
|
83
|
+
raise exc.PaymeNetworkError(data=exc_data)
|
|
84
|
+
|
|
85
|
+
def handle_payme_error(self, error: dict):
|
|
86
|
+
"""
|
|
87
|
+
Handle Paycom-specific errors from the JSON-RPC error response.
|
|
88
|
+
|
|
89
|
+
Parameters
|
|
90
|
+
----------
|
|
91
|
+
error : dict
|
|
92
|
+
The error dictionary from Paycom's response, typically containing
|
|
93
|
+
error details such as code, message, and data.
|
|
94
|
+
|
|
95
|
+
Returns
|
|
96
|
+
-------
|
|
97
|
+
None
|
|
98
|
+
Raises an exception based on the error code received from
|
|
99
|
+
Paycom's response.
|
|
100
|
+
"""
|
|
101
|
+
error_code = error.get("code", "Unknown code")
|
|
102
|
+
error_message = error.get("message", "Unknown error")
|
|
103
|
+
error_data = error.get("data", "")
|
|
104
|
+
|
|
105
|
+
exception_class = exc.errors_map.get(error_code, exc.BaseError)
|
|
106
|
+
exception_class.message = error_message
|
|
107
|
+
raise exception_class(data=error_data)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
|
|
3
|
+
from django.conf import settings
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Initializer:
|
|
7
|
+
"""
|
|
8
|
+
Initialize the Payme class with necessary details.
|
|
9
|
+
|
|
10
|
+
Attributes
|
|
11
|
+
----------
|
|
12
|
+
payme_id: str
|
|
13
|
+
The Payme ID associated with your account
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, payme_id: str = None, fallback_id: str = None):
|
|
17
|
+
self.payme_id = payme_id
|
|
18
|
+
self.fallback_id = fallback_id
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def generate_pay_link(
|
|
22
|
+
self,
|
|
23
|
+
id: int,
|
|
24
|
+
amount: int,
|
|
25
|
+
return_url: str
|
|
26
|
+
) -> str:
|
|
27
|
+
"""
|
|
28
|
+
Generate a payment link for a specific order.
|
|
29
|
+
|
|
30
|
+
This method encodes the payment parameters into a base64 string and
|
|
31
|
+
constructs a URL for the Payme checkout.
|
|
32
|
+
|
|
33
|
+
Parameters
|
|
34
|
+
----------
|
|
35
|
+
id : int
|
|
36
|
+
Unique identifier for the account.
|
|
37
|
+
amount : int
|
|
38
|
+
The amount associated with the order in currency units.
|
|
39
|
+
return_url : str
|
|
40
|
+
The URL to which the user will be redirected after the payment is
|
|
41
|
+
processed.
|
|
42
|
+
|
|
43
|
+
Returns
|
|
44
|
+
-------
|
|
45
|
+
str
|
|
46
|
+
A payment link formatted as a URL, ready to be used in the payment
|
|
47
|
+
process.
|
|
48
|
+
|
|
49
|
+
References
|
|
50
|
+
----------
|
|
51
|
+
For full method documentation, visit:
|
|
52
|
+
https://developer.help.paycom.uz/initsializatsiya-platezhey/
|
|
53
|
+
"""
|
|
54
|
+
amount = amount * 100 # Convert amount to the smallest currency unit
|
|
55
|
+
params = (
|
|
56
|
+
f'm={self.payme_id};ac.{settings.PAYME_ACCOUNT_FIELD}={id};a={amount};c={return_url}'
|
|
57
|
+
)
|
|
58
|
+
params = base64.b64encode(params.encode("utf-8")).decode("utf-8")
|
|
59
|
+
return f"https://checkout.paycom.uz/{params}"
|
|
60
|
+
|
|
61
|
+
def generate_fallback_link(self, form_fields: dict = None):
|
|
62
|
+
"""
|
|
63
|
+
Generate a fallback URL for the Payme checkout.
|
|
64
|
+
|
|
65
|
+
Parameters
|
|
66
|
+
----------
|
|
67
|
+
fields : dict, optional
|
|
68
|
+
Additional query parameters to be appended to the fallback URL.
|
|
69
|
+
|
|
70
|
+
Returns
|
|
71
|
+
-------
|
|
72
|
+
str
|
|
73
|
+
A fallback URL formatted as a URL, ready to be used in the payment
|
|
74
|
+
process.
|
|
75
|
+
"""
|
|
76
|
+
result = f"https://payme.uz/fallback/merchant/?id={self.fallback_id}"
|
|
77
|
+
|
|
78
|
+
if form_fields is not None:
|
|
79
|
+
for key, value in form_fields.items():
|
|
80
|
+
result += f"&{key}={value}"
|
|
81
|
+
|
|
82
|
+
return result
|