Статьи

Как настроить регулярные платежи

Вполне вероятно, что в какой-то момент вы захотите осуществить регулярные платежи или оплату подписки на SaaS или другую услугу. К счастью, PayPal предлагает инструменты, необходимые для реализации полностью интегрированного решения по оплате подписки.


Примечание. В этом руководстве я использую Laravel, но вы можете применить эти концепции к другим языкам и средам.

Мы настроим PayPal для приема платежей по подписке и настроим прослушиватель уведомлений о мгновенных платежах (IPN). Как только мы завершим компонент регистрации, мы рассмотрим процесс отмены через API PayPal. Я начинаю с простого приложения Laravel с простой регистрацией и входом в систему, и мы добавим компоненты, необходимые для введения платежей по подписке, по мере прохождения учебного курса.


PayPal предоставляет настраиваемое поле, которое мы можем использовать для передачи идентификатора пользователя.

Прежде чем мы начнем, убедитесь, что у вас есть бизнес-аккаунт PayPal. Это бесплатно, но вы должны иметь бизнес-аккаунт, чтобы осуществлять подписку на вашем сайте.

PayPal предлагает несколько типов кнопок, которые мы можем использовать, в том числе: Купить сейчас, Подписаться и Автоматический биллинг. Сегодня мы рассмотрим кнопку подписки. Кнопки подписки позволяют установить сумму выставления счета, а также период повторяющихся платежей. Вы также можете установить пробный период и позволить PayPal создать учетную запись пользователя, когда он пингует ваш сервер.

Сначала войдите в свою учетную запись PayPal и перейдите в « Профиль» -> «Мои настройки продаж» . Затем найдите раздел « Кнопки PayPal » и выберите « Подписки» в раскрывающемся списке. Обязательно заполните остальную информацию.

Я рекомендую не устанавливать флажок «Пусть PayPal создает имена пользователей и пароли для клиентов» и выбрать вариант «Использовать мой безопасный идентификатор учетной записи продавца».

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

Создайте свою кнопку и скопируйте сгенерированный код; вы будете использовать его в своем приложении.

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

К счастью, PayPal предоставляет настраиваемое поле, которое мы можем использовать для передачи идентификатора пользователя. Он имеет ограничение в 256 символов. Поэтому я собираюсь использовать структуру JSON, позволяющую нам передавать дополнительную информацию, если нам это нужно.

1
<input type=»hidden» name=»custom» value=»{{json_encode(array(‘user_id’ => Auth::user()->id))}}»>

Обязательно ознакомьтесь с полным списком допустимых переменных HTML .


Сначала нам нужно настроить нашу таблицу платежей, где мы будем хранить наши транзакции. Давайте создадим его со следующими столбцами:

  • id : автоинкрементное целое число и наш первичный ключ.
  • txn_id : идентификатор нашей транзакции, который нам даст PayPal. Установите это как varchar.
  • user_id : Мы будем использовать это, чтобы установить наши отношения с пользовательской таблицей, целое число сделает.
  • paypal_id : идентификатор профиля PayPal, который нам понадобится для отмены позже. Установите это как varchar.
  • created_at : мы будем использовать это, чтобы увидеть, когда транзакция будет завершена, и начать подписку.

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


PayPal предоставляет простое решение для уведомления нас об обработке платежа; они называют это мгновенными платежными уведомлениями (IPN). Чтобы воспользоваться преимуществами IPN, нам необходимо создать прослушиватель IPN для нашего приложения. Слушатель проверяет данные, вставляет их в нашу таблицу платежей и устанавливает уровень подписки пользователя.

К счастью, нам не нужно изобретать велосипед благодаря этому удобному классу . Мы будем использовать класс IpnListener для быстрой проверки данных, а затем мы можем обработать их, чтобы вставить их в нашу базу данных. С Laravel мы можем поместить класс в нашу папку библиотек, что делает его автозагрузкой для нас.

Создайте новый контроллер или маршрут и добавьте следующий код:

01
02
03
04
05
06
07
08
09
10
11
12
13
$listener = new IpnListener();
 
try {
    $verified = $listener->processIpn();
} catch (Exception $e) {
    exit(0);
}
 
if ($verified) {
    // IPN response was «VERIFIED»
} else {
    // IPN response was «INVALID»
}

Я назвал свой файл ipn.php и сопоставлю его с /ipn . Не забывайте, что PayPal будет отправлять по этому URL; поэтому, если вы используете глаголы HTTP / REST, настройте их соответствующим образом. Отсюда мы можем обработать наши данные:

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
28
$listener = new IpnListener();
 
try {
    $verified = $listener->processIpn();
} catch (Exception $e) {
    return Log::error($e->getMessage());
}
 
if ($verified) {
 
    $data = $_POST;
    $user_id = json_decode($data[‘custom’])->user_id;
 
    $subscription = ($data[‘mc_gross_1′] == ’10’) ?
 
    $txn = array(
        ‘txn_id’ => $data[‘txn_id’],
        ‘user_id’ => $user_id,
        ‘paypal_id’ => $data[‘subscr_id’],
        ‘subscription’ => $subscription,
        ‘expires’ => date(‘Ymd H:i:s’, strtotime(‘+1 Month’)),
    );
 
    Payment::create($txn);
 
} else {
    Log::error(‘Transaction not verified’);
}

