Інтеграція платіїної системи CloudPayments на сайт
CloudPayments — російський процесинг з хорошою документацією, вбудованою касою (54-ФЗ), підтримкою рекурентних платежів та зручним віджетом. Відрізняється від конкурентів тим, що платіжна форма відкривається поверх сайту, не уводячи покупця на зовнішню сторінку — конверсія вище.
Варіанти інтеграції
CloudPayments пропонує три способи вбудування:
- Віджет — JavaScript-попап, найшвидше в реалізації
- Checkout — вбудована форма через iframe
- API — прямий процесинг без переходу на сторонні сторінки (потребує PCI DSS SAQ A-EP або вище)
Для більшості сайтів підходит віджет. API потребен, якщо потребен повний контроль над UI форми або реалізація токенізації.
Підключення віджета
<script src="https://widget.cloudpayments.ru/bundles/cloudpayments.js"></script>
const pay = () => {
const widget = new cp.CloudPayments({ language: 'ru-RU' });
widget.charge(
{
publicId: 'pk_xxxxxxxxxxxxxxxxxxxx',
description: 'Заказ #12345',
amount: 1500,
currency: 'RUB',
accountId: '[email protected]',
invoiceId: 'order-12345',
skin: 'mini',
data: {
// довільні метадані, повертаються у webhook
orderId: 12345,
},
},
(options) => {
// успіх — не довіряти цьому коллбеку без серверної перевірки
console.log('payment success', options);
},
(reason, options) => {
console.error('payment failed:', reason);
},
);
};
publicId — публічний ключ з особистого кабінету. Секретний ключ (apiSecret) — тільки на сервері, ніколи у фронтенді.
Webhook
Після оплати CloudPayments відправляє POST на URL, вказаний у особистому кабінеті (розділ «Сповіщення»). Тип сповіщення — payment:
public function handleWebhook(Request $request): Response
{
// Перевіряємо HMAC-підпис
$hmac = base64_encode(
hash_hmac('sha256', $request->getContent(), env('CP_API_SECRET'), true)
);
if ($hmac !== $request->header('Content-HMAC')) {
return response('Invalid signature', 403);
}
$data = $request->all();
if ($data['Status'] === 'Completed') {
$orderId = $data['InvoiceId'];
$amount = $data['Amount'];
Order::where('id', $orderId)
->where('total', $amount)
->update(['status' => 'paid', 'transaction_id' => $data['TransactionId']]);
}
// CloudPayments очікує код 200 з тілом {"code":0}
return response()->json(['code' => 0]);
}
Якщо повернути {"code": 13}, CloudPayments буде повторювати сповіщення по розписанню до 10 разів. Це корисно при тимчасових помилках БД.
Фіскалізація
CloudPayments має вбудовану онлайн-касу. Дані для чека передаються у параметрі cloudPayments.customerReceipt всередину об'єкта data віджета:
data: {
cloudPayments: {
customerReceipt: {
Items: [
{
label: 'Товар 1',
price: 1500.00,
quantity: 1.0,
amount: 1500.00,
vat: null, // null=без НДС
method: 0, // 0=повний розрахунок
object: 1, // 1=товар
},
],
taxationSystem: 1, // 1=УСН дохід
email: '[email protected]',
amounts: {
electronic: 1500.00,
advancePayment: 0.00,
credit: 0.00,
provision: 0.00,
},
},
},
}
Токенізація карти
Для повторних платежів без введення реквізитів CloudPayments повертає Token у першому успішному платежі. Збережіть у БД та використовуйте для подальших списань:
// Повторне списання по токену через API
$response = Http::withBasicAuth(env('CP_PUBLIC_ID'), env('CP_API_SECRET'))
->post('https://api.cloudpayments.ru/payments/tokens/charge', [
'Amount' => 1500,
'Currency' => 'RUB',
'AccountId' => '[email protected]',
'Token' => $savedToken,
'InvoiceId' => 'order-12346',
'Description' => 'Автоматичне списання',
]);
Повернення через API
Http::withBasicAuth(env('CP_PUBLIC_ID'), env('CP_API_SECRET'))
->post('https://api.cloudpayments.ru/payments/refund', [
'TransactionId' => 123456789,
'Amount' => 750, // частинковий
]);
Продуктивність та особливості
Віджет CloudPayments завантажує зовнішній скрипт вагою ~180 KB. Завантажувати його краще ліниво — тільки при взаємодії користувача з кнопкою оплати, а не при завантаженні сторінки. Час активації боевого аккаунту після подання заявки — від 1 до 3 робочих днів, що швидше більшості конкурентів на російському ринку.







