xandeadx.ru Блог музицирующего веб-девелопера

Drupal → Оплата доступа к ноде с помощью Робокассы

Опубликовано в

Пример организации платного доступа к конкретной ноде с помощью модуля Robokassa Merchant и своего кода.

Будем продавать доступ к материалам типа article.

1. Настраиваем модуль робокассы и сам мерчант.

2. Добавляем типу материала Article два поля:

— Цена, field_price, тип Integer
— Покупатели, field_buyers, тип Entity reference

3. Скрываем контент для не оплативших пользователей — будем при просмотре full ноды переключать дисплей на teaser:

/**
 * Return TRUE if user paid node.
 */
function modulename_user_is_paid($node, $uid = NULL) {
  if ($uid === NULL) {
    $uid = $GLOBALS['user']->uid;
  }
  $node_wrapper = entity_metadata_wrapper('node', $node);
  return in_array($uid, $node_wrapper->field_buyers->raw());
}
 
/**
 * Implements hook_entity_view_mode_alter().
 */
function modulename_entity_view_mode_alter(&$view_mode, $context) {
  if ($context['entity_type'] == 'node'
  && $context['entity']->type == 'article'
  && $view_mode == 'full'
  && !modulename_user_is_paid($context['entity'])) {
    $view_mode = 'teaser';
  }
}

4. Выводим не оплатившим пользователям форму оплаты:

/**
 * Payment form.
 */
function modulename_payment_form($form, &$form_state, $nid) {
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Оплатить',
  );
  return $form;
}
 
/**
 * Implements hook_node_view().
 */
function modulename_node_view($node, $view_mode, $langcode) {
  if ($node->type == 'article' && !modulename_user_is_paid($node)) {
    $node->content['payment_form'] = drupal_get_form('modulename_payment_form', $node->nid);
    $node->content['payment_form']['#weight'] = 100;
  }
}

5. Реализуем submit callback формы оплаты, в нём создаём транзакцию и редиректим на промежуточную страницу:

/**
 * Submit callback.
 */
function modulename_payment_form_submit($form, &$form_state) {
  $nid = $form_state['build_info']['args'][0];
  $node_wrapper = entity_metadata_wrapper('node', $nid);
 
  $payment = robokassa_api('insert', array(
    'uid' => $GLOBALS['user']->uid,
    'created' => REQUEST_TIME,
    'amount' => $node_wrapper->field_price->value(),
    'currency' => 'RUB',
    'memo' => 'Оплата материала',
    'nid' => $nid,
  ));
 
  $form_state['redirect'] = 'robokassa/payment/' . $payment['pid'];
}

6. После успешной оплаты заносим юзера в поле field_buyers:

/**
* Implements hook_robokassa().
*/
function modulename_robokassa($op, $pid, $payment = array()){
  if ($op == 'enrolled' && $payment['memo'] == 'Оплата материала') {
    $params = unserialize($payment['params']);
    $node = node_load($params['nid']);
    $node->field_buyers['und'][]['target_id'] = $payment['uid'];
    node_save($node);
  }
}

7. Даём авторизованным пользователям право делать оплату своих платежей.

Profit.

В коде для краткости нет логики работы с анонимными пользователями.

Написанное актуально для Drupal 7
Похожие записи

Комментарии RSS

$node->field_buyers['und'][]['target_id'] = $payment['uid'];
Возможно же появление вместо und - ru например?!
Может лучше тоже через entity_metadata_wrapper делать?

ну только если захочется раздельно продавать разные языковые версии ноды.
в entity_metadata_wrapper то же придётся указывать язык

Спасибо большое за материал.
Это, в принципе, то, что я спрашивал на dru.io.

А если мне нужно продавать контент незарегистрированным пользователям? Как тогда реализовать?

* требовать регистрацию
* регистрировать самостоятельно
* реализовать систему с уникальными ссылками

Я предполагал что-то вроде ключа (например передавать его через URL или сделать страницу-прослойку для ввода ключа)

https://www.drupal.org/project/comment_notify - в этом модуле так и реализовано - ключ в урле. Можете попробовать понять как это сделано и не забудьте поделиться с нами ;-)
Но проще требовать email! Он есть у всех кому нужен ваш контент. Другое - это ваша головная боль при разработке - стоит ли она того?

Надо :)
Работаю над проектом, скажем, по продаже консультаций. Так вот статистика показывает, что пользователи уходят со страницы где нужно заполнить контактные данные... следовательно, не переходят на страницу оплаты.
Вот думаю как реализовать анонимную продажу консультаций. Если найду хороший способо - обязательно поделюсь

Сделать бы тоже самое но через Yandex.Money миную Drupal Commerce. Возможно ли сие?

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании