Статьи

Прозрачные перенаправления с Braintree

Простое упоминание о «PCI Compliance» обычно вызывает сочетание запутанной внешности и потных ладоней у владельцев бизнеса, которые принимают платежи по кредитным картам онлайн. Но что это на самом деле означает?

Это сложная тема, но короткая версия заключается в том, что крупные компании, выпускающие кредитные карты, в 2006 году создали совет под названием Совет по стандартам безопасности индустрии платежных карт (PCI SSC), чтобы создать набор правил, стандартизирующих политики и процедуры безопасности, которые продавцы должны следовать (PCI DSS) при обработке и хранении конфиденциальной информации о кредитной карте. Чтобы определить, соответствуют ли ваши системы, вы обычно выбираете соответствующий Вопросник самооценки (SAQ) из одного из восьми вариантов, а затем отвечаете на ряд вопросов, чтобы определить, действительно ли вы соответствовали. Крупные корпорации часто используют услуги квалифицированного оценщика безопасности (QSA), чтобы помочь им заполнить SAQ D (наиболее вовлеченный в SAQS), который может стоить сотни тысяч долларов. И что еще хуже: если ваши системы скомпрометированы и установлено, что они не соответствовали требованиям, когда они были взломаны, вы можете быть привлечены к штрафу в размере до 500 000 долл. США за инцидент.

Так что же делать владельцу малого бизнеса? Вот тут-то и появятся платежные решения Braintree . Они предлагают два решения для минимизации нагрузки на PCI-совместимость: прозрачное перенаправление и Braintree.js. Я должен упомянуть, что ни Braintree, ни какой-либо другой поставщик услуг, совместимый с PCI DSS, не могут сказать вам, какой SAQ заполнять или соответствуют ли ваши системы. Но они объединились с Security Metrics , ведущим в отрасли QSA, чтобы предоставить бесплатное решение, чтобы помочь всем своим клиентам достичь и поддерживать соответствие PCI. И, по своему опыту, клиенты, использующие либо Transparent Redirect, либо Braintree.js, как правило, могли заполнить SAQ A, что намного менее затратно (и, следовательно, дорого), чем SAQ D. Вы можете прочитать больше здесь .

Но достаточно фона; давайте напишем некоторый код.

Начиная

Эта статья посвящена методу прозрачного перенаправления. Первое, что нам нужно сделать, это зайти в Braintree, чтобы получить наши ключи API на стороне сервера. Для тех из вас, у кого нет рабочей учетной записи, укажите в браузере « Песочницу» Braintree и зарегистрируйте тестовую учетную запись. Войдите в систему и нажмите «Учетная запись -> Ключи API». Затем нажмите кнопку «Создать новый» и, наконец, нажмите «Просмотр» в столбце «Личный ключ» вновь созданного ключа API. Вы попадете на следующий экран, который содержит всю информацию, необходимую для настройки клиентской библиотеки Braintree.

Braintree Control Panel API Key Page

Вы можете видеть, что у него даже есть инструмент, который генерирует код конфигурации для вас на разных языках.

Теперь пришло время установить настоящую клиентскую библиотеку Braintree PHP. Мы можем сделать это с помощью Composer , выполнив следующую команду:

composer require braintree/braintree:* 

Прозрачный редирект

Один из основных факторов, который помогает определить, нужно ли вам заполнять SAQ D или SAQ A, заключается в том, передаются ли данные вашей кредитной карты через вашу систему. И в начале типичной модели сервер-сервер (S2S) ваш веб-сервер отправлял форму оплаты в браузер клиента. После заполнения формы клиент нажимает кнопку «Отправить», после чего данные отправляются обратно на ваш веб-сервер, который, в свою очередь, передает эти данные в Braintree для проверки и обработки. Это будет выглядеть примерно так:

Braintree Server to Server (S2S) Payment Flow

