Як працює безпечний прийом платежів в інтернет-магазині

Надається інформація вірна для будь-якої платіжної системи. В тому числі для систем PCI DSS, простого еквайрингу (приймання платежів банківськими картами), віртуальних платіжних систем (яндекс.деньги, вебмані, робокасса і ін).

Обговорення статті «Скомпрометовані транзакції платників RBK Money» показало критичну безграмотність деяких коментуючих. Зазвичай знання у невігластва викликає страх і роздратування, що цікаво відстежити за коментарям. Я спробував дати роз'яснення там в коментарях, за що і поплатився.

Як програмувати безпечний прийом платежів? Поділюся досвідом, розповім і покажу. Для нужденних посилання на прувы (докази) наведені в кінці статті.

Дійові особи
Їх три.
1. Користувач — в загальному випадку живий чоловік, які використовують сервіси.
2. Інтернет-магазин (ЇМ) — браузерна CMS або апп з функцією оплати. У нього повинен бути власник, який має право займатися комерційною діяльністю (відповідно до ЦК РФ — ІП або юрособа — коммерческяа організація). Власник НИМ повинен укласти юридичний договір з ПС і виконати вимоги останнього з технічного підключення.
3. Платіжна система (ПС) — сервіс, що надає можливість здійснювати платежі. Його власником обов'язково повинна бути фінансова організація (юридична особа, що має юридичні можливості здійснювати такого роду діяльність).

Дії користувача
1. Користувач вибирає якісь товари або послуги ЇМ.
2. Користувач висловлює бажання купити і оплатити покупку ЇМ.
3. ЇМ направляє користувача в ПС.
4. Користувач здійснює платіж в ПС. Користувач бачить, що платіж успішним або не успішним.
5. ПС пропонує користувачеві повернутися в ЇМ.
6. Якщо платіж був успішний, користувач може отримати оплачені товари чи послуги. Якщо платіж не був успішний, користувач отримує відповідне повідомлення.

Дії ЇМ
1. ЇМ дозволяє користувачеві сформувати замовлення. Зазвичай це один або кілька замовлених товарів і послуг. У товарів і послуг повинна бути явно позначена ціна і умови, на яких вони продаються.
2. ЇМ формує рахунок для оплати.
3. ЇМ відправляє користувача в ПС, при цьому повідомляє дані рахунки до оплати — ідентифікатор, суму.
4. ЇМ отримує повідомлення від ПС про успіх чи невдачу платежу. Для цього відправляється спеціальне повідомлення — повз користувача! Користувач не знає про це повідомлення. Формат повідомлення, як правило — XML або JSON.
5. ЇМ відповідає ПС про успішне отримання повідомлення про статус платежу. ПС не візьме гроші, якщо ЇМ не працює, або не бажає визнавати успішність платежу (наприклад, рахунок минув, або відбулися інші події, які не дозволяють ЇМ визнати цей платіж). Повторю — в цьому випадку ПС не прийме платіж від користувача!
6. ЇМ шанує користувача після відвідування ПС, повідомляючи статус рахунки до оплати. При цьому ПС повідомляє номер рахунка — в засланні або даних, отриманих POST. Користувач повинен бути авторизований! Не слід повідомляти дані рахунки до оплати стороннім особам (дурість, яка обговорювалася в горезвісних коментарях!). Слід запрограмувати механізм авторизації таким чином, що якщо неавторизований користувач потрапить на сторінку рахунки до оплати — він повинен отримати повідомлення «Доступ заборонений» і запрошення авторизуватись. Авторизація при успіху повинна повертати (або не відводити) на поточну сторінку сайту. Якщо авторизований користувач є власником рахунку, то він має право переглядати його сторінки. Якщо авторизований користувач не є власником рахунку (і не є співробітником ЇМ) — замість даних показати йому повідомлення ДОСТУП ЗАБОРОНЕНИЙ.

Дії ПС
1. Прийняти користувача ЇМ разом з даними рахунку до оплати.
2. Прийняти платіж від користувача, згідно з даними рахунки до сплати (сума, дійсна до, валюта).
3. Повідомити ЇМ про успіх чи невдачу платежу (це повідомлення ЇМ, а не для користувача!).
4. Отримати повідомлення ЇМ про те, що ЇМ успішно отримав і підтвердив повідомлення про успіх платежу! Якщо ЇМ не відповість — ПС не буде приймати платіж від користувача (поверне гроші і повідомить, що в оплаті відмовлено).
5. Повідомити користувачеві про успіх чи невдачу платежу (це повідомлення для користувача, а не ЇМ!).
6. Повернути користувача ЇМ, передавши номер рахунку (щоб користувач зміг потрапити на потрібну сторінку сайту ЇМ).



