ФорумПрограммированиеПыхнуть хотите?Готовые решения → Мой опыт по подключению платежных систем

Мой опыт по подключению платежных систем

  • Ivan.

    Сообщения: 495 Репутация: N Группа: Адекваты

    Spritz 11 мая 2016 г. 5:38

    Пишу сам для себя на будущее.

    При работе с комиссиями нужно учитывать:
    - комиссия может отличаться для каждой валюты
    - комиссия может отличаться для материка (как правило европа, сша, все остальное)
    - комиссия может иметь статическую часть
    - комиссия может иметь минимальный размер
    - комиссия может иметь процентную часть
    - комиссия может иметь округление в большую или меньшую сторону
    - комиссия может быть на ввод, на вывод, на перевод
    - комиссия за конвертацию валюты может быть основана на собственном курсе валюты системы
    - охуительно считать все платежи и комиссии в копейках, но только если у вас копейки/центы, с помесью копеек и сатоши уже будет проблемнее

    При работе с комиссиями возникают часто проблемы математического характера
    Рекомендую на стороне JavaScript использовать math.js и работать с большими числами
    На стороне сервера, если речь идет о питоне то Decimal

    Настраивайте одинаковую точность для Decimal на сервере и math.js на клиенте, например 64 знака после запятой

    
    from decimal import localcontext
    
    with localcontext() as ctx:
        ctx.prec = 64   # Perform a high precision calculation
        s = calculate_something()
    s = +s  # Round the final result back to the default precision
    
    
    math.config({
      number: 'BigNumber',  // Default type of number:
                            // 'number' (default), 'BigNumber', or 'Fraction'
      precision: 64         // Number of significant digits for BigNumbers
    });
    

    Почти все платежные системы работают одинаково, можно разделить их на две большие группы:
    агрегаторы (freekassa, robokassa, liqpay) и кошельки (webmoney, qiwi, yandex money, brick)

    Агрегаторы берут охуевшие проценты, порой даже сильно охуевшие (freekassa)
    К слову о фрикассе - с пользователя или магазина на ваш выбор берется комиссия ввода, а затем вы можете вывести деньги на выбранную систему с комиссией, то есть получается двойная комиссия

    Робокасса на данный момент не работает с физ лицами, да и вообще почти все агрегаторы требуют либо юр лицо либо ип для нормальной работы

    Без юрлица можно работать с вебмани мерчантом (с ограничениями) и яндекс деньгами (до 15000 на кошелек)
    Ну и с фрикассой разумеется

    Системы которые я подключал:
    - yandex money через данные для формы, перевод 0.5% (подключается очень легко, тестирование затруднено)
    - yandex касса (проценты не помню)
    - webmoney, перевод 0.8% (подключается очень легко, есть адекватное тестирование)
    - robokassa (подключается легко, есть адекватное тестирование)
    - freekassa (подключается легко, с тестированием какие-то траблы насколько помню)
    - paymentwall brick для сша и европы (подключается средне для первого раза, из особенностей работа на стороне клиента собственной js-библиотекой, комиссии Pricing - Paymentwall [paymentwall.com]

    буду дописывать этот пост по мере использования новых шлюзов
    если будут вопросы по этим системам можете задавать

    сейчас занимаюсь подключением bitcoin ( Bitcoin Wallet - Coinbase [coinbase.com]), lightcoin, и много другого (например CloudPayments [cloudpayments.ru] в качестве карточного мерча для россии )

    Основная суть работы с платежными системами:
    можно сделать url вида /payments/<system>/<result>/ где system будет платежным шлюзом, а result типом уведомления, обычно их три: уведомление о платеже, успешная переадресация и переадресация с провалом. Туда платежный шлюз будет слать свой пингбэк или соответственно перенаправлять пользователя.

    всегда передается контрольная сумма для проверки валидности данных
    самый часто используемые алгоритмы sha1, md5, sha256
    из них конечно надежнее последний, поэтому если есть выбор то надо выбирать именно его или что-нибудь покруче
    определенным образом составляется строка и проверяется хеш от нее

    часто вместе с параметрами приходит язык, сумма, кошелек покупателя (идентификатор)
    редко ip-адрес, сумма с комиссией
    часто можно добавлять свои параметры

    При работе с транзакциями использую такой алгоритм:
    - создаю транзакцию через ajax
    - возвращаю номер новой транзакции клиенту
    - заполняю поля формы и делаю POST на сайт шлюза (или дополнительный запрос в случае если можно не редиректить)

    Функция post (angular, но легко можно переписать, angular.element это jQuery, $document[0] это document)

    
        vm.doPost = function (path, parameters) {
            var form = angular.element('<form></form>');
    
            form.attr('method', 'post');
            form.attr('action', path);
    
            angular.element.each(parameters, function(key, value) {
                var field = angular.element('<input></input>');
    
                field.attr('type', 'hidden');
                field.attr('name', key);
                field.attr('value', value);
    
                form.append(field);
            });
            angular.element($document[0].body).append(form);
            form.submit();
        };
    

    тогда работа с яндекс деньги превращается во что-то такое

    
              path = 'https://money.yandex.ru/quickpay/confirm.xml';
              req = {
                'sum': mustPay.toString(),
                'formcomment': 'Balance replenish',
                'short-dest': 'Balance replenish: ' + $user.nickname,
                'targets': 'Пополнение баланса пользователя ' + $user.nickname,
                'successURL': $settings.backendSite + '/service/yd/result/success/',
                'label': transactionId,  // номер транзакции, которая хранит информацию о платеже, сумму и прочее
                'quickpay-form': 'shop',
                'paymentType': 'PC',
                'receiver': $settings.ydReceiver  // кошелек яндекс денег для приема
              };
    
              vm.doPost(path, req);
    

    нужно включить для кошелька http-уведомление
    Уведомление о входящем переводе — Технологии Яндекса [tech.yandex.ru]

    webmoney merchant

    
              path = 'https://merchant.webmoney.ru/lmi/payment.asp';
              req = {
                LMI_PAYMENT_AMOUNT: mustPay.toString(),  // к оплате сумма
                LMI_PAYMENT_DESC_BASE64: base64.encode('Пополнение баланса пользователя ' + $user.nickname),
                LMI_PAYMENT_NO: transactionId,
                CP_USER_ID: $user.user_id,
                LMI_PAYEE_PURSE: (vm.replenish.currency == 'RUB') ? $settings.payeeWMR : $settings.payeeWMZ,
                LMI_PAYMER_EMAIL: $user.email,
                /**
                  Дополнительное поле, определяющее режим тестирования. Действует только в режиме тестирования и может принимать одно из следующих значений:
                  0 или отсутствует: Для всех тестовых платежей сервис будет имитировать успешное выполнение;
                  1: Для всех тестовых платежей сервис будет имитировать выполнение с ошибкой (платеж не выполнен);
                  2: Около 80% запросов на платеж будут выполнены успешно, а 20% - не выполнены.
                 */
                LMI_SIM_MODE: '0'
              };
    
              if ($user.phone) {
                req.LMI_FAST_PHONENUMBER = $user.phone;
              }
    
              vm.doPost(path, req);
    

    Web Merchant Interface - WebMoney Wiki [wiki.webmoney.ru]

    Фрикасса имеет интересную сука особенность: если отправить сумму платежа, то она обязательно будет воспринята как сумма в российских рублях, и это при том, что можно указать к оплате доллары.
    Поэтому если хотите принимать через фрикассу разные валюты нужно руками конвертировать их в рубли и только потом передавать фрикассе
    К примеру вы хотите взять с пользователя 1 USD, значит надо передать 67.80 и указать USD
    ПРи этом цепочка получится такая Исходная->Рубль->Фрикасса->Доллары->Комиссия ввода->Рубли->Комиссия вывода->Ваши деньги рублями (потеря 15-25%)

    Фрикасса имеет непонятные неадекватно названные переменные:
    Free-Kassa.ru - Центр Приема Платежей, система приема платежей на сайте, интернет-магазине! [free-kassa.ru]
    Запрос надо отправлять на Free-Kassa.ru - Центр Приема Платежей, система приема платежей на сайте, интернет-магазине! [free-kassa.ru]

    Brick адекватная документация с примерами кода:
    Paymentwall [paymentwall.com] (указывайте brick, my own form)

    По поводу транзакций:
    - транзакция может содержать сумму, если речь идет о криптовалюте то до 8 знаков после запятой

    amount = models.DecimalField(max_digits=20, decimal_places=8, default=Decimal(0.0))
    • время отправления, объект кошелька, валюту, цель оплаты, тип (ввод, вывод, прочее)
    • пользователя, статус (в процессе, успех, провал, отказ, в очереди)
    • статус обработки (законченности) (выполнена или нет)
    • идентификатор кошелька пользователя (номер карты например)
    • комментарий, ip-адрес, значение без комиссии, прибыль компании (для удобного анализа)
    • внутренний ли платеж (да или нет)

    С подобной моделью достаточно удобно, заявки на вывод удобнее держать отдельной моделью с указанием на транзакцию

  • adw0rd

    Сообщения: 22959 Репутация: N Группа: в ухо

    Spritz 11 мая 2016 г. 6:26, спустя 48 минут 51 секунду

    • охуительно считать все платежи и комиссии в копейках, но только если у вас копейки/центы, с помесью копеек и сатоши уже будет проблемнее

    @Ivan., хранить надо в инте, сатоши тоже не проблема, храни в 10**8, а не в 10**2

    Спустя 179 сек.

    сейчас занимаюсь подключением bitcoin ( Bitcoin Wallet - Coinbase [coinbase.com]), lightcoin, и много другого (например CloudPayments [cloudpayments.ru] в качестве карточного мерча для россии )

    @Ivan., зачем тебе coinbase? Разверни свой биток. Что касается лайткойна, то все остальные *коины имеют на 99% такой же API что и биток

    Спустя 92 сек.

    Я за свою карьеру подключил десятками аггрегаторы, платежки, криптокоины и т.п. фигню
    Кстати, почему нет Qiwi? У них раньше был отдельный проект под такие подключения, но надо договор заключать было

    Спустя 72 сек.

    всегда передается контрольная сумма для проверки валидности данных

    @Ivan., не всегда, есть упоротые, которые предлагают максимум контроль по их IP адресу

    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • adw0rd

    Сообщения: 22959 Репутация: N Группа: в ухо

    Spritz 11 мая 2016 г. 6:39, спустя 12 минут 57 секунд

    Я никогда не писал платежный шлюз как конечный проект, но из проекта в проект получался именно шлюз: надо было брать с пользователя денег и выводить деньги
    В итоге для каждой платежки был класс, который наследовался от интерфейса
    И это был микросервис со своим REST, своей историей транзакция и шифрованием данных
    В который прилетали потом коллбеки, а он пинговал уже конечную систему
    Получилось очень удобно, в самом проекте не надо было городить огород, была простая логика: есть ссылка на свой шлюз (чтобы сабмитить по протоколу данные из формы, заполненые пользователем) и урл для уведомлений (коллбеков), типа "платеж такой-то одобрен" (с подписью конечно)
    Этакий свой агрегатор, которому ты полностью доверяешь
    А дальше появлялся новый проект и копия этого шлюза уже работала на него

    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • Ivan.

    Сообщения: 495 Репутация: N Группа: Адекваты

    Spritz 11 мая 2016 г. 6:44, спустя 4 минуты 23 секунды

    А ты не думал завернуть и выложить на гитхаб?

  • adw0rd

    Сообщения: 22959 Репутация: N Группа: в ухо

    Spritz 11 мая 2016 г. 6:49, спустя 5 минут 26 секунд

    А ты не думал завернуть и выложить на гитхаб?

    @Ivan., ну я не для себя его делал, надо спрашивать разрешение, потом отрефакторить, написать доку, тесты
    вообще думал конечно, но мне влом
    есть куда более интересные вещи в жизни

    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • Ivan.

    Сообщения: 495 Репутация: N Группа: Адекваты

    Spritz 11 мая 2016 г. 6:57, спустя 7 минут 49 секунд

    А ты не думал завернуть и выложить на гитхаб?

    @Ivan., ну я не для себя его делал, надо спрашивать разрешение, потом отрефакторить, написать доку, тесты
    вообще думал конечно, но мне влом
    есть куда более интересные вещи в жизни

    @adw0rd, а жаль, подобного в интернете мало, не забывай хотя бы про свой блог)

  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 11 мая 2016 г. 6:58, спустя 31 секунду

    даунхилл, например ;)

    ιιlllιlllι унц-унц
  • adw0rd

    Сообщения: 22959 Репутация: N Группа: в ухо

    Spritz 11 мая 2016 г. 7:02, спустя 4 минуты 34 секунды

    @artoodetoo, в том числе, но больше фрирайд доставляет
    неделю назад ногу повредил, не вошел в шпильку и на 30кмч ударился в бордюр
    ладно хоть скорость сбросил

    Спустя 112 сек.

    ну а если честно, то семья-дети важнее всего
    да и по работе есть много интересного

    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 11 мая 2016 г. 7:09, спустя 6 минут 36 секунд

    Ужоснах! Ногу удалось спасти?

    ιιlllιlllι унц-унц
  • adw0rd

    Сообщения: 22959 Репутация: N Группа: в ухо

    Spritz 11 мая 2016 г. 7:32, спустя 23 минуты 38 секунд

    @artoodetoo, был в травме, сделал рентген, все норм. Просто сильный ушиб

    Спустя 49 сек.

    надо доделать разделение темы, у меня там было почти все готово и даже тест уже писал вроде )
    посмотрю сегодня

    https://smappi.org/ - платформа по созданию API на все случаи жизни

Пожалуйста, авторизуйтесь, чтобы написать комментарий!