Зміст

OpenPayz

Ой що це?

OpenPayz - існує для отримання інформації про онлайн-платежі здійснені з зовнішніх платіжних систем. Надає спільні інтерфейси для реєстрації та обробки повідомлень, що надійшли від платіжних систем, про здійснені користувачами платежі, а також для автоматизованого рознесення отриманих від платіжних систем сум по особових рахунках користувачів Ubilling.

Чим приймаються оплати?

На даний момент підтримуються і безкоштовно поширюються фронтенди/бекенди для:

Платіжна система Що приймає? Фронтенд / бекенд
EasyPay Термінали
VISA
MasterCard
easypay, easypaymulti, easypaymultibyid
2click Термінали/картки 2click
24NonStop Термінали 24nonstop
МобиАЗС Термінали 24nonstop
Приватбанк Приват24
Термінали
privatx, privatx_strict, privatmulti, privatmultifa, privat_multiserv, PrivatGoose
LiqPay VISA
MasterCard
liqpay
iBox Термінали ibox, iboxmulti
Банк "Фамільний" Термінали 2click
Термінали CITY 24
Термінали БНК 24
Термінали ФК Система
Термінали TYME
WebMoney
Ipay
Walletone W1
plategka.com
TachCard
fbank, fbankmulti (24nonstop) / fbank2 (easypay)
Ukrpays VISA
MasterCard
WebMoney
картки НСМЭП
City24
IBox
Tyme
EasyPay
E-Pay
24NonStop
ФК Система
ukrpays
Банк "Тинькофф" Visa
MasterCard
МИР
tinkoff
COIN VISA
MasterCard
24nonstop
Mpay lifecell мобільні платежі lifecell easypay
fondy.eu Qiwi
Яндекс.Деньги
Webmoney
VISA
MasterCard
Приват24
fondy
Paymaster VISA
MasterCard
WebMoney
Приват 24
MoneXy
LiqPay
Wishround
paymaster
iPay checkout VISA
MasterCard
Google pay
Apple pay
ipayz
iPay MasterPass VISA
MasterCard
ПРОСТІР
ipayx
IPAY.BY МТС (Беларусь)
Лайф (Беларусь)
Система «Расчет» (ЕРИП)
ipay_by
QIWI Термінали qiwi
Новоплат Термінали novoplat
Uniteller VISA
MasterCard
JCB
Diners Club
ChinaUnionPay
QIWI Кошелек
Яндекс.Деньги
WebMoney WMR
Евросеть
EasyPay
MoneyMail
Platezh.ru
RBK Money
WebCreds
PayPal
Деньги@Mail.ru
мобільні платежі:
-МТС
- Мегафон
- Билайн
uniteller
Comepay Термінали comepay
City-Pay Термінали citypay
City24 Термінали city24 city24_multi City24Goose
CoPAYCo VISA
MasterCard
Укрексимбанк
Кредитпромбанк
НСМЭП
WebMoney
copayco
Paylogic / ОСМП Термінали osmp
Сбербанк России Готівкові платежі sberbank
Portmone VISA
Visa Electron
MasterCard
Cirrus
Maestro
portmone
portmonemulti
platezhka.com.ua (Банк Національный Кредит) Термінали platezhka
Яндекс.Деньги Яндекс.Деньги
VISA
MasterCard
yandex_notify
Монобанк кредитки monobank, monobankmulti
АБанк24 кредитки abank24multi
ФК-Система Термінали fcsistemamulti
ConcordPay VISA
MasterCard
ApplePay
GooglePay
concordpay
ClickUZ кредитки
Android APP
click_uz / myclickuz
PaymeUZ кредитки
Android APP
payme_uz / mypaymeuz
GlobalMoney Термінали globalmoney
Platon Google Pay
Apple Pay
Приват24
Privat Pay
Masterpass
VisaCheckout
Visa
Mastercard
Простір
platon platonGoose
Platonmobile Google Pay
Apple Pay
Visa
Mastercard
platonmobile
Providex Google Pay
Apple Pay
Visa
Mastercard
providex / providex
А-банк термінали, àbank24 abankcombo, a-bank