Однако в случае прозрачного перенаправления действие формы устанавливается так, чтобы форма отправляла POST напрямую на серверы Braintree , а ответ отправлялся обратно в браузер клиента. Затем браузер перенаправляется в скрипт на веб-сервере с помощью перенаправления HTTP 303. Наконец, скрипт веб-сервера подтверждает транзакцию с Braintree и представляет результаты клиентскому браузеру. Так что эта модель выглядит примерно так:

Braintree Transparent Redirect (TR) Payment Flow

Теперь, когда у нас есть теория, давайте продолжим и напишем некоторый код. Те из вас, кто хотел бы увидеть полную версию, могут найти ее на Github .

Первое, что мы собираемся сделать, — это создать очень простую HTML-форму, чтобы мы могли ввести некоторые данные для отправки в Braintree для обработки. Я собираюсь сделать это как можно более простым, чтобы мы могли сосредоточиться на функциональности.

 <!doctype html> <html lang="en"> <body> <div id="wrap"> <form method="post" action="" autocomplete="off"> <label>Name on Card: <input type="text" name="transaction[credit_card][cardholder_name]"></label> <label>Card Number: <input type="text" name="transaction[credit_card][number]"></label> <label>CVV: <input type="text" name="transaction[credit_card][cvv]" class="short"></label> <label>Expiration Date (MM/YYYY): <input type="text" name="transaction[credit_card][expiration_date]" class="short"></label> <input type="submit" value="submit payment"> </form> </div> </body> </html> 

Здесь ничего сложного не происходит. Единственное, что вы заметите, это то, что имена полей ввода имеют формат массива. Вы можете увидеть полный список допустимых имен полей здесь . Еще одна вещь, которую я укажу на этой странице, заключается в том, что если вы используете платформу, которая имеет проблемы с использованием массивов для входных имен (я смотрю на вас, Zend Framework!), То вы можете использовать альтернативное двойное подчеркивание синтаксис. Таким образом, ваш срок действия будет выглядеть следующим образом:

 <input type="text" name="transaction__credit_card__expiration_date"> 

Единственное, что вы можете заметить, это то, что я добавил в форму атрибут «автозаполнение» и установил для него значение «Выкл.». Брейнтри рекомендует это сделать, и я надеюсь, что причина этого очевидна …

Есть еще несколько вещей, которые нам нужно сделать, чтобы использовать магию прозрачного перенаправления в нашей форме. Но прежде чем мы это сделаем, нам нужно настроить наш скрипт для работы с API Braintree.

Прежде чем я расскажу вам, как это сделать, я просто упомяну, что для ясности я поместил все PHP и HTML в один и тот же файл в моем примере кода. Я надеюсь, что само собой разумеется, что в производственном проекте код установки будет помещен в файл начальной загрузки моего проекта и что код обработки формы перейдет в действие контроллера или другой отдельный файл. Хорошо, достаточно извинений — давайте настроим это!

 <?php require('vendor/autoload.php'); Braintree_Configuration::environment('sandbox'); Braintree_Configuration::merchantId('YOUR_MERCHANT_ID'); Braintree_Configuration::publicKey('YOUR_PUBLIC_KEY'); Braintree_Configuration::privateKey('YOUR_PRIVATE_KEY'); ?> 

Первая строка просто позволяет нам воспользоваться преимуществами автозагрузчика Composer и использовать библиотеку Braintree без явного включения каких-либо дополнительных файлов. Надеемся, что следующие четыре строки выглядят знакомо, потому что они были дословно скопированы из инструмента «Ключ API панели управления песочницей», с которым я познакомил вас в предыдущем разделе. Очевидно, вы замените это кодом из своей учетной записи панели управления.

Следующее, что я хочу сделать, — это настроить действие формы так, чтобы наш клиент отправлял свои конфиденциальные данные непосредственно в Braintree, что является основным смыслом использования TR. К счастью, библиотека Braintree делает это очень легко, предоставляя вспомогательный объект / метод. Так что просто измените код вашей формы следующим образом:

 <form ... action="<?= Braintree_TransparentRedirect::url()?>"> 

