Обработка кредитных карт, к сожалению, гораздо сложнее, чем мы могли бы надеяться, как разработчики. Учитывая, что это такая распространенная задача, действительно ли необходимо прыгать через бесчисленные обручи (конечно, в окружении огня) с единственной целью обработки платежа? Торговцы? Шлюзы? SSL? Безопасность? Очень быстро, казалось бы, простая операция может стать чрезвычайно запутанной и, что более важно, опасной задачей. Каждый раз, когда вы обнаруживаете, что обрабатываете конфиденциальные данные пользователя, вам лучше быть в тонусе.
Разве не было бы удивительно, если бы существовал сервис, который сделал этот процесс настолько простым, насколько это возможно? Сервис, созданный разработчиками для разработчиков. Что за мысль! Введите полосу ; нет торговых счетов, нет шлюзов. Вызов API, а также несколько правил безопасности — это все, что вам нужно, чтобы начать принимать платежи по кредитным картам сегодня.
Хотя Stripe не является бесплатным, они просят только 2,9% от каждого заряда ( плюс .30 центов ). Вот и все. Нет платы за установку, плата за хранение, скрытые расходы — ничего из этого. Всего 2,9%. Неплохо!
5 ключевых особенностей полосы
- Просто: обработка кредитных карт вручную сложна и опасна. С Stripe это так просто! Вы даже можете обрабатывать обвинения из командной строки!
- Дешево: различные продавцы платежей известны своими скрытыми сборами. Stripe сообщает вам, что именно вы можете заплатить: 2,9% за каждый заряд + 30 центов. Нет платы за установку. Никаких скрытых платежей. Нет платы за хранение карты.
- Интуитивно понятный API: API Stripe является чистым, спокойным и простым в использовании.
- Используется Cool Kids: Если усыновление вызывает беспокойство, это не обязательно. Бесчисленные сервисы используют Stripe, включая Reddit, Grooveshark и Shopify.
- Создано разработчиками: очень четко, Stripe был создан, чтобы почесать зуд разработчика. Команда полна разработчиков и предпринимателей, как и вы.
Давай сделаем это
Продано? Я был тоже. Давайте обработаем наш первый тестовый платеж. Конечно, прежде чем начать, посетите stripe.com
, создайте новую учетную запись (бесплатно) и заполните различные формы, такие как дескриптор выписки и ваши банковские данные.
Для зарядки пользователя требуется два основных шага:
- Получите информацию о кредитной карте пользователя и отправьте запрос AJAX на сервер Stripe, который вернет уникальный токен, представляющий эти защищенные данные.
- Используя выбранный вами серверный язык (PHP для этой статьи), создайте новый заряд Stripe, проходя через уникальный токен.
Создайте форму оплаты
Естественно, первым шагом является создание формы оплаты для вашего продукта. У вас есть два варианта: использовать скрипт проверки Stripe, который автоматически создаст форму, подтвердит вводимые пользователем данные и сгенерирует уникальный токен для данных кредитной карты пользователя. В ситуациях, когда конфигурация и стиль являются гибкими, это отличный путь. Вставьте тег сценария вместе с несколькими пользовательскими атрибутами HTML5, и все готово!
01
02
03
04
05
06
07
08
09
10
|
<form action=» method=»POST»>
<script
src=»https://checkout.stripe.com/v2/checkout.js» class=»stripe-button»
data-key=»pk_test_G5YhIkq2PEq84lwU064TZENT»
data-amount=»2000″
data-name=»Demo Site»
data-description=»2 widgets ($20.00)»
data-image=»/128×128.png»>
</script>
</form>
|
Однако в большинстве ситуаций вам потребуется полный контроль. Таким образом, для целей этой статьи мы будем использовать пользовательскую форму. В этом разделе мы выполним три вещи:
- Используйте форму для сбора информации о кредитной карте пользователя
- Преобразуйте эти данные в уникальный одноразовый токен
- Отправьте форму на сервер вместе с токеном
Базовая форма оплаты может выглядеть так:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<form action=» method=»POST» id=»payment-form»>
<span class=»payment-errors»>
<div class=»row»>
<label>
<span>Card Number
<input type=»text» data-stripe=»number»>
</label>
</div>
<div class=»row»>
<label>
<span>CVC
<input type=»text» data-stripe=»cvc»>
</label>
</div>
<div class=»row»>
<label>
<span>Expiration (MM/YYYY)
<input type=»text» data-stripe=»exp-month»>
</label>
<input type=»text» data-stripe=»exp-year»>
</div>
<button type=»submit»>Buy Now</button>
</form>
|
Обратите внимание, что нам не нужно много информации для обработки кредитной карты. Технически единственной информацией, которую требует Stripe, является номер кредитной карты и срок действия. Однако, как правило, чем больше информации, которую вы получаете от пользователя, тем лучше. Если обвинение будет оспорено, эта дополнительная информация пригодится. Или, другими словами, чем больше информации вы запрашиваете, тем выше вероятность того, что истинный владелец кредитной карты размещает транзакцию. Ключ заключается в том, чтобы найти грань между достаточным и настолько большим, чтобы пользователь не стал заполнять форму . Как минимум, запросите имя пользователя, адрес электронной почты, номер кредитной карты, срок действия и номер CVC.
Чтобы продолжить углубление в вашу голову, никогда не позволяйте конфиденциальным данным кредитной карты касаться вашего сервера. Это может создать мир боли, если оно выполнено неправильно. Вместо этого выберите легкий путь: убедитесь, что input
для данных кредитной карты пользователя не содержат атрибутов name
. Опуская этот атрибут, данные не могут быть опубликованы на вашем сервере.
Обратите особое внимание на пользовательские атрибуты на входах, такие как data-stripe="number"
. Stripe предлагает плагин stripe.js
, который помогает в процессе компиляции предоставленных пользователем данных и генерации токена. Stripe будет искать эти атрибуты и извлекать их соответствующие значения.
Чтобы использовать stripe.js
, stripe.js
к сценарию в своем проекте и установите свой публикуемый ключ, который будет предоставлен при регистрации в Stripe. В этой статье мы также будем использовать jQuery, хотя это, конечно, не обязательно.
1
2
3
4
5
6
7
|
<script src=»//code.jquery.com/jquery-2.0.2.min.js»></script>
<script src=»//js.stripe.com/v2/»></script>
<script>
(function() {
Stripe.setPublishableKey(‘YOUR PUBLISHABLE KEY’);
})();
</script>
|
Думайте о setPublishableKey
как о способе идентификации вашего веб-сайта при общении с Stripe. После регистрации вам будут представлены две разные версии этого ключа для тестирования и производства, соответственно.
Затем нам нужно создать уникальный одноразовый токен для данных кредитной карты пользователя. Для этой цели мы можем использовать объект Stripe
, предоставленный импортированным нами скриптом. Более того, нам не нужно беспокоиться о сериализации данных платежной формы; просто пройдите через объект jQuery формы, а Stripe справится с остальными.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
// Event Listeners
$(‘#payment-form’).on(‘submit’, generateToken);
var generateToken = function(e) {
var form = $(this);
// No pressing the buy now button more than once
form.find(‘button’).prop(‘disabled’, true);
// Create the token, based on the form object
Stripe.create(form, stripeResponseHandler);
// Prevent the form from submitting
e.preventDefault();
};
var stripeResponseHandler = function(status, response) {};
|
С помощью этого кусочка JavaScript при stripe-
платежной формы Stripe попытается сгенерировать токен одноразового использования, используя связанные данные из входных данных, которые включают специальные атрибуты stripe-
. Второй аргумент метода create
— это обратный вызов, который получит токен ( response.id
) с сервера Stripe и будет действовать соответствующим образом.
В рамках этого обратного вызова важно проверить результат (правильно ли была предоставлена вся информация), вставить токен в скрытый input
и отправить форму на свой сервер. Опять же, обратите внимание, что информация о кредитной карте не должна / не попадет на ваш сервер — только токен и нечувствительные данные. Это важно, поэтому напишите приемочные или функциональные тесты, чтобы проверить это.
Ваш обратный вызов может выглядеть так:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
var stripeResponseHandler = function(status, response) {
var form = $(‘#payment-form’);
// Any validation errors?
if (response.error) {
// Show the user what they did wrong
form.find(‘.payment-errors’).text(response.error.message);
// Make the submit clickable again
form.find(‘button’).prop(‘disabled’, false);
} else {
// Otherwise, we’re good to go!
// Insert the unique token into the form
$(‘<input>’, {
‘type’: ‘hidden’,
‘name’: ‘stripeToken’,
‘value’: response.id
}).appendTo(form);
// Call the native submit method on the form
// to keep the submission from being canceled
form.get(0).submit();
}
};
|
Это действительно довольно просто! Отправьте запрос AJAX в API Stripe (используя их полезный плагин JavaScript), получите сгенерированный токен, вставьте его в форму и опубликуйте на своем сервере!
Зарядка
Если после этого вы успешно сгенерировали токен одноразового использования и отправили форму оплаты. Теперь пришло время для вашего языка на стороне сервера физически создать заряд. Помните, что в предыдущем разделе не было сделано никаких обвинений. Мы только сгенерировали токен, который представлял данные кредитной карты.
Stripe предлагает ряд серверных библиотек для регистрации новых платежей или даже организации подписок. Высоки шансы, что ваш предпочтительный язык представлен (PHP, Ruby, Python и т. Д.).
Как и в предыдущем разделе, отправка нового платежа может быть выполнена в несколько шагов:
- Объявите свой ключ API
- Используя библиотеку Stripe, сделайте вызов API, пройдя через детали транзакции
- Подтвердите заряд и действуйте соответствующим образом.
Обратитесь к странице библиотеки Stripe для получения инструкций по установке. При использовании PHP, как будет в этой статье, рекомендуется использовать Composer для загрузки пакета Stripe.
1
2
3
4
5
|
{
«require»: {
«stripe/stripe-php»: «dev-master»
}
}
|
Composer — это будущее управления зависимостями PHP, так что начните прямо сейчас, если вы еще этого не сделали. Базовый заряд Stripe может принимать форму:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
// Set your API key
Stripe::setApiKey(«YOUR API KEY»);
try {
Stripe_Charge::create([
‘amount’ => 2000, // this is in cents: $20
‘currency’ => ‘usd’,
‘card’ => $_POST[‘stripeToken’],
‘description’ => ‘Describe your product’
]);
} catch (Stripe_CardError $e) {
// Declined.
// Go back, and tell the user to try a new card
}
|
Это оно! Ключ API аутентифицирует вас как действующего пользователя Stripe. Как и публикуемый ключ, Stripe предоставит вам две разные версии этого ключа: одну для тестирования и производства, соответственно.
Обратите внимание, что все расходы на Stripe должны быть объявлены в центах (конечно, в зависимости от валюты). Если цены хранятся в вашей базе данных в долларах, евро или фунтах, то вы захотите соответственно компенсировать это при оплате.
Если исключение не выдано, вы можете быть уверены, что платеж успешно обработан. Продолжайте, предлагая пользователю их цифровую загрузку или регистрируя их покупку в вашей системе.
Хотите верьте, хотите нет, работа Stripe закончена. Конечно, вы можете сделать еще больше, например, создать клиентов и управлять подписками, но когда дело доходит до простой обработки одного платежа, все готово! … кроме тебя нет.
SSL
Хотя да, работа Stripe закончена, а ваша — нет. Независимо от провайдера платежей, в любое время, когда вы работаете с информацией о кредитной карте, безопасность должна быть главной заботой. Мы уже сделали первые шаги, гарантируя, что данные кредитной карты никогда не коснутся сервера, но еще многое предстоит сделать. Далее мы должны защитить соединение пользователя с вашим сервером. Другими словами, вам нужен сертификат SSL. Ни при каких обстоятельствах вы не должны пропустить этот шаг!
«SSL (Secure Sockets Layer) — это стандартная технология безопасности для установления зашифрованной связи между веб-сервером и браузером. Эта ссылка гарантирует, что все данные, передаваемые между веб-сервером и браузерами, останутся частными и целостными ». — info.ssl.com
Когда пользователь предлагает веб-сайту информацию о своей кредитной карте, он ожидает увидеть https
в адресной строке. К счастью, приобрести сертификат SSL гораздо проще, чем раньше. На самом деле, большинство хостов предлагают надстройку SSL, которая превращает весь процесс в один клик. То же самое верно для различных вариантов SaaS, таких как Pagoda Box или Heroku.
Совет. После включения SSL возможно повреждение изображений и ресурсов. Чтобы это исправить, убедитесь, что все URL-адреса используют
https
, а неhttp
. Или, как лучшее решение, используйте относящиеся к протоколу URL.
1
2
3
4
5
|
<!— Not good for SSL —>
<img src=»http://domain.com/images/foo.jpg» alt=»Foo Bar»>
<!— Better —>
<img src=»//domain.com/images/foo.jpg» alt=»Foo Bar»>
|
С этой техникой, популярной у Пола Айриша, если текущая страница использует HTTPS, то ресурс также будет запрашиваться с HTTPS.
Предполагая, что ваш хост предлагает надстройку SSL в один клик, просто укажите вашему пользователю https://
версию страницы заказа, и все готово!
Советы и приемы
Примеры в этой статье простые и в основном процедурные. Однако высока вероятность того, что вы будете работать со структурой, которая поддерживает несколько сред, маршрутизацию и средства тестирования. Используйте следующие советы в качестве основы для интеграции Stripe с вашими предпочтениями.
1. Специальные номера кредитных карт
Очевидно, что вы не хотите использовать реальные номера кредитных карт для проверки ваших платежных форм! К счастью, нашивка уже подумала об этом; они включают в себя ряд номеров кредитных карт, которые имитируют конкретные ответы, такие как успешный платеж, неверный номер, неправильный код CVC и многие другие.
Вот несколько номеров карт, на которые вы будете часто ссылаться:
- Одобренная виза: 4242424242424242
- Одобрено Mastercard: 5555555555554444
- Карта отклонена: 4000000000000002
- Неверный номер: 4242424242424241
2. Используйте окружение с умом
При работе с Stripe у вас будет два уникальных ключа, которые представляют API и публикуемые ключи. Кроме того, для каждого из них есть варианты тестирования и производства. Большинство фреймворков предлагают способ управления несколькими средами. Таким образом, для разработки ваше приложение будет правильно использовать ключи тестирования, а после развертывания будут ссылаться на рабочие версии.
Ниже приведен проект для Laravel. Laravel предоставляет простую систему среды. Добавьте файл конфигурации в папку, соответствующую имени среды, и эти значения будут иметь приоритет над значениями по умолчанию.
Сначала мы устанавливаем ключи производства:
1
2
3
4
5
6
|
<?php // app/config/stripe.php
return [
‘apiKey’ => ‘PRODUCTION API KEY’,
‘publishableKey’ => ‘PRODUCTION PUBLISHABLE KEY’
];
|
А для разработки мы переопределяем производственные ключи с помощью их тестовых аналогов:
1
2
3
4
5
6
|
<?php // app/config/development/stripe.php
return [
‘apiKey’ => ‘TEST API KEY’,
‘publishableKey’ => ‘TEST PUBLISHABLE KEY’
];
|
Теперь, когда приложению требуется ключ API с помощью Config::get('stripe.apiKey')
, возвращаемое значение будет определяться средой. Успех!
3. Не подключайте приложение к полосе
Распространенная ошибка, которую начинающие разработчики делают из-за связи своих приложений с различными поставщиками, такими как Stripe. Ваше приложение не должно заботиться о том, какой поставщик биллинга используется. Это связано только с тем, что один доступен. Путем жесткого кодирования ссылок на Stripe в ваших классах вы создаете прямую связь между этими двумя понятиями, которую, вероятно, будет трудно изменить.
Спросите себя: «Если в будущем мне нужно поменять Stripe с другим провайдером, насколько это будет сложно?»
Вместо этого, код для интерфейса — возможно, BillingProvider
или BillingGateway
. Таким образом, вы можете создать различные реализации интерфейса: одну для Stripe или другую для другого сервиса, если возникнет такая необходимость. Эти различные реализации будут содержать функциональные возможности для конкретной службы. Если в какой-то момент вы найдете более дешевого поставщика биллинга, чем Stripe, замена реализации BillingProvider
на Stripe с версией ServiceX
займет всего одно мгновение, то есть после создания новой реализации, запрашивающей API биллинга ServiceX
.
Вот скелет того, как это может выглядеть:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
// Define the interface
interface BillingProvider {
public function charge($creditInfo);
}
// Create a Stripe implementation
class StripeBilling {
public function charge($creditInfo)
{
// Stripe_Charge::charge(…);
}
}
// Create a ServiceX implementation
class ServiceXBilling {
public function charge($creditInfo)
{
// charge user with ServiceX
}
}
|
Теперь, когда у нас есть две реализации, мы можем ссылаться на наш текущий предпочтительный сервис биллинга, используя внедрение зависимостей.
1
2
3
4
5
6
7
8
|
class PaymentController {
protected $billing;
public function __construct(BillingProvider $billing)
{
$this->billing = $billing;
}
}
|
При таком стиле разработки, если вам в конечном итоге потребуется отойти от Stripe, к контроллеру не нужно прикасаться. Поскольку Stripe не имеет жесткого кода, он не знает разницы!
4. Не оставляйте покупателя висеть
При продаже цифровых товаров спросите себя: «Что должен делать покупатель, если что-то пойдет не так с моей стороны?». Всегда предоставляйте покупателю возможность связаться с вами или вашей компанией. Что если электронное письмо с подтверждением, содержащее ссылку для загрузки цифрового файла, никогда не поступит в почтовый ящик покупателя? Что они должны делать?
Сайт поддержки или даже простой адрес электронной почты на главной странице должен помочь в этих неизбежных ситуациях.
5. SSL-сертификаты
Если вам необходимо вручную приобрести сертификат SSL, есть несколько услуг на выбор. Основываясь на предыдущем опыте, вы можете ожидать, что потратите от тридцати минут до часа на настройку. Имейте в виду, что большинство сертификатов не являются бесплатными и могут варьироваться от 10 до 500 долларов США, в зависимости от поставщика.
Команда Stripe рекомендует DigiCert и Namecheap , хотя, если вы предпочитаете, вы можете рассмотреть бесплатное решение, такое как StartSSL .
6. Не полагайтесь на цену формы
Частая ошибка связана с использованием данных формы для определения цены приобретаемого продукта, возможно, посредством скрытого ввода. Поскольку пользователь может легко редактировать значение этого ввода, неразумно зависеть от него. Всегда выбирайте цену продукта со стороны сервера. Никогда не полагайтесь на форму, чтобы сказать вам. Простой запрос к базе данных является предпочтительным вариантом.
7. Цифровой файл не должен быть общедоступным
Актив, который вы продаете, никогда не должен быть доступен публике, даже если URL, по вашему мнению, является длинным и запутанным настолько, что большинство его никогда не узнает. Это плохая практика по ряду причин.
Вместо этого создайте таблицу downloads
которой хранятся уникальные коды покупок и идентификаторы соответствующих продуктов. Таким образом, когда запрашивается URI, такой как /downloads/23gsfga831g
, ваше приложение будет:
- Сверьте предоставленный токен с тем, что хранится в таблице базы данных.
- В ответ предложите загрузить файл, связанный с токеном покупки.
Чтобы пойти дальше, вы также можете установить ограничение на скачивание. Для этого просто необходимо добавить поле download_count
в таблицу purchases
. При каждом запросе это число должно увеличиваться на единицу. Как только этот номер достигнет установленного вами порога, загрузка больше не должна предоставляться. Это может быть полезно в тех случаях, когда вы хотите убедиться, что ссылки для скачивания не передаются.
Вывод
Замечательная вещь в Stripe заключается в том, что он переводит сложную, запутанную и опасную операцию в один простой вызов API. Нет торговых счетов, нет шлюзов, нет скрытых платежей. Есть причина, по которой они говорят, что Stripe просто смешен в использовании. Это!