Як це працює?

В цілому якось так:

З чого випливає, що платіжні системи безпосередньо спілкуються зі своїми “фронтендами”, абоненти у разі потреби спілкуються з “бекендами” інтегрованими в кабінет користувача або прямо в сайт провайдера, а OpenPayz реєструє транзакції, що надійшли від “фронтендів”, вносить їх до загального реєстру транзакцій і викликає для них різноманітні “обробники”.

Транзакції реєструються для конкретного “віртуального ідентифікатора” (Платіжного ID) користувача однозначно прив'язаного до “реального ідентифікатора” (логіну) користувача Ubilling. Яким він буде і як це все працюватиме – залежить повністю від вас. Для візуального контролю появи нових транзакцій існує однойменний модуль Ubilling.

Встановлення

Починаючи з Ubilling 1.3.4 OpenPayz вже попередньо сконфігуровано інсталятором системи та готово до розгортання одразу після встановлення Ubilling. Вам залишається тільки скопіювати OpenPayz в директорію в якій він працюватиме та налаштувати необхідні вам фронтенди.

Отож кладемо OpenPayz десь подалі і за межі кореневої директорії Ubilling:

# cp -R /usr/local/www/apache24/data/billing/docs/openpayz /usr/local/www/apache24/data/

Та запам'ятовуємо, що OpenPayz тепер живе ось тут

# cd /usr/local/www/apache24/data/openpayz/

Після чого перевіряємо очима, чи відповідають налаштування в config/mysql.ini нашим реаліям:

mysql.ini
;database host
server = "localhost"
;database port
port = "3306"
;user login
username = "mylogin"
;user password
password = "newpassword"
;database name to use
db = "stg"
;connection codepage 
character = "UTF8"
;tables prefix
prefix = "op_"

та зазираємо в конфіг config/openpayz.ini

openpayz.ini
; Вносити оплати до Stargazer напряму за допомогою sgconf?
STG_DIRECT=1
; Шлях до sgconf
SGCONF=/usr/sbin/sgconf
; Хост на якому встановлено Stargazer
STG_HOST=localhost
; Порт stargazer
STG_PORT=5555
; Логін адміністратора stargazer
STG_LOGIN=admin
; Пароль адміністратора stargazer
STG_PASSWD=123456
;ID типу оплат Ubilling (Взагалі хорошою практикою було б додати для цього окремий, наприклад "Самообслуговування")
UB_CASHTYPE=1

; Надсилати сповіщення про отримані платежі електропоштою? (DEPRECATED)
SEND_MAIL=0
; Пошта на котру надсилатимуться сповіщення (DEPRECATED)
NOTIFY_MAIL=notify@ourisp.ua

; Режим сильнонавантаженого OpenPayz із мульйонами транзакцій. При включенні цієї опції всі транзакції
; повинні періодично оброблятися в окремому потоці, зовнішнім воркером op_WorkerPaymentsProceed
OP_HIGHLOAD_ENABLE=0

; У такому форматі можна вказувати кастомні типи платежів для різних платіжних систем.
; Але ми все ж таки рекомендуємо використовувати один загальний UB_CASHTYPE для цих цілей, і розрізняти платіжні системи налаштувавши відповідний довідник.
;CASHTYPEID_EASYPAY=33
;CASHTYPEID_PRIVATX=34

Щиро сподіваюсь, що з цим усе зрозуміло. Далі нам слід знати, що в каталозі frontend в окремих каталогах лежать модулі, що взаємодіють з нашими платіжними системами. Все спілкування з ними у нас відбувається тільки через них. Описувати все немає ніякої можливості, так що можливо слід зазирнутивсередину і подивитися чи немає там якихось специфічних налаштувань усередині.