Рахунок до оплати
Додайте цю сутність у вашу CMS, якщо її ще немає.

У рахунку до оплати повинні бути обов'язкові властивості:
1. Ідентифікатор. Зазвичай це позитивне ціле число. ЇМ повинен обов'язково повідомляти його ПС при запиті дії оплати!
2. Дата, коли створений рахунок
3. Час, протягом якого дійсний рахунок. Це опціональна можливість, але вона дозволить уникнути маси дурних ситуацій.
4. Сума
5. Ідентифікатор користувача. Чий це? Це важлива інформація, яка також використовується і для забезпечення безпеки.
6. Ознака дійсності рахунку.
7. Інші дані.

В ЇМ, крім рахунку є й інші сутності: замовлення, статуси замовлення (іноді це не окрема сутність, а просто денормализованные дані), товари та послуги у замовленні.
Не треба робити замовлення і рахунок до оплати однією сутністю. Тому є технологічні причини, юзкейсы:
— користувач може зробити кілька спроб оплати;
— дійсність (маю на увазі час актуальності) замовлення може відрізнятися від дійсності рахунку, і це нормально;
— результати несправностей (у тому числі проблем нетехнічного характеру) і зломів добре фіксувати. Логи не зберігають дані користувача (userdata). А в сутності вони як раз є;
— інші причини, відомі розробникам.

Невеликий офтопік.

Якщо б ми говорили лише про програмуванні ЇМ, тут варто було б нагадати наступне.
1. Слід зберігати ціни в сутності «товари і послуги в замовленні». Ціни змінюються, і це нормально. При цьому не повинні постраждати старі дані — ціни, що діють на момент оформлення замовлень.
2. Не можна робити реальне вилучення товарів і послуг у ЇМ. Вони повинні відображатися, як зв'язкові дані — для коректного відображення старих замовлень, коли вони були в наявності, були в каталогах і т.д.

Дії ЇМ з рахунком до оплати
1. Створення. На цьому етапі замовлення повинен бути повністю сформований, так як редагування даних в процесі платежу не допускається.
2. Рахунок до оплати не повинен змінюватися в процесі платежу. Якщо вміст замовлення змінено, і він ще не оплачений — повинен бути створений новий рахунок до оплати, а старий оголошений недійсним.
3. Зміна статусу рахунки до оплати, згідно із сигналом, отриманим від ПС. Рахунок до оплати повинен бути дійсним (перевіряється дата створення рахунку та період дійсності або дата дійсності рахунку — може бути зроблено і так і сяк). При цьому ЇМ отримує повідомлення від ПС у форматі JSON, XML або пачку даних POST. Це повідомлення сторінкою (зверстаній в HTML, DOC, PDF, RTF) ну ніяк не влияется. Більше того, воно взагалі для людей не призначено.
4. Сторінка рахунки для користувача. Повинна бути захищена користувача сесією. На цій сторінці користувач-власник рахунку (або співробітник ЇМ) може побачити інформацію про статус рахунки: оплачений, не оплачений, невдала оплата, минув і т.д.
При зміні статусу рахунку повинен спрацьовувати тригер, який повинен змінювати статус замовлення. Це робить можливим процесинг інтернет-магазину і пов'язаних з ним модулів: CRM, складу і т.д.

Безпека
1. Користувач повинен бути в авторизований ЇМ перед оплатою.
2. Добре, коли дії користувача під НИМ приховані від сторонніх очей за допомогою SSL.
3. Повідомлення, якими обмінюються ПС і ЇМ, супроводжуються хешами, соленными секретними кодами, виключно унікальними для кожного ЇМ — партнера ПС. Хеши генеруються з даних рахунку. Таким чином, спроба спотворення даних оригінального рахунки ЇМ призведе до неуспіху платежу.
4. Всі персональні дані, включаючи відомості про статус та інших деталях рахунків, повинні бути захищені користувача сесією! Захищати їх одним хешем, як обговорювалося в горезвісних коментарях, недостатньо. А ось причини якраз там розкриті.

Джерела
Ось обіцяні прувы.
Яндекс.Деньги api.yandex.ru/money/doc/dg/concepts/About.xml
PayPal developer.paypal.com/webapps/developer/docs/classic/products/
WebMoney wiki.webmoney.ru/projects/webmoney/wiki/Web_Merchant_Interface
Робокасса www.robokassa.ru/uk/Doc/Ru/Interface.aspx

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.