В этом коде мы сначала декодируем JSON, переданный в наше настраиваемое поле, предоставляя нам легкий доступ к идентификатору пользователя. Затем мы устанавливаем уровень подписки на основе суммы транзакции и сохраняем ее в базе данных. Мы также регистрируем любые ошибки, используя класс Laravel Log. Также было бы неплохо отправить квитанцию ​​пользователю, но я оставлю это на ваше усмотрение.


Далее нам нужно включить IPN и настроить PayPal для проверки связи с нашим слушателем. Поскольку панель администрирования PayPal может быть сложной для навигации, я включил следующие скриншоты, чтобы помочь вам. Перейти в профиль -> Настройки продаж :

Затем найдите уведомления о мгновенных платежах :

Далее нажмите « Выбрать настройки IPN» :

А затем введите URL для вашего слушателя:


Пока мы на панели инструментов, стоит получить учетные данные API, прежде чем мы рассмотрим процесс отмены. Перейти в профиль -> Настройки продаж :

Ищите API Access :

Выберите вариант 2 :

Запросить подпись API:

И принять к сведению ваши полномочия:


Для осуществления платежей по подписке у вас должен быть бизнес-аккаунт.

Примечание. Для обработки отмены вам понадобится сертификат SSL или PayPal с сообщением об ошибке.

Чтобы обеспечить лучший пользовательский опыт, скорее всего, вы захотите обрабатывать отмены внутри вашего приложения или службы. PayPal предоставляет несколько API, которые позволяют нам делать это: NVP или SOAP. Я бы порекомендовал пойти с NVP.

Документация PayPal, кажется, усложняет ситуацию, но NVP (Name-Value-Pair) — это просто строка в кодировке URL, которую мы можем обработать.

Интересующий нас метод — ManageRecurringPaymentsProfileStatus . Мы можем изменить состояние подписки, выбрав одно из следующих трех действий:

  • Отмена : только активные или приостановленные подписки могут быть отменены. Выбор этого действия предотвращает повторную активацию пользователя позднее.
  • Приостановить : только активные подписки могут быть приостановлены. Это действие позволяет пользователям повторно активировать свою подписку позже.
  • Повторно активировать: только приостановленные подписки могут быть повторно активированы, повторно создавая подписку.

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

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
28
$input = Input::all();
 
$req = array(
    ‘USER’ => ‘YOUR_API_USER’,
    ‘PASSWORD’ => ‘YOUR_API_PASSWORD’,
    ‘SIGNATURE’ => ‘YOUR_API_SIGNATURE’,
    ‘VERSION’ => ‘76.0’,
    ‘METHOD’ => ‘ManageRecurringPaymentsProfileStatus’,
    ‘PROFILEID’ => urlencode($input[‘paypal_id’]),
    ‘ACTION’ => ‘Cancel’,
    ‘NOTE’ => ‘User cancelled on website’,
);
 
$ch = curl_init();
 
// Swap these if you’re testing with the sandbox
// curl_setopt($ch, CURLOPT_URL, ‘https://api-3t.sandbox.paypal.com/nvp’);
curl_setopt($ch, CURLOPT_URL, ‘https://api-3t.paypal.com/nvp’);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($req));
curl_exec($ch);
curl_close($ch);
 
return Redirect::to(‘settings’)->with(‘cancelled’, true);

Теперь мы можем легко отменить подписку, но по какой-то причине PayPal решил не отправлять запрос IPN. Это не проблема, поскольку мы настроили наше приложение так, чтобы оно содержало столбец с expires сроком expires . Таким образом, мы можем проверить это поле, чтобы определить, подписан ли пользователь.


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

Мы собираемся протестировать наш слушатель, убедившись, что он работает правильно, без необходимости выполнять реальные транзакции. Прежде чем мы что-то сделаем в песочнице, нам нужно настроить наш прослушиватель IPN для проверки связи с песочницей вместо живого сервера.

1
$listener->use_sandbox = true;

Теперь перейдите в « песочницу» PayPal , войдите в систему, нажмите « Тестовые инструменты» слева и откройте симулятор IPN.

Введите URL-адрес вашего слушателя и выберите « Быстрая проверка» в раскрывающемся списке. Вы можете использовать большинство деталей по умолчанию, но не забудьте поместить свой JSON в настраиваемое поле внизу страницы.


Итак, мы настроили нашу подписку и разрешили пользователям отменять услугу, теперь, как мы проверяем это? Laravel делает это легко, и его метод транслируется во многие языки и структуры. Я собираюсь добавить метод к моей модели User который дает нам доступ к подписке, используя класс Auth Laravel:

1
2
3
4
5
public function subscription(){
    return Payment::where(‘user_id’, ‘=’, Auth::user()->id)
                ->where(‘expires’, ‘>’, date(‘Ymd H:i:s’, time()))
                ->first(array(‘subscription’, ‘expires’, ‘paypal_id’, ‘txn_id’));
}

Теперь мы можем получить к нему доступ и проверить наши контроллеры и представления очень легко. Например:

01
02
03
04
05
06
07
08
09
10
<?php
$sub = Auth::user()->subscription();
if($sub && $sub->subscription == 1){
    echo ‘You\’re on the standard plan’;
} elseif($sub && $sub->subscription == 2){
    echo ‘You\’re on the premium plan’;
} else {
    echo ‘You\’re not subscribed’;
}
?>

Надеемся, что это руководство дало вам представление о том, насколько просто настроить повторяющиеся платежи или подписку в ваших приложениях. PayPal ни в коем случае не единственный платежный процессор, но он является одним из самых узнаваемых и широко используемых.

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