Увага: при введенні в продакшн, слід видалити всі каталоги фронтендів, що не використовуються, а використовувані перейменувати на щось більш рандомне (наприклад frontend/privatbank_87GS923FF) з цілком зрозумілих причин. Можливо, варто занепокоїтися про допуск до цих директорій лише конкретних IP платіжних сервісів, з якими вони повинні працювати за допомогою htaccess. Це вже на ваш смак. Але ховати фронтенди перейменуванням та видаляти невикористовувані - обов`язково!

Режим високої продуктивності

При ввімкненні опції

OP_HIGHLOAD_ENABLE=1

вся обробка транзакцій перестає здійснюватися вбудованими у фронтенди викликами op_ProcessHandlers і повинна бути винесена в окремий воркер op_WorkerPaymentsProceed, що періодично викликається. Викликатися він може, наприклад із “crontab -e” якось так:

*/2 * * * * /usr/local/bin/php /usr/local/www/apache24/data/openpayz/libs/op_WorkerPaymentsProceed.php

Слід також зауважити, що експлуатація OpenPayz з вимкненою опцією OP_HIGHLOAD_ENABLE у реальному світі та на продакшні вкрай не рекомендується. Відключати його має сенс лише при тестуванні та запуску нових фронтендів платіжних систем. В іншому випадку, ви можете банально напоротись на дублікати оплат, та інші в цілому очікувані ефекти.

Альтернативні Платіжні ID

В деяких, випадках, наприклад, з “міркувань легасі” вам може захотітись використовувати “якісь інші Платіжні ID”. Для цього варто знати, що усі меппінги “Логін”⇒“Платіжний ID” лежать в view вашої БД з іменем op_customers. Власне для того аби на ходу замінити їх всі на потрібне вам представлення трансформуючи дані ваших користувачів для цього як вам заманеться. Нижче декілька прикладів:

Рекомендований за замовчуванням

op_customers_crc32_full.sql
CREATE OR REPLACE VIEW op_customers (realid,virtualid) AS SELECT users.login, CRC32(users.login) FROM users LEFT JOIN op_denied ON users.login = op_denied.login WHERE op_denied.login IS NULL;

З можливістю оверрайду статикою

op_customers_crc32_plus_static.sql
CREATE OR REPLACE VIEW op_customers (realid,virtualid) AS SELECT DISTINCT users.login AS realid, COALESCE(op_static.virtualid,CRC32(users.login)) AS virtualid FROM users 
LEFT JOIN op_static ON op_static.realid=users.login
LEFT JOIN op_denied ON users.login = op_denied.login WHERE op_denied.login IS NULL;

Без заборон

власне все той же за замовчуванням, але з ігноруванням заборон за рахунок чого є трішечки швидшим

op_customers_crc32_fast.sql
-- transform users.login -> crc32(users.login);
CREATE OR REPLACE VIEW op_customers (realid,virtualid) AS SELECT users.login, CRC32(users.login) FROM `users`;

Використовуємо IP

Або якось так, для використання IP адрес користувачів у вигляді INT

op_customers_aton.sql
-- transform users.login -> ip2int(users.IP);
CREATE OR REPLACE VIEW op_customers (realid,virtualid) AS SELECT users.login, INET_ATON(users.IP) FROM `users`;

Використовуємо логіни

Або якось так, у випадку якщо у вас повністю цифрові логіни користувачів:

op_customers_login.sql
-- transform users.login -> users.login;
CREATE OR REPLACE VIEW op_customers (realid,virtualid) AS SELECT users.login, users.login FROM `users`;

Використовуємо угоди

Або якось так, якщо ви впевнені, що у всіх ваших користувачів є унікальні номери угод:

op_customers_contract.sql
-- transform contracts.login -> contracts.contract;
CREATE OR REPLACE VIEW op_customers (realid,virtualid) AS SELECT contracts.login, contracts.contract FROM `contracts`;

Непорожні угоди

Можна якось так, якщо ви впевнені, що у всіх ваших користувачів унікальні номери угод - в різниці від попереднього, не буде записів для користувачів з порожніми угодами:

op_customers_login_contract2.sql
-- transform contracts.login -> contracts.contract;
CREATE OR REPLACE VIEW `op_customers` (`realid`,`virtualid`) AS SELECT `users`.`login`,`contracts`.`contract` FROM (`users` JOIN `contracts` ON((`users`.`login` = `contracts`.`login`))) WHERE (`contracts`.`contract` <> '');

Знову угоди

Наступне представлення більш універсальне, теж створює платіжний ID на базі номеру угоди, але виникають помилки при відсутній угоді.

op_customers_login_contract_pautina.sql
CREATE OR REPLACE VIEW `op_customers` (realid,virtualid) AS SELECT `users`.`login` AS `realid`,`contracts`.`contract` AS `virtualid` FROM (`users` JOIN `contracts` ON ((CONVERT(`users`.`login` USING utf8) = `contracts`.`login`))) WHERE (`contracts`.`contract` <> '');

Логін + угода

Також ви можете спробувати використовувати два різних платіжних ID для ваших користувачів, наприклад використовуючи для цього одночасно їх логін (сподіваємось що він цифровий) а також можливо номер угоди цього користувача, у випадку якщо він не порожній. Якось так:

login_plus_contract.sql
CREATE OR REPLACE VIEW `op_customers` (realid,virtualid) AS 
SELECT DISTINCT `users`.`login` AS `realid`, 
				`users`.`login` AS `virtualid` 
FROM `users` 
LEFT JOIN `op_denied` ON `users`.`login` = `op_denied`.`login` WHERE `op_denied`.`login` IS NULL
 UNION
SELECT DISTINCT `contracts`.`login` AS `realid`,
			    `contracts`.`contract` AS `virtualid`
 FROM `contracts`
LEFT JOIN `op_denied` ON `contracts`.`login` = `op_denied`.`login` 
WHERE `op_denied`.`login` IS NULL AND `contracts`.`contract` !='' AND `contracts`.`contract` IS NOT NULL

Загалом як не складно помітити все лімітовано тільки збоченістю вашої фантазії ;)
(Переконайтесь що у вас всюди увімкнено OPENPAYZ_REALID для використання Платіжних ID з БД, до слова “всюди” це в alter.ini та в userstats.ini)

Статичні платіжні ID

У випадку, якщо вам треба з якоїсь причини (ну наприклад хочете зберегти старі, які були до міграції), щоб платіжні ідентифікатори наглухо лежали в якійсь табличці в БД, ви можете налаштувати опцію OPENPAYZ_STATIC_ID конфігу alter.ini та зберігати їх собі у окремій табличці op_static. В цьому вигляді вьюшка повинна мати наступний вигляд:

op_static_payids.sql
CREATE OR REPLACE VIEW op_customers (realid,virtualid) AS SELECT op_static.realid, op_static.virtualid FROM op_static LEFT JOIN op_denied ON op_static.realid = op_denied.login WHERE op_denied.login IS NULL;

Розробка власного фронтенду

Далі, щоб було зрозуміло як це насправді працює ми можемо наприклад, написати наш власний фронтенд для прийому платежів від абстрактної “ГрабуйКоровани payment system” :)

Специфікація отримання повідомлення про успішну оплату користувачем від платіжної системи “ГрабуйКоровани payment system”

 При успішному поповненні рахунку вам буде надіслано набір GET наступних обов'язкових параметрів:

   user - ідентифікатор користувача від якого отримано платіж
   transactionid – унікальний ідентифікатор платежу
   cash - сума платежу
 Якщо ви все добре, ви повинні відповісти нам у форматі "transactionid:код статусу"
 Де "код статусу" це
   OK - все добре, платіж отримано та оброблено
   USER_NOT_FOUND - немає такого користувача
   DONE – платіж вже оброблений, сума вже внесена на рахунок користувача
   NOT_ENOUGH_PARAMS - Ктулху фхтагн!
 Приклад запиту на внесення коштів з нашого боку:
http://your_url/?user=90665123&transactionid=SDEFGSSDRHD324SDF&cash=100
frontend/corovan/index.php
<?php
 
/**
 * Just sample frontend intended only for OpenPayz testing
 */
include ("../../libs/api.openpayz.php");
 
$reply = '';
 
/**
 * Check is transaction unique?
 * 
 * @param string $hash - hash string to check
 * 
 * @return bool
 */
function corovan_checkTransaction($hash) {
    $hash = mysql_real_escape_string($hash);
    $query = "SELECT `id` from `op_transactions` WHERE `hash`='" . $hash . "'";
    $data = simple_query($query);
    if (!empty($data)) {
        return (false);
    } else {
        return (true);
    }
}
 
if ((isset($_GET['user'])) AND ( isset($_GET['transactionid'])) AND ( isset($_GET['cash']))) {
    $allcustomers = op_CustomersGetAll();
    $hashRaw = trim($_GET['transactionid']);
    $hash = 'COROVANTEST' . $hashRaw;
    $summ = $_GET['cash'];
    $customerid = trim($_GET['user']);
 
 
    if (isset($allcustomers[$customerid])) {
        if (is_numeric($summ)) {
            //maybe already processed?
            if (corovan_checkTransaction($hash)) {
                op_TransactionAdd($hash, $summ, $customerid, 'COROVAN', '');
                op_ProcessHandlers();
                $reply = $hashRaw . ':OK';
            } else {
                $reply = $hashRaw . ':DONE';
            }
        } else {
            $reply = $hashRaw . ':OK';
        }
    } else {
        $reply = $hashRaw . ':USER_NOT_FOUND';
    }
} else {
    $reply = 'ERROR:NOT_ENOUGH_PARAMS';
}
 
die($reply);

Ось власне і все, у разі успіху - op_TransactionAdd створює нову транзакцію, а op_ProcessHandlers викликає стандартні обробники для всіх поки що необроблених транзакцій. Тепер Ubilling вміє грабувати коровани :)

Налаштування платіжних систем (очевидні і не дуже)

Platonmobile

Відобразити конфіг

Сховати конфіг

Мабуть, одна з перших “платіжок”, що своїм конфігом спирається не тільки на доволі звичний багатьом власний config/platonmobile.ini, а й вимагає трохи додаткових рухів безпосередньо в біллінгу.

Ітак:

  • або не помилитись - найменування платіжної системи бажано не вписувати руками, а вибрати з випадаючого списку наявних платіжних систем, бо найменування платіжної системи - критично важливе
  • Merchant ID та його пароль мають бути вписані точно в ті ж самі поля, які ви бачите на скріні вище, тобто Код контрагента в платіжній системі та Пароль сервісу відповідно
  • звичайно, за потреби ми можемо зробити необмежену кількість записів для кожного контрагента під необхідну кількість копій фронтендів даної платіжної системи

Ось і все - налаштування креденшлів платіжної системи Platonmobile для певного господарюючого суб'єкта - завершено.


Providex

Відобразити конфіг

Сховати конфіг

  • для необхідного нам контрагента створюємо новий запис для нашої платіжної системи PROVIDEX в “Додатковій інфо про контрагента”, враховуючи маппінг полів:

  • звичайно, за потреби ми можемо зробити необмежену кількість записів для кожного контрагента під необхідну кількість копій фронтендів даної платіжної системи


PRIVAT_MULTISERV

Відобразити конфіг

Сховати конфіг

  • для необхідного нам контрагента створюємо новий запис для нашої платіжної системи PB_MULTISERV(нехай вас не бентежить трохи різне найменування, власне, платіжної системи та каталогу фронтенду - так історично склалося) в “Додатковій інфо про контрагента”, враховуючи маппінг полів:

  • звичайно, за потреби ми можемо зробити необмежену кількість записів для кожного контрагента під необхідну кількість копій фронтендів даної платіжної системи