Единственное, что нам нужно сделать, — это создать скрытый ввод, который содержит хэшированное представление URL, на который Braintree должен перенаправить клиента после отправки формы, а также любую информацию, которую вы не хотите, чтобы он представлял. в состоянии указать. Например, здесь вы можете указать сумму транзакции. В качестве стиля я предпочитаю указывать обратный URL для самой формы оплаты, чтобы я мог отображать любые ошибки для пользователей и давать им возможность повторной отправки. Вот как это будет выглядеть:

 $tr_data = Braintree_TransparentRedirect::transactionData([ 'transaction' => [ 'type' => Braintree_Transaction::SALE, 'amount' => '100.00' ], 'redirectUrl' => 'https://YOUR-DOMAIN.COM/transparent-redirect-form-basic.php' ]); 

Очевидно, что здесь я жестко программирую сумму, но в производственном приложении вы либо сгенерируете ее с использованием некоторой логики на стороне сервера, либо в случае формы пожертвования с неопределенным итогом вы создадите поле формы и разрешите Пользователь должен предоставить один. Я также обычно устанавливаю для параметра «отправить в расчет» значение true. В противном случае эта транзакция будет просто

Теперь мне просто нужно добавить это как скрытое поле в мою форму следующим образом:

 <input type="hidden" name="tr_data" value="<?=$tr_data?>"> 

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

 $status = ''; if(isset($_GET['http_status']) && $_GET['http_status'] == '200') { try { $result = Braintree_TransparentRedirect::confirm($_SERVER['QUERY_STRING']); if ($result->success) { $status = 'Your transaction was processed successfully.'; } else { $status = $result->message; } } catch (Braintree_Exception_NotFound $e) { $status = 'Due to security reasons, the reload button has been disabled on this page.'; } } 

Теперь давайте выясним, что мы только что сделали. Когда пользователь нажимает кнопку отправки, форма отправляется непосредственно в Braintree, и вся конфиденциальная информация клиента надежно сохраняется на его серверах, совместимых с PCI CSS. Затем в браузер отправляется перенаправление HTTP 303, которое отправляет пользователя по URL-адресу, указанному вами при $tr_data переменной $tr_data , и добавляет несколько параметров в строку запроса URL-адреса.

Когда данные будут успешно отправлены, одним из этих параметров будет http_status , а если все работает с серверами Braintree, он будет установлен в 200 . Очевидно, что в процессе работы вы бы хотели обрабатывать не-200 кодов ответов, но сейчас мы просто выполняем код внутри этого оператора if только в том if если мы успешно передали нашу платежную информацию в их систему.

Следующее, что происходит, это то, что мы должны взять строку запроса из нашего прозрачного перенаправления и отправить ее обратно в Braintree, чтобы завершить транзакцию. Таким образом, мы запускаем другую библиотечную функцию ( Braintree_TransparentRedirect::confirm ) и предоставляем ей строку запроса URL, чтобы сообщить Braintree, что нужно продолжить и обработать наш платеж. Как только это произойдет, Braintree отправит наш скрипт обратно объект результата. Внутренне этот объект может быть либо Braintree_Result_Error либо Braintree_Result_Successful , но оба объекта имеют логическое свойство success поэтому вы можете видеть, была ли транзакция успешной или нет.

Вы также, вероятно, заметили, что я завернул все подтверждение в блок try / catch. Единственный недостаток использования одной и той же страницы для отображения формы и обработки результатов состоит в том, что вы можете подтвердить строку запроса TR только один раз. Это означает, что если кто-то нажмет кнопку перезагрузки после неудачной транзакции, ваш код попытается подтвердить строку запроса с истекшим сроком, и Braintree выдаст исключение.

