github.com
Open in
urlscan Pro
140.82.121.3
Public Scan
Submitted URL: https://sellvpn.ggtm.ru/
Effective URL: https://github.com/WhiteApfel/pyQiwiP2P
Submission: On February 17 via automatic, source certstream-suspicious — Scanned from DE
Effective URL: https://github.com/WhiteApfel/pyQiwiP2P
Submission: On February 17 via automatic, source certstream-suspicious — Scanned from DE
Form analysis
1 forms found in the DOMGET /WhiteApfel/pyQiwiP2P/search
<form class="js-site-search-form" role="search" aria-label="Site" data-scope-type="Repository" data-scope-id="277708555" data-scoped-search-url="/WhiteApfel/pyQiwiP2P/search" data-owner-scoped-search-url="/users/WhiteApfel/search"
data-unscoped-search-url="/search" data-turbo="false" action="/WhiteApfel/pyQiwiP2P/search" accept-charset="UTF-8" method="get">
<label class="form-control header-search-wrapper input-sm p-0 js-chromeless-input-container header-search-wrapper-jump-to position-relative d-flex flex-justify-between flex-items-center">
<input type="text" class="form-control js-site-search-focus header-search-input jump-to-field js-jump-to-field js-site-search-field is-clearable" data-hotkey="s,/" name="q" placeholder="Search" data-unscoped-placeholder="Search GitHub"
data-scoped-placeholder="Search" autocapitalize="off" role="combobox" aria-haspopup="listbox" aria-expanded="false" aria-autocomplete="list" aria-controls="jump-to-results" aria-label="Search"
data-jump-to-suggestions-path="/_graphql/GetSuggestedNavigationDestinations" spellcheck="false" autocomplete="off">
<input type="hidden" data-csrf="true" class="js-data-jump-to-suggestions-path-csrf" value="fJcx8x3S96DXuAuHy/km+NuLroHFCfNL0njwH+DPbBSnZKTiD9E5Lqgx/+PbqM5jVxdUA4hoqym8tJ9RTzOVRA==">
<input type="hidden" class="js-site-search-type-field" name="type">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="20" aria-hidden="true" class="mr-1 header-search-key-slash">
<path fill="none" stroke="#979A9C" opacity=".4" d="M3.5.5h12c1.7 0 3 1.3 3 3v13c0 1.7-1.3 3-3 3h-12c-1.7 0-3-1.3-3-3v-13c0-1.7 1.3-3 3-3z"></path>
<path fill="#979A9C" d="M11.8 6L8 15.1h-.9L10.8 6h1z"></path>
</svg>
<div class="Box position-absolute overflow-hidden d-none jump-to-suggestions js-jump-to-suggestions-container">
<ul class="d-none js-jump-to-suggestions-template-container">
<li class="d-flex flex-justify-start flex-items-center p-0 f5 navigation-item js-navigation-item js-jump-to-suggestion" role="option">
<a tabindex="-1" class="no-underline d-flex flex-auto flex-items-center jump-to-suggestions-path js-jump-to-suggestion-path js-navigation-open p-2" href="" data-item-type="suggestion">
<div class="jump-to-octicon js-jump-to-octicon flex-shrink-0 mr-2 text-center d-none">
<svg title="Repository" aria-label="Repository" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo js-jump-to-octicon-repo d-none flex-shrink-0">
<path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path>
</svg>
<svg title="Project" aria-label="Project" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project js-jump-to-octicon-project d-none flex-shrink-0">
<path fill-rule="evenodd" d="M1.75 0A1.75 1.75 0 000 1.75v12.5C0 15.216.784 16 1.75 16h12.5A1.75 1.75 0 0016 14.25V1.75A1.75 1.75 0 0014.25 0H1.75zM1.5 1.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v12.5a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25V1.75zM11.75 3a.75.75 0 00-.75.75v7.5a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75zm-8.25.75a.75.75 0 011.5 0v5.5a.75.75 0 01-1.5 0v-5.5zM8 3a.75.75 0 00-.75.75v3.5a.75.75 0 001.5 0v-3.5A.75.75 0 008 3z"></path>
</svg>
<svg title="Search" aria-label="Search" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search js-jump-to-octicon-search d-none flex-shrink-0">
<path fill-rule="evenodd" d="M11.5 7a4.499 4.499 0 11-8.998 0A4.499 4.499 0 0111.5 7zm-.82 4.74a6 6 0 111.06-1.06l3.04 3.04a.75.75 0 11-1.06 1.06l-3.04-3.04z"></path>
</svg>
</div>
<img class="avatar mr-2 flex-shrink-0 js-jump-to-suggestion-avatar d-none" alt="" aria-label="Team" src="" width="28" height="28">
<div class="jump-to-suggestion-name js-jump-to-suggestion-name flex-auto overflow-hidden text-left no-wrap css-truncate css-truncate-target">
</div>
<div class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none js-jump-to-badge-search">
<span class="js-jump-to-badge-search-text-default d-none" aria-label="in this repository">
In this repository
</span>
<span class="js-jump-to-badge-search-text-global d-none" aria-label="in all of GitHub">
All GitHub
</span>
<span aria-hidden="true" class="d-inline-block ml-1 v-align-middle">↵</span>
</div>
<div aria-hidden="true" class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none d-on-nav-focus js-jump-to-badge-jump">
Jump to
<span class="d-inline-block ml-1 v-align-middle">↵</span>
</div>
</a>
</li>
</ul>
<ul class="d-none js-jump-to-no-results-template-container">
<li class="d-flex flex-justify-center flex-items-center f5 d-none js-jump-to-suggestion p-2">
<span class="color-fg-muted">No suggested jump to results</span>
</li>
</ul>
<ul id="jump-to-results" role="listbox" class="p-0 m-0 js-navigation-container jump-to-suggestions-results-container js-jump-to-suggestions-results-container">
<li class="d-flex flex-justify-start flex-items-center p-0 f5 navigation-item js-navigation-item js-jump-to-scoped-search d-none" role="option">
<a tabindex="-1" class="no-underline d-flex flex-auto flex-items-center jump-to-suggestions-path js-jump-to-suggestion-path js-navigation-open p-2" href="" data-item-type="scoped_search">
<div class="jump-to-octicon js-jump-to-octicon flex-shrink-0 mr-2 text-center d-none">
<svg title="Repository" aria-label="Repository" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo js-jump-to-octicon-repo d-none flex-shrink-0">
<path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path>
</svg>
<svg title="Project" aria-label="Project" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project js-jump-to-octicon-project d-none flex-shrink-0">
<path fill-rule="evenodd" d="M1.75 0A1.75 1.75 0 000 1.75v12.5C0 15.216.784 16 1.75 16h12.5A1.75 1.75 0 0016 14.25V1.75A1.75 1.75 0 0014.25 0H1.75zM1.5 1.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v12.5a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25V1.75zM11.75 3a.75.75 0 00-.75.75v7.5a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75zm-8.25.75a.75.75 0 011.5 0v5.5a.75.75 0 01-1.5 0v-5.5zM8 3a.75.75 0 00-.75.75v3.5a.75.75 0 001.5 0v-3.5A.75.75 0 008 3z"></path>
</svg>
<svg title="Search" aria-label="Search" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search js-jump-to-octicon-search d-none flex-shrink-0">
<path fill-rule="evenodd" d="M11.5 7a4.499 4.499 0 11-8.998 0A4.499 4.499 0 0111.5 7zm-.82 4.74a6 6 0 111.06-1.06l3.04 3.04a.75.75 0 11-1.06 1.06l-3.04-3.04z"></path>
</svg>
</div>
<img class="avatar mr-2 flex-shrink-0 js-jump-to-suggestion-avatar d-none" alt="" aria-label="Team" src="" width="28" height="28">
<div class="jump-to-suggestion-name js-jump-to-suggestion-name flex-auto overflow-hidden text-left no-wrap css-truncate css-truncate-target">
</div>
<div class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none js-jump-to-badge-search">
<span class="js-jump-to-badge-search-text-default d-none" aria-label="in this repository">
In this repository
</span>
<span class="js-jump-to-badge-search-text-global d-none" aria-label="in all of GitHub">
All GitHub
</span>
<span aria-hidden="true" class="d-inline-block ml-1 v-align-middle">↵</span>
</div>
<div aria-hidden="true" class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none d-on-nav-focus js-jump-to-badge-jump">
Jump to
<span class="d-inline-block ml-1 v-align-middle">↵</span>
</div>
</a>
</li>
<li class="d-flex flex-justify-start flex-items-center p-0 f5 navigation-item js-navigation-item js-jump-to-owner-scoped-search d-none" role="option">
<a tabindex="-1" class="no-underline d-flex flex-auto flex-items-center jump-to-suggestions-path js-jump-to-suggestion-path js-navigation-open p-2" href="" data-item-type="owner_scoped_search">
<div class="jump-to-octicon js-jump-to-octicon flex-shrink-0 mr-2 text-center d-none">
<svg title="Repository" aria-label="Repository" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo js-jump-to-octicon-repo d-none flex-shrink-0">
<path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path>
</svg>
<svg title="Project" aria-label="Project" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project js-jump-to-octicon-project d-none flex-shrink-0">
<path fill-rule="evenodd" d="M1.75 0A1.75 1.75 0 000 1.75v12.5C0 15.216.784 16 1.75 16h12.5A1.75 1.75 0 0016 14.25V1.75A1.75 1.75 0 0014.25 0H1.75zM1.5 1.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v12.5a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25V1.75zM11.75 3a.75.75 0 00-.75.75v7.5a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75zm-8.25.75a.75.75 0 011.5 0v5.5a.75.75 0 01-1.5 0v-5.5zM8 3a.75.75 0 00-.75.75v3.5a.75.75 0 001.5 0v-3.5A.75.75 0 008 3z"></path>
</svg>
<svg title="Search" aria-label="Search" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search js-jump-to-octicon-search d-none flex-shrink-0">
<path fill-rule="evenodd" d="M11.5 7a4.499 4.499 0 11-8.998 0A4.499 4.499 0 0111.5 7zm-.82 4.74a6 6 0 111.06-1.06l3.04 3.04a.75.75 0 11-1.06 1.06l-3.04-3.04z"></path>
</svg>
</div>
<img class="avatar mr-2 flex-shrink-0 js-jump-to-suggestion-avatar d-none" alt="" aria-label="Team" src="" width="28" height="28">
<div class="jump-to-suggestion-name js-jump-to-suggestion-name flex-auto overflow-hidden text-left no-wrap css-truncate css-truncate-target">
</div>
<div class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none js-jump-to-badge-search">
<span class="js-jump-to-badge-search-text-default d-none" aria-label="in this user">
In this user
</span>
<span class="js-jump-to-badge-search-text-global d-none" aria-label="in all of GitHub">
All GitHub
</span>
<span aria-hidden="true" class="d-inline-block ml-1 v-align-middle">↵</span>
</div>
<div aria-hidden="true" class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none d-on-nav-focus js-jump-to-badge-jump">
Jump to
<span class="d-inline-block ml-1 v-align-middle">↵</span>
</div>
</a>
</li>
<li class="d-flex flex-justify-start flex-items-center p-0 f5 navigation-item js-navigation-item js-jump-to-global-search d-none" role="option">
<a tabindex="-1" class="no-underline d-flex flex-auto flex-items-center jump-to-suggestions-path js-jump-to-suggestion-path js-navigation-open p-2" href="" data-item-type="global_search">
<div class="jump-to-octicon js-jump-to-octicon flex-shrink-0 mr-2 text-center d-none">
<svg title="Repository" aria-label="Repository" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo js-jump-to-octicon-repo d-none flex-shrink-0">
<path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path>
</svg>
<svg title="Project" aria-label="Project" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project js-jump-to-octicon-project d-none flex-shrink-0">
<path fill-rule="evenodd" d="M1.75 0A1.75 1.75 0 000 1.75v12.5C0 15.216.784 16 1.75 16h12.5A1.75 1.75 0 0016 14.25V1.75A1.75 1.75 0 0014.25 0H1.75zM1.5 1.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v12.5a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25V1.75zM11.75 3a.75.75 0 00-.75.75v7.5a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75zm-8.25.75a.75.75 0 011.5 0v5.5a.75.75 0 01-1.5 0v-5.5zM8 3a.75.75 0 00-.75.75v3.5a.75.75 0 001.5 0v-3.5A.75.75 0 008 3z"></path>
</svg>
<svg title="Search" aria-label="Search" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search js-jump-to-octicon-search d-none flex-shrink-0">
<path fill-rule="evenodd" d="M11.5 7a4.499 4.499 0 11-8.998 0A4.499 4.499 0 0111.5 7zm-.82 4.74a6 6 0 111.06-1.06l3.04 3.04a.75.75 0 11-1.06 1.06l-3.04-3.04z"></path>
</svg>
</div>
<img class="avatar mr-2 flex-shrink-0 js-jump-to-suggestion-avatar d-none" alt="" aria-label="Team" src="" width="28" height="28">
<div class="jump-to-suggestion-name js-jump-to-suggestion-name flex-auto overflow-hidden text-left no-wrap css-truncate css-truncate-target">
</div>
<div class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none js-jump-to-badge-search">
<span class="js-jump-to-badge-search-text-default d-none" aria-label="in this repository">
In this repository
</span>
<span class="js-jump-to-badge-search-text-global d-none" aria-label="in all of GitHub">
All GitHub
</span>
<span aria-hidden="true" class="d-inline-block ml-1 v-align-middle">↵</span>
</div>
<div aria-hidden="true" class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none d-on-nav-focus js-jump-to-badge-jump">
Jump to
<span class="d-inline-block ml-1 v-align-middle">↵</span>
</div>
</a>
</li>
</ul>
</div>
</label>
</form>
Text Content
Skip to content Toggle navigation Sign up * Product * Actions Automate any workflow * Packages Host and manage packages * Security Find and fix vulnerabilities * Codespaces Instant dev environments * Copilot Write better code with AI * Code review Manage code changes * Issues Plan and track work * Discussions Collaborate outside of code * Explore * All features * Documentation * GitHub Skills * Blog * Solutions * For * Enterprise * Teams * Startups * Education * By Solution * CI/CD & Automation * DevOps * DevSecOps * Case Studies * Customer Stories * Resources * Open Source * GitHub Sponsors Fund open source developers * The ReadME Project GitHub community articles * Repositories * Topics * Trending * Collections * Pricing * In this repository All GitHub ↵ Jump to ↵ * No suggested jump to results * In this repository All GitHub ↵ Jump to ↵ * In this user All GitHub ↵ Jump to ↵ * In this repository All GitHub ↵ Jump to ↵ Sign in Sign up {{ message }} WhiteApfel / pyQiwiP2P Public * Notifications * Fork 12 * Star 52 Simple wrapper for comfortable work with the API of payment system for individuals QiwiP2P LICENSE MPL-2.0 license 52 stars 12 forks Star Notifications * Code * Issues 6 * Pull requests 0 * Actions * Projects 0 * Security * Insights More * Code * Issues * Pull requests * Actions * Projects * Security * Insights WHITEAPFEL/PYQIWIP2P This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository. master Switch branches/tags Branches Tags Could not load branches Nothing to show {{ refName }} default View all branches Could not load tags Nothing to show {{ refName }} default View all tags NAME ALREADY IN USE A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch? Cancel Create 3 branches 15 tags Go to file Code * Local * Codespaces * Clone HTTPS GitHub CLI Use Git or checkout with SVN using the web URL. Work fast with our official CLI. Learn more. * Open with GitHub Desktop * Download ZIP SIGN IN REQUIRED Please sign in to use Codespaces. LAUNCHING GITHUB DESKTOP If nothing happens, download GitHub Desktop and try again. LAUNCHING GITHUB DESKTOP If nothing happens, download GitHub Desktop and try again. LAUNCHING XCODE If nothing happens, download Xcode and try again. LAUNCHING VISUAL STUDIO CODE Your codespace will open once ready. There was a problem preparing your codespace, please try again. LATEST COMMIT WhiteApfel ✨ Improve privkey validation … Loading status checks… 61ae3a6 Aug 4, 2022 ✨ Improve privkey validation 61ae3a6 GIT STATS * 218 commits FILES Permalink Failed to load latest commit information. Type Name Latest commit message Commit time .github/workflows 👷 Change pypi workflow trigger to published October 19, 2021 03:32 docs 📝 Fix docs July 12, 2022 23:16 p2proxy ✨ Update starlette server (fix #34) [2] July 27, 2022 23:55 pyqiwip2p ✨ Improve privkey validation August 4, 2022 08:22 tests 💄 Black and isort July 12, 2022 22:39 .deepsource.toml 🔧 Add test patterns November 22, 2021 23:25 .pyup.yml create pyup.io config file May 3, 2021 00:49 .readthedocs.yml 🛠 Improve doc config March 17, 2022 16:06 LICENSE Update LICENSE July 18, 2020 13:45 README.md Update README.md July 31, 2022 03:01 requirements.txt ⬆️ Upgrade dependencies July 12, 2022 22:32 setup.py 💄 Black and isort July 12, 2022 22:39 View code pyQiwiP2P Поддержка прекращена О библиотеке Миграция с первой версии: ⚠️ Важное уведомление А как пользоваться Что есть? А асинхронно могёте? И всё? И асинхронный сервер, наверное, у вас есть? Настройка проксирующего Nginx README.MD PYQIWIP2P ПОДДЕРЖКА ПРЕКРАЩЕНА Есть более качественный инструмент, полностью покрывающий функции pyQiwiP2P: glQiwiApi Возможно, здесь когда-нибудь будет гайд по миграции на него, но всё в руках сообщества О БИБЛИОТЕКЕ Штучка для удобной работы с кивишной апишкой платежей Есть типа документация, но в ней есть и косячки, поэтому, если найдёте таковой, обязательно сообщите мне. Буду искренне рад. Правда. Спасибо. МИГРАЦИЯ С ПЕРВОЙ ВЕРСИИ: 1. Свойство Bill.actual было удалено из-за PEP8 2. QiwiNotify по умолчанию выполняет только функцию по первому подошедшему хендлеру ⚠️ ВАЖНОЕ УВЕДОМЛЕНИЕ С июня Qiwi начала блокировать кошельки, если пользователь открыл страницу оплаты "напрямую", тем самым не передав заголовок referer. Это случается при открытии ссылки: * из мессенджера * из смс * из письма * из адресной строки * из браузера с повышенным режимом приватности или расширениями для приватного просмотра Для обхода всех проблем, кроме последней (она не решается), к объекту Bill был добавлен атрибут Bill.alt_url, который предоставляет ссылку для перенаправления на страницу оплаты через специальную страницу-прокладу, добавляющую этот самый referer. Страница предоставлена мною, но её можно поднять на своём сервере с помощью docker-контейнера. * Исходники: Github * Образ контейнера: ghcr.io/whiteapfel/pyqiwip2p:p2proxy * Запуск: docker run -p 3600:3600 -e QP2P_DOMAIN='example.com' -d ghcr.io/whiteapfel/pyqiwip2p:p2proxy * Свой домен в клиенте: p2p = AioQiwiP2P(PrivKey, alt="example.com") -------------------------------------------------------------------------------- А КАК ПОЛЬЗОВАТЬСЯ ЧТО ЕСТЬ? Есть сам класс QiwiP2P, который обладает тремя инструментами: для выставления, проверки и закрытия платежа (счёта). Пример использования: from pyqiwip2p import QiwiP2P from pyqiwip2p.p2p_types import QiwiCustomer, QiwiDatetime, PaymentMethods QIWI_PRIV_KEY = "abCdef...xYz" p2p = QiwiP2P(auth_key=QIWI_PRIV_KEY) # Выставим счет на сумму 228 рублей который будет работать 45 минут new_bill = p2p.bill(bill_id=212332030, amount=228, lifetime=45) print(new_bill.bill_id, new_bill.pay_url) # Проверим статус выставленного счета print(p2p.check(bill_id=new_bill.bill_id).status) # Потеряли ссылку на оплату счета? Не проблема! print(p2p.check(bill_id=245532).pay_url) # Клиент отменил заказ? Тогда и счет надо закрыть p2p.reject(bill_id=new_bill.bill_id) # Если планируете выставлять счета с одинаковой суммой, # можно воспользоваться параметром default_amount p2p = QiwiP2P(auth_key=QIWI_PRIV_KEY, default_amount=148) # Теперь, если не указывать в методе p2p.bill() значение суммы заказа, # будет применяться указанная базовая сумма new_bill = p2p.bill(bill_id=6627358) # А ещё можно не указывать bill_id, тогда значение сгенерируется автоматически. # Его можно будет посмотреть в объекте ответа Bill # В комбинации со стандартным значением суммы будет вот так new_bill = p2p.bill() print(new_bill.bill_id, new_bill.pay_url) # Чтобы запретить приём платежей через какой-то метод оплаты, например, карты, # необходимо передать paySourcesFilter в fields. Туда же можно передать themeCode fields = { "paySourcesFilter": "qw,card", "themeCode": "MalchikGay", } p2p.bill(fields=fields) # Либо же воспользоваться удобными полями p2p.bill(pay_sources=[PaymentMethods.qiwi, PaymentMethods.card]) p2p.bill(pay_sources=[PaymentMethods.qiwi], theme_code="MalchikGay") А АСИНХРОННО МОГЁТЕ? Могём. Причём примерно так же. from pyqiwip2p import AioQiwiP2P from pyqiwip2p.p2p_types import QiwiCustomer, QiwiDatetime, PaymentMethods QIWI_PRIV_KEY = "abCdef...xYz" p2p = AioQiwiP2P(auth_key=QIWI_PRIV_KEY) # Если планируете выставлять счета с одинаковой суммой, # можно воспользоваться параметром default_amount p2p = AioQiwiP2P(auth_key=QIWI_PRIV_KEY, default_amount=148) async def main(): async with p2p: # Выставим счет на сумму 228 рублей который будет работать 45 минут new_bill = await p2p.bill(bill_id=212332030, amount=228, lifetime=45) print(new_bill.bill_id, new_bill.pay_url) # Проверим статус выставленного счета print((await p2p.check(bill_id=new_bill.bill_id)).status) # Потеряли ссылку на оплату счета? Не проблема! print((await p2p.check(bill_id=245532)).pay_url) # Клиент отменил заказ? Тогда и счет надо закрыть await p2p.reject(bill_id=new_bill.bill_id) # Если не указывать в методе p2p.bill() значение суммы заказа, # будет применяться указанная базовая сумма, которую вы установили new_bill = await p2p.bill(bill_id=6627358) # А ещё можно не указывать bill_id, тогда значение сгенерируется автоматически. # Его можно будет посмотреть в объекте ответа Bill # В комбинации со стандартным значением суммы будет вот так new_bill = await p2p.bill() print(new_bill.bill_id, new_bill.pay_url) # Чтобы запретить приём платежей через какой-то метод оплаты, например, карты, # необходимо передать paySourcesFilter в fields. Туда же можно передать themeCode fields = { "paySourcesFilter": "qw,card", "themeCode": "MalchikGay", } await p2p.bill(fields=fields) # Либо же воспользоваться удобными полями await p2p.bill(pay_sources=[PaymentMethods.qiwi, PaymentMethods.card]) await p2p.bill(pay_sources=[PaymentMethods.qiwi], theme_code="MalchikGay") p2p.run(main()) # Аналог # asyncio.run(main()) И ВСЁ? Нет, не всё. Ещё можно настроить кивишные уведомления на свой сервер, для этого придется немного пострадать, но лишь немного. Внимание! Для работы будет необходим проксирующий сервер (например, Nginx) с доверенным SSL-сертификатом. Да. Подробнее про требования к проксирующему серверу в документации Qiwi А эта шайтан-машина нужна для захендлирования функций на события. Она не готова самостоятельно контактировать с внешним миром. Пожалей её. Запросы сервер по умолчанию принимает на 8099 порту, его можно изменить, и только на /qiwi_notify - изменить нельзя. from pyqiwip2p.notify import QiwiNotify from pyqiwip2p.p2p_types import Bill QIWI_PRIV_KEY = "abCdef...xYz" qiwi_notify = QiwiNotify(QIWI_PRIV_KEY) # # Хэндлер принимает в себя аргументом функцию, # в которую передаст объект счёта - Bill # # Добавим хэндлер, который будет печатать billID для всех счетов @qiwi_notify.handler(lambda bill: True) def print_bill(bill: Bill): print(bill.bill_id) # Создадим хэндлер, который будет печатать сумму оплаченных счетов @qiwi_notify.handler(lambda bill: bill.status == "PAID") def print_bill(bill: Bill): print(bill.amount) # Теперь запустим сервер на 12345'ом порту qiwi_notify.start(port=12345) И АСИНХРОННЫЙ СЕРВЕР, НАВЕРНОЕ, У ВАС ЕСТЬ? Да есть. Причём хендлить функции можно и асинхронные, и синхронные. from pyqiwip2p import QiwiP2P, AioQiwiP2P from pyqiwip2p.p2p_types import Bill from pyqiwip2p.notify import AioQiwiNotify import asyncio QIWI_PRIV_KEY = "abCdef...xYz" qiwi_notify = AioQiwiNotify(QIWI_PRIV_KEY) p2p = AioQiwiP2P(auth_key=QIWI_PRIV_KEY) @qiwi_notify.handler(lambda bill: bill.status == "EXPIRED") async def on_expired(bill: Bill): new_bill = await p2p.bill(amount=bill.amount, comment=bill.comment) print(new_bill.pay_url) @qiwi_notify.handler(lambda bill: True) def on_all(bill: Bill): print(bill.status) async def main(): p = asyncio.get_event_loop() server = p.create_task(qiwi_notify.a_start(port=12345)) await server loop = asyncio.get_event_loop() loop.run_until_complete(main()) НАСТРОЙКА ПРОКСИРУЮЩЕГО NGINX Для порта 12345 (как в примерах выше) будет: server { listen 443; server_name qiwinotify.domain.com; ssl_certificate cert.crt; ssl_certificate_key pkey.key; location /superSecretQiwiURI { proxy_pass http://0.0.0.0:12345/qiwi_notify; } } В таком случае при генерации ключей API на https://qiwi.com/p2p-admin/transfers/api нужно будет указать https://qiwinotify.domain.com/superSecretQiwiURI в качестве URL для уведомлений P.S. за неприходящие от Qiwi запросы ответственность не несу, как и за приходящие, кстати, тоже. Если запроса от Qiwi не было, то пишите им в поддержку @qiwi_api_help_bot ABOUT Simple wrapper for comfortable work with the API of payment system for individuals QiwiP2P TOPICS api payments api-wrapper asyncio qiwi qiwip2p RESOURCES Readme LICENSE MPL-2.0 license STARS 52 stars WATCHERS 4 watching FORKS 12 forks RELEASES 11 🏷️ Version 2.0.6 Latest Jul 30, 2022 + 10 releases PACKAGES 1 * pyqiwip2p USED BY 187 * * * * * * * * + 179 CONTRIBUTORS 8 * * * * * * * * LANGUAGES * Python 99.6% * Dockerfile 0.4% FOOTER © 2023 GitHub, Inc. FOOTER NAVIGATION * Terms * Privacy * Security * Status * Docs * Contact GitHub * Pricing * API * Training * Blog * About You can’t perform that action at this time. You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.