Использовать без кнопки покупки
Кнопка покупки, это слой удобства. Под капотом Coin Moebius, это арендованный вебхук плюс несколько JSON-эндпоинтов. Если вы предпочитаете построить собственный интерфейс, вести собственный поток оформления или подключить Coin Moebius к чему-то, что кнопка не покрывает (подписки Square или Authorize.Net, своя платёжная форма, серверный скрипт, мобильное приложение), каждый эндпоинт, который использует кнопка, тоже можно вызвать откуда угодно. Без изменений кода на нашей стороне.
Аутентификация серверных вызовов
Вызовы, которые вы делаете с собственного сервера, могут нести ключ API вашего проекта как bearer-токен. Создайте ключ в панели управления, в разделе ключей API вашего проекта (он начинается с cmk_), и отправьте его в заголовке Authorization:
Authorization: Bearer cmk_live_xxxxxxxxxxxxxxxxxxxxxxxxКлюч привязан к одному проекту, и аутентифицированные вызовы получают более высокий лимит частоты, чем анонимные. Сама кнопка покупки публична и не нуждается в ключе. Держите ключ на своём сервере. Никогда не помещайте его в браузер или другой клиентский код.
Все эти эндпоинты живут под URL вашего проекта. В боевой среде эта база, это https://api.coinmoebius.com. Полный URL для каждого показан ниже (замените части {…} своими значениями).
| Эндпоинт | Что он делает |
|---|---|
GET https://api.coinmoebius.com/api/projects/{projectId}/public-info | Список поставщиков, выводимый кнопкой покупки: каждый способ оплаты, включённый в проекте, содержит только открытые безопасные поля (название, иконка, публикуемый ключ, почтовый адрес для оплаты по почте). Добавьте ?productId=…, чтобы получить цены, порядок и названия для каждого продукта. Ключ не требуется. Ответы приходят из граничного кэша и могут быть устаревшими до минуты; ваши сохранения в панели управления отображаются сразу же. |
POST https://api.coinmoebius.com/api/checkout/{provider}/{projectId} | Начать оформление. POST { productId, metadata }; получите обратно то, что нужно провайдеру (URL перенаправления для Stripe, URL одобрения для PayPal, токен для Authorize.Net Accept Hosted). Отрисуйте это как угодно. |
POST https://api.coinmoebius.com/webhook/{provider}/{projectId} | Провайдер постит сюда. Мы проверяем подпись, нормализуем событие, сохраняем его, считаем квоту. Направьте вебхук провайдера на этот URL, пришло ли исходное оформление с нашей кнопки или из вашей собственной интеграции. |
GET https://api.coinmoebius.com/status/{projectId}/{txId} | Опросить текущее состояние платежа или подписки. Возвращает ту же нормализованную форму, что получает кнопка покупки. |
POST https://api.coinmoebius.com/api/subscriptions/{projectId}/{subscriptionId}/portal-url | Сгенерировать URL размещённого провайдером портала, чтобы покупатель управлял своей подпиской. Работает для любого провайдера, у которого есть портал. |
Идентифицируйте покупателя в собственной системе, передав metadata.customerRef в вызове оформления. Он проходит через провайдера и обратно на каждом событии вебхука, так что вы можете соединить записи Coin Moebius с собственной базой пользователей без того, чтобы мы хранили что-либо о покупателе.
Зачем кто-то использует этот путь: создатель статического сайта, который хочет написать собственную кнопку под дизайн своего сайта, и которому нужна лишь обработка вебхука. Разработчик, который хочет вовсе пропустить кнопку и вызывать API с собственного сервера. Продавец, который хочет вести подписки Square или Authorize.Net и не против сам настроить сбор карты. Кнопка, это отправная точка. API, это сам продукт.
Прослушивание событий покупателя
Элемент выпускает пять браузерных событий. Слушайте через addEventListener на элементе (или на document, события всплывают) — в Angular это (cm-busy)="onBusy($event)" прямо в шаблоне, и React, Vue и простой JavaScript связывают то же самое, как они связывают любое событие DOM. Все события отменяемы; что делает preventDefault(), перечислено по событиям.
| Событие | Когда срабатывает | Полезная нагрузка Detail |
|---|---|---|
cm-busy | Нажатие запустило обработку: кнопка заблокировала себя и показала свой спиннер. Отмените его, чтобы скрыть встроенный спиннер и управлять своим интерфейсом загрузки. Блокировка от двойного клика всегда удерживается. | Пусто. |
cm-load-providers | Модальное окно выбора собирается запросить у API список провайдеров, настроенных на этом проекте. | Пусто. |
cm-checkout-started | Покупатель выбрал провайдера, и Coin Moebius собирается создать сессию оформления (Stripe / NOWPayments) или сгенерировать код-ссылку (manual). | { provider: 'stripe' | 'nowpayments' | 'manual', ... } |
cm-error | Что-то не удалось: сетевая ошибка, сбой подписи, не настроен ни один провайдер. Отмените его, чтобы подавить встроенный дисплей ошибки и направить сообщение в собственный интерфейс. | { error: Error } |
cm-idle | Обработка завершилась: покупатель был передан оформлению, всплывающее окно открилось или появилась ошибка. Парное завершение к cm-busy. | Пусто. |
document.addEventListener('cm-error', (event) => {
console.error('Coin Moebius:', event.detail.error);
// Show your own error UI, send to your analytics, etc.
});В браузере покупателя нет события cm-success. К моменту, когда платёж фактически завершается, покупатель уже перенаправлен на размещённое оформление платёжного провайдера (Stripe Checkout, страница счёта NOWPayments). Они возвращаются на ваш сайт через настроенный вами success_url (см. следующий раздел), а ваш сервер узнаёт о платеже через панель или путём опроса эндпоинта /status.
Опрос с вашего сервера
Для серверного источника истины опрашивайте GET /status/:projectId/:txId с вашего сервера. Форма ответа:
{
"status": "succeeded",
"amount": 29.99,
"currency": "USD",
"isTest": false,
"createdAt": "2026-05-14T01:04:21.000Z",
"updatedAt": "2026-05-14T01:04:21.000Z"
}Значения статуса следуют тому же перечню, что и панель (см. Статусы транзакций). Эндпоинт не требует аутентификации, но ограничен 60 запросами в минуту на один IP. Id транзакции, который вы передаёте, это то, что SDK вернул в событии cm-checkout-started, или то, что показано в столбце «Ссылка» панели.
Типичный шаблон: когда загружается страница вашего success_url, запустите серверную задачу, которая опрашивает /status/:projectId/:txId каждые 15 секунд, пока не увидит succeeded (или failed / тайм-аут), затем выполните заказ.