<p align="center">
<a href="https://imgur.com/9t3fDgT"><img src="https://i.imgur.com/9t3fDgT.png" title=Logo" width="500"/></a>
</p>
<p align="center">
<img src="https://img.shields.io/badge/Version-1.0.5-blueviolet" alt="Project Version">
<img src="https://img.shields.io/badge/License-MIT-success" alt="License">
</p>
## О библиотеке 💙
Библиотека **CrystalPayIO** предоставит удобное использование и интеграцию _[CrystalPay](https://crystalpay.io/) API_ в ваши проекты.
> [!TIP]
> **Документация CrystalPAY:** https://docs.crystalpay.io/
В данном репозитории вы найдете способы установки и использования библиотеки.
Если вы обнаружите баги или какие-либо проблемы при использовании прошу отписать в [телеграм](https://t.me/fsoky_community). Данный модуль будет поддерживаться и обновляться. Спасибо, хорошего настроения!
> [!NOTE]
> Чтобы получить _AUTH_LOGIN_ & _AUTH_SECRET_ перейдите в [телеграм бота](https://t.me/CrystalPAY_bot) и создайте новую кассу. \
> В настройках можете включить тестовые платежи.
## Установка 🧡
- Установка, используя пакетный менеджер pip
```
$ pip install crystalpayio
```
- Установка с GitHub *(требуется [git](https://git-scm.com/downloads))*
```
$ git clone https://github.com/Fsoky/crystalpayio
$ cd crystalpayio
$ python setup.py install
```
- Или
```
$ pip install git+https://github.com/Fsoky/crystalpayio
```
## Примеры использования 💜
- Шаблон
```py
import asyncio
from crystalpayio import CrystalPayIO
async def main() -> None:
async with CrystalPayIO("AUTH_LOGIN", "AUTH_SECRET") as crystal:
...
if __name__ == "__main__":
asyncio.run(main())
```
- Доступные методы \
`checkout` - Касса \
`payment` - Платежи \
`invoice` - Инвойсы (чеки) \
`payoff` - Вывод средств \
`ticker` - Доступные валюты и курс \
`history` - История платежей/выводов/общая
```py
async with CrystalPayIO("AUTH_LOGIN", "AUTH_SECRET") as crystal:
# Каждый метод хранится в свойстве, например касса:
checkout = await crystal.checkout.me()
```
## Пример интеграции в телеграм-бота (aiogram 3.x) ❤
```py
import asyncio
from aiogram import Router, Bot, Dispatcher, F
from aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
from aiogram.filters import CommandStart
from crystalpayio import CrystalPayIO
router = Router()
crystal = CrystalPayIO("AUTH_LOGIN", "AUTH_SECRET")
async def create_invoice() -> tuple:
invoice = await crystal.invoice.create(
100, # Цена
5, # Время жизни чека (в минутах)
amount_currency="RUB" # Валюта
)
return (invoice.url, invoice.id)
async def invoice_handler(id: str, message: Message) -> None:
while True:
invoice = await crystal.invoice.get(id)
if invoice.state != "notpayed":
await message.answer("Счёт успешно оплачен!")
await asyncio.sleep(15) # Задержка
@router.message(CommandStart())
async def show_goods(message: Message) -> None:
await message.answer(
"🎃 Тыква - 100 РУБ.",
reply_markup=InlineKeyboardMarkup(
inline_keyboard=[
[InlineKeyboardButton(text="КУПИТЬ", callback_data="buy")]
]
)
)
@router.callback_query(F.data == "buy")
async def buy_handler(query: CallbackQuery) -> None:
invoice_task = asyncio.create_task(create_invoice())
invoice_result = await invoice_task
await query.message.answer(f"Перейди по ссылке и оплати: {invoice_result[0]}")
await query.answer()
asyncio.create_task(invoice_handler(invoice_result[1], query.message))
async def main() -> None:
bot = Bot("TOKEN")
dp = Dispatcher()
dp.include_router(router)
await bot.delete_webhook(True)
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())
```
## Пример использования Webhook'ов 🕸
```py
import asyncio
from crystalpayio import CrystalPayIO, WebhookManager, PaymentEvent
from fastapi import FastAPI # pip install fastapi[all]
import uvicorn # pip install uvicorn
WEBHOOK_URL = "https://xxx-xxx-xxx.ngrok-free.app" # ngrok url
WEBHOOK_ENDPOINT = "/my-endpoint"
app = FastAPI()
crystal = CrystalPayIO("AUTH_LOGIN", "AUTH_SECRET")
wm = WebhookManager(app)
wm.register_webhook_endpoint(WEBHOOK_ENDPOINT) # Регистрируем путь к вебхуку
@wm.successfull_payment()
async def handle_successfull_event(event: PaymentEvent) -> None:
print(event)
async def create_invoice() -> None:
order = await crystal.invoice.create(
10, # Сумма (в рублях)
5, # Время жизни чека (в минутах)
callback_url=f"{WEBHOOK_URL}{WEBHOOK_ENDPOINT}"
)
print(order.url)
if __name__ == "__main__":
asyncio.run(create_invoice()) # Запуск функции
uvicorn.run("test:app")
```
Raw data
{
"_id": null,
"home_page": "https://github.com/Fsoky/aiocrystalpay",
"name": "crystalpayio",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "api crystalpay asyncio crypto",
"author": "Fsoky",
"author_email": "cyberuest0x12@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/75/a8/edec0d99b8cfa2cdd4b47fbfc12413cba88f8f12e7cb1230ba017c80cf2d/crystalpayio-1.0.5.tar.gz",
"platform": null,
"description": "<p align=\"center\">\n <a href=\"https://imgur.com/9t3fDgT\"><img src=\"https://i.imgur.com/9t3fDgT.png\" title=Logo\" width=\"500\"/></a>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/Version-1.0.5-blueviolet\" alt=\"Project Version\">\n <img src=\"https://img.shields.io/badge/License-MIT-success\" alt=\"License\">\n</p>\n\n## \u041e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \ud83d\udc99\n\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 **CrystalPayIO** \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442 \u0443\u0434\u043e\u0431\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e _[CrystalPay](https://crystalpay.io/) API_ \u0432 \u0432\u0430\u0448\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u044b.\n\n> [!TIP]\n> **\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f CrystalPAY:** https://docs.crystalpay.io/\n\n\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.\n\u0415\u0441\u043b\u0438 \u0432\u044b \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u0435 \u0431\u0430\u0433\u0438 \u0438\u043b\u0438 \u043a\u0430\u043a\u0438\u0435-\u043b\u0438\u0431\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043f\u0440\u043e\u0448\u0443 \u043e\u0442\u043f\u0438\u0441\u0430\u0442\u044c \u0432 [\u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c](https://t.me/fsoky_community). \u0414\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f. \u0421\u043f\u0430\u0441\u0438\u0431\u043e, \u0445\u043e\u0440\u043e\u0448\u0435\u0433\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f!\n> [!NOTE]\n> \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c _AUTH_LOGIN_ & _AUTH_SECRET_ \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u0432 [\u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442\u0430](https://t.me/CrystalPAY_bot) \u0438 \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u0443\u044e \u043a\u0430\u0441\u0441\u0443. \\\n> \u0412 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u043f\u043b\u0430\u0442\u0435\u0436\u0438.\n\n## \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \ud83e\udde1\n- \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u0430\u043a\u0435\u0442\u043d\u044b\u0439 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 pip\n```\n$ pip install crystalpayio\n```\n- \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441 GitHub *(\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f [git](https://git-scm.com/downloads))*\n```\n$ git clone https://github.com/Fsoky/crystalpayio\n$ cd crystalpayio\n$ python setup.py install\n```\n- \u0418\u043b\u0438\n```\n$ pip install git+https://github.com/Fsoky/crystalpayio\n```\n\n## \u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \ud83d\udc9c\n- \u0428\u0430\u0431\u043b\u043e\u043d\n```py\nimport asyncio\nfrom crystalpayio import CrystalPayIO\n\n\nasync def main() -> None:\n async with CrystalPayIO(\"AUTH_LOGIN\", \"AUTH_SECRET\") as crystal:\n ...\n\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n- \u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \\\n `checkout` - \u041a\u0430\u0441\u0441\u0430 \\\n `payment` - \u041f\u043b\u0430\u0442\u0435\u0436\u0438 \\\n `invoice` - \u0418\u043d\u0432\u043e\u0439\u0441\u044b (\u0447\u0435\u043a\u0438) \\\n `payoff` - \u0412\u044b\u0432\u043e\u0434 \u0441\u0440\u0435\u0434\u0441\u0442\u0432 \\\n `ticker` - \u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0432\u0430\u043b\u044e\u0442\u044b \u0438 \u043a\u0443\u0440\u0441 \\\n `history` - \u0418\u0441\u0442\u043e\u0440\u0438\u044f \u043f\u043b\u0430\u0442\u0435\u0436\u0435\u0439/\u0432\u044b\u0432\u043e\u0434\u043e\u0432/\u043e\u0431\u0449\u0430\u044f\n```py\nasync with CrystalPayIO(\"AUTH_LOGIN\", \"AUTH_SECRET\") as crystal:\n # \u041a\u0430\u0436\u0434\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043a\u0430\u0441\u0441\u0430:\n checkout = await crystal.checkout.me()\n```\n\n## \u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0432 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c-\u0431\u043e\u0442\u0430 (aiogram 3.x) \u2764\n```py\nimport asyncio\n\nfrom aiogram import Router, Bot, Dispatcher, F\nfrom aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton\nfrom aiogram.filters import CommandStart\n\nfrom crystalpayio import CrystalPayIO\n\nrouter = Router()\ncrystal = CrystalPayIO(\"AUTH_LOGIN\", \"AUTH_SECRET\")\n\n\nasync def create_invoice() -> tuple:\n invoice = await crystal.invoice.create(\n 100, # \u0426\u0435\u043d\u0430\n 5, # \u0412\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u0447\u0435\u043a\u0430 (\u0432 \u043c\u0438\u043d\u0443\u0442\u0430\u0445)\n amount_currency=\"RUB\" # \u0412\u0430\u043b\u044e\u0442\u0430\n )\n return (invoice.url, invoice.id)\n\n\nasync def invoice_handler(id: str, message: Message) -> None:\n while True:\n invoice = await crystal.invoice.get(id)\n \n if invoice.state != \"notpayed\":\n await message.answer(\"\u0421\u0447\u0451\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043e\u043f\u043b\u0430\u0447\u0435\u043d!\")\n await asyncio.sleep(15) # \u0417\u0430\u0434\u0435\u0440\u0436\u043a\u0430\n\n\n@router.message(CommandStart())\nasync def show_goods(message: Message) -> None:\n await message.answer(\n \"\ud83c\udf83 \u0422\u044b\u043a\u0432\u0430 - 100 \u0420\u0423\u0411.\",\n reply_markup=InlineKeyboardMarkup(\n inline_keyboard=[\n [InlineKeyboardButton(text=\"\u041a\u0423\u041f\u0418\u0422\u042c\", callback_data=\"buy\")]\n ]\n )\n )\n\n\n@router.callback_query(F.data == \"buy\")\nasync def buy_handler(query: CallbackQuery) -> None:\n invoice_task = asyncio.create_task(create_invoice())\n invoice_result = await invoice_task\n\n await query.message.answer(f\"\u041f\u0435\u0440\u0435\u0439\u0434\u0438 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u0438 \u043e\u043f\u043b\u0430\u0442\u0438: {invoice_result[0]}\")\n await query.answer()\n\n asyncio.create_task(invoice_handler(invoice_result[1], query.message))\n\n\nasync def main() -> None:\n bot = Bot(\"TOKEN\")\n dp = Dispatcher()\n\n dp.include_router(router)\n\n await bot.delete_webhook(True)\n await dp.start_polling(bot)\n\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\n## \u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f Webhook'\u043e\u0432 \ud83d\udd78\n```py\nimport asyncio\n\nfrom crystalpayio import CrystalPayIO, WebhookManager, PaymentEvent\n\nfrom fastapi import FastAPI # pip install fastapi[all]\nimport uvicorn # pip install uvicorn\n\nWEBHOOK_URL = \"https://xxx-xxx-xxx.ngrok-free.app\" # ngrok url\nWEBHOOK_ENDPOINT = \"/my-endpoint\"\n\napp = FastAPI()\ncrystal = CrystalPayIO(\"AUTH_LOGIN\", \"AUTH_SECRET\")\nwm = WebhookManager(app)\n\nwm.register_webhook_endpoint(WEBHOOK_ENDPOINT) # \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u0443\u0442\u044c \u043a \u0432\u0435\u0431\u0445\u0443\u043a\u0443\n\n\n@wm.successfull_payment()\nasync def handle_successfull_event(event: PaymentEvent) -> None:\n print(event)\n\n\nasync def create_invoice() -> None:\n order = await crystal.invoice.create(\n 10, # \u0421\u0443\u043c\u043c\u0430 (\u0432 \u0440\u0443\u0431\u043b\u044f\u0445)\n 5, # \u0412\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u0447\u0435\u043a\u0430 (\u0432 \u043c\u0438\u043d\u0443\u0442\u0430\u0445)\n callback_url=f\"{WEBHOOK_URL}{WEBHOOK_ENDPOINT}\"\n )\n print(order.url)\n\n\nif __name__ == \"__main__\":\n asyncio.run(create_invoice()) # \u0417\u0430\u043f\u0443\u0441\u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0438\n uvicorn.run(\"test:app\")\n```\n\n",
"bugtrack_url": null,
"license": "",
"summary": "Asynchronous wrapper for CrystalPay API",
"version": "1.0.5",
"project_urls": {
"Homepage": "https://github.com/Fsoky/aiocrystalpay"
},
"split_keywords": [
"api",
"crystalpay",
"asyncio",
"crypto"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "75a8edec0d99b8cfa2cdd4b47fbfc12413cba88f8f12e7cb1230ba017c80cf2d",
"md5": "2084525f4a2c0f80d75b509d6cfc5716",
"sha256": "ece27c207b3e9af96867673787474c33404c50080c8a84701e917cd66570f8fc"
},
"downloads": -1,
"filename": "crystalpayio-1.0.5.tar.gz",
"has_sig": false,
"md5_digest": "2084525f4a2c0f80d75b509d6cfc5716",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 10912,
"upload_time": "2023-11-21T12:11:31",
"upload_time_iso_8601": "2023-11-21T12:11:31.111845Z",
"url": "https://files.pythonhosted.org/packages/75/a8/edec0d99b8cfa2cdd4b47fbfc12413cba88f8f12e7cb1230ba017c80cf2d/crystalpayio-1.0.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-11-21 12:11:31",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Fsoky",
"github_project": "aiocrystalpay",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "crystalpayio"
}