Официальная клиентская библиотека для работы с API Wind. Поддерживает Node.js и TypeScript.
npm install @windmc/jsimport { WindClient } from "@windmc/js";
const client = new WindClient({
clientId: "ВАШ_CLIENT_ID",
clientSecret: "ВАШ_CLIENT_SECRET", // для OAuth
redirectUri: "https://yoursite.example/callback",
appToken: "ВАШ_APP_TOKEN", // для Billing
webhookSecret: "ВАШ_WEBHOOK_SECRET", // для проверки вебхуков
});// 1. Получить ссылку для входа
const url = client.getAuthorizeUrl(["identify", "bank"]);
// → https://windmc.su/oauth2/authorize?...
// 2. Обменять code на токены
const tokens = await client.exchangeCode(code);
// 3. Получить данные пользователя
const user = await client.getUser(tokens.access_token);
console.log(user.nickname, user.avatar);Если ваше приложение не может безопасно хранить clientSecret (браузер, мобильное
приложение), используйте PKCE вместо секрета — clientSecret в конфиге при этом
можно не указывать:
import { WindClient, generatePKCE } from "@windmc/js";
const client = new WindClient({
clientId: "ВАШ_CLIENT_ID",
redirectUri: "https://yourapp.example/callback",
});
// 1. Сгенерировать пару и сохранить codeVerifier (например, в сессии/cookie)
const { codeVerifier, codeChallenge } = generatePKCE();
const url = client.getAuthorizeUrl(["identify"], undefined, codeChallenge);
// 2. После редиректа обменять code на токены с помощью сохранённого codeVerifier
const tokens = await client.exchangeCode(code, codeVerifier);
// 3. refreshToken() и revokeToken() для PKCE-токенов работают без clientSecret
const refreshed = await client.refreshToken(tokens.refresh_token);| Scope | Описание |
|---|---|
identify |
Никнейм, UUID, роли |
bank |
Счета и транзакции |
bank:charge |
Списание средств (требует подтверждения) |
communities |
Список сообществ пользователя |
friends |
Список друзей |
client.getAuthorizeUrl(scopes, state?) // URL авторизации
client.exchangeCode(code) // code → tokens
client.refreshToken(refreshToken) // обновить токен
client.revokeToken(token) // отозвать токен
client.getUser(accessToken) // scope: identify
client.getBank(accessToken) // scope: bank
client.getBankTransactions(accessToken, limit?)// scope: bank
client.getCommunities(accessToken) // scope: communities
client.getFriends(accessToken) // scope: friends
client.createCharge(accessToken, payload) // scope: bank:charge
client.getCharge(accessToken, chargeId) // scope: bank:charge// Создать счёт — вернёт payUrl для редиректа пользователя
const bill = await client.createBill({
toAccountId: 1001,
amount: 500,
comment: "Оплата",
webhookUrl: "https://yoursite.example/webhooks/wind",
returnUrl: "https://yoursite.example/success",
});
// → { billId, payUrl, expiresAt }
// Проверить статус счёта
const status = await client.getBill(bill.billId);
// → { status: "pending" | "paid" | "expired", ... }Счёт действует 10 минут. После оплаты Wind отправляет POST-запрос на webhookUrl с заголовком X-Signature: sha256=<hmac>.
// Express: читать тело как raw buffer
app.use("/webhooks/wind", express.raw({ type: "application/json" }));
app.post("/webhooks/wind", (req, res) => {
const signature = req.headers["x-signature"];
let payload;
try {
payload = client.parseWebhook(req.body.toString(), signature);
} catch {
return res.status(401).json({ error: "Неверная подпись" });
}
if (payload.event === "bill.paid") {
console.log(`Оплачен счёт ${payload.billId} на сумму ${payload.amount}`);
}
res.status(200).json({ ok: true });
});Готовые примеры в директории example/:
oauth-login— OAuth авторизация с Expresscreate-bill— Создание счёта на оплатуwebhook— Обработка вебхуков
npm run build