Теперь, когда у нас есть все, что нам нужно, мы можем запустить несколько тестовых транзакций. Полную документацию по использованию Песочницы можно найти здесь , но если вы действительно взволнованы и хотите сразу же выполнить успешную транзакцию, введите свое имя в поле «Имя на карте», 4111111111111111 (4, а затем пятнадцать) в качестве «номера карты», 123 в поле CVV и любую дату в будущем как дату истечения срока действия. Если все идет хорошо, вы сможете вернуться в «песочницу», нажать «Транзакции» в разделе «Расширенный поиск» и, нажав кнопку «Поиск», увидеть свою первую успешную транзакцию.

Получение фантазии

Прозрачное перенаправление — это отличный способ минимизировать нагрузку на соответствие PCI, но у него есть несколько особенностей, к которым вам нужно привыкнуть. Прежде всего, если вы хотите включить в свою платежную форму какие-либо данные, которые не соответствуют ни одной из транзакций, клиентов или объектов кредитной карты Braintree, то вам необходимо использовать функцию «настраиваемого поля». Допустим, я хотел запечатлеть любимый цвет пользователя. Первое, что я хотел бы сделать, это зайти на панель управления и нажать «Настройки -> Обработка». Прокрутите вниз до раздела «Пользовательские поля» и нажмите «Создать». Вы окажетесь на следующем экране:

Braintree Control Panel Custom Field Page

Имя Api — это то, на что вы будете ссылаться в атрибуте name ввода формы. Отображаемое имя предназначено для вашей справки, и вы можете указать, хотите ли вы сохранить значение своего настраиваемого поля в Braintree с вашей транзакцией или просто передать его обратно на сервер.

Чтобы собрать его, просто добавьте следующее поле в форму.

 <label>Customer Favorite Color: <input type="text" name="transaction[custom_fields][color]"></label> 

Если вы попытаетесь сделать это без добавления настраиваемого поля на панели управления Braintree, вы вызовете ошибку проверки.

Говоря о проверке, TR может усложнить проверку вашей платежной формы на стороне сервера. Допустим, я хотел запросить адрес электронной почты моего клиента. Я бы не знал, что пользователь оставил это поле пустым, пока транзакция не была подтверждена. Решение, которое я нашел, состоит в том, чтобы запустить мою проверку в блоке success моего сценария TR, а затем аннулировать транзакцию, если мои проверки не пройдены. Так что это изменило бы наш код следующим образом:

 if ($result->success) { // transaction was successful, but email is missing if ($result->transaction->customer['email'] == '') { Braintree_Transaction::void($result->transaction->id); $status = 'Email address is a required field'; } else { $status = 'Your transaction was processed succesfully.'; } } 

Как вы можете видеть, если мои локальные проверки не проходят, я использую клиентскую библиотеку, чтобы аннулировать транзакцию, используя идентификатор транзакции из моего объекта Braintree_Result_Success .

Наконец, в нашем базовом примере я не стал заполнять поля формы для пользователя, потому что все наши поля содержат конфиденциальные данные кредитной карты, которые Braintree скрывает от нашего сервера. Но теперь, когда мы добавили некоторые данные о клиентах, я могу предварительно заполнить эти менее чувствительные поля данными из объекта результата Braintree. Вы можете увидеть полный код в моем примере Github , но хитрость в понимании происходящего заключается в том, чтобы знать, что объект Braintree_Result_Success хранит данные формы, отправленные пользователем, в своем свойстве transaction , тогда как Braintree_Result_Error хранит их в свойстве params . Так, например, переменная имени была бы найдена в $result->transaction->customer['firstName'] когда транзакция была успешной, в то время как неудачная транзакция сохранила бы ее в $result->params['transaction']['customer']['firstName'] .

Завершение

Прозрачное перенаправление Braintree — это один из способов минимизировать подверженность вашего приложения конфиденциальным данным клиентов, что снижает нагрузку на соответствие PCI, а их клиентская библиотека PHP значительно упрощает процесс интеграции, но усложняет сбор и проверку не связанных с оплатой информация в той же форме, что и данные кредитной карты вашего клиента.

В следующий раз мы рассмотрим их другое умное решение: Braintree.js.