Configuration
Secrets stored in browser localStorage. Не коммить этот файл в публичный git. Bearer-токен на этой странице === полный доступ к мерчанту.
Что такое proxy prefix и зачем он нужен
У OPP CORS обычно закрыт — браузер не пустит прямой
1) Без прокси — кнопка Send упадёт, но curl-команда сгенерируется корректно, копируешь и шлёшь из терминала.
2) С прокси — поднимаешь локальный proxy-сервер, например
fetch. Варианты:1) Без прокси — кнопка Send упадёт, но curl-команда сгенерируется корректно, копируешь и шлёшь из терминала.
2) С прокси — поднимаешь локальный proxy-сервер, например
node server.js на порту 8787. Минимальный код Node ниже (в раскрывашке внизу страницы).
Payment status & queries
Get payment status
/v1/payments/{id}Получить полный статус транзакции по её
id. Это основной способ "проверить, что с платежом".// response will appear here
Query transactions
/v1/queryПоиск платежей по фильтрам. Ближайший аналог "посмотреть, что было за период" — то, что в API можно назвать "балансом".
// response will appear here
Get checkout payment status
/v1/checkouts/{id}/paymentУзнать, чем закончилась checkout-сессия (после виджета Copy & Pay).
// response will appear here
Get token info
/v1/registrations/{id}Получить данные сохранённой карты (токена): бренд, last4, expiry.
// response will appear here
Checkout flow (hosted widget)
Create checkout
/v1/checkoutsСоздать checkout-сессию для Copy & Pay виджета. Возвращает
id для подстановки в виджет.// response will appear here
Get registration from checkout
/v1/checkouts/{id}/registrationЕсли в checkout был
createRegistration=true, получить созданный токен.// response will appear here
Server-to-server payments (PCI scope)
Эти эндпоинты принимают сырые данные карты. Использовать можно ТОЛЬКО если у тебя PCI DSS SAQ D или ты в защищённой PCI-среде. Тестовые карты — см. блок внизу.
Direct payment
/v1/paymentsS2S платёж картой. PA = preauth (hold), DB = debit (полное списание), CD = credit (выплата на карту).
// response will appear here
Capture / Refund / Reverse
/v1/payments/{id}CP capture (после PA), RF refund (возврат после DB), RV reversal (отмена до клиринга).
// response will appear here
Account verification (zero-amount auth)
/v1/paymentsПроверить, что карта живая, не списывая ни цента.
paymentType=PA, amount=0.// response will appear here
Tokenization
Register card (tokenize)
/v1/registrationsСохранить карту как токен. Возвращает
registrationId для последующих списаний.// response will appear here
Charge stored token
/v1/registrations/{id}/paymentsСписать с ранее сохранённого токена (recurring / one-click).
// response will appear here
Delete token
/v1/registrations/{id}Удалить сохранённый токен.
// response will appear here
3-D Secure (standalone)
Standalone 3DS authentication
/v1/threeDSecureОтдельный 3DS-флоу, без привязки к платежу. Используется когда нужно сначала пройти challenge, а потом списать.
// response will appear here
Test cards (sandbox eu-test.oppwa.com)
Эти карты работают только на тестовом окружении. На
eu-prod вернут ошибку.VISA success: 4200 0000 0000 0000 05/34 CVV 123 MASTER success: 5454 5454 5454 5454 05/34 CVV 123 AMEX success: 3779 5715 7838 080 05/34 CVV 1234 VISA decline: 4444 4444 4444 4448 3DS challenge: 4711 1000 0000 0000 Insufficient funds: 4200 0000 0000 0042
Local proxy (если CORS блокирует)
Сохрани как
server.js рядом, запусти node server.js. В поле Proxy prefix вверху укажи http://localhost:8787/proxy?url=.// server.js — минимальный CORS-proxy
const http = require('http');
const https = require('https');
const { URL } = require('url');
http.createServer((req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,DELETE,OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Authorization,Content-Type');
if (req.method === 'OPTIONS') return res.end();
const target = new URL(req.url, 'http://x').searchParams.get('url');
if (!target) { res.statusCode = 400; return res.end('url required'); }
const u = new URL(target);
const opts = {
method: req.method,
headers: { ...req.headers, host: u.host },
};
delete opts.headers['origin']; delete opts.headers['referer'];
const proxied = https.request(u, opts, (r) => {
res.statusCode = r.statusCode;
Object.entries(r.headers).forEach(([k,v]) => {
if (k.toLowerCase() !== 'access-control-allow-origin') res.setHeader(k, v);
});
res.setHeader('Access-Control-Allow-Origin','*');
r.pipe(res);
});
proxied.on('error', e => { res.statusCode=500; res.end(e.message); });
req.pipe(proxied);
}).listen(8787, () => console.log('proxy on http://localhost:8787'));