Пример организации платного доступа к конкретной ноде с помощью модуля 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.
В коде для краткости нет логики работы с анонимными пользователями.
- Тонкая настройка прав материалов с помощью hook_node_access()
- Добавить своё действие над сущностью в bulk operations
- Добавить своё действие над сущностью в contextual links
- Добавить своё действие над сущностью в operations links
- Добавляем на страницу управления отображением материала поля "Заголовок" и "Дата создания"
Комментарии
$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. Возможно ли сие?
Вместо
'und'
нужно использовать константуLANGUAGE_NONE
(D7).зачем?
Есть константа и нужно использовать ее. Это тоже самое, если использовать
\n
вместоPHP_EOL
.Зачем использовать константу? Затем, что Вы на 100% уверены, что код будет работать так, как Вы ожидаете. Если в каком-нибудь 7.99 релизе друпала значение этой константы будет отличным от
und
, то Ваш код как минимум посыпет нотисы.Я и с und уверен, что код будет работать так, как ожидаю. Ни в 7.99, ни в 8.99 und ни на что не поменяют, можете быть уверены.
Странный подход. Ну, делаете как считаете нужным.
Статус "enrolled" устанавливается только если вручную поставить галочку в админке что платеж зачислен.
Пожалуйста, пожскажите, как сделать чтобы при успешной оплате статус "enrolled" ставился автоматом?
Спасибо!
Спасибо большое. А что делать, если каждая нода может продаваться только 1 раз? Т.е. когда купил доступ к одной ноде - она больше не возможна к продаже.
Здесь только coomerce спасёт?
А как прикрутить робокассу к форме создания ноды? Чтобы после создания появлялась форма оплаты и нода публиковалась
Спасибо, полезно. А можно ли таким макаром сделать доступ не к ноде а к полю? К примеру нода открыта для всех а поле скрыто модулем field-permission
Мистика какаято, хочу отправить письмо с аттачем после оплаты. Письмо приходит а аттача-файла нет. Если убрать условие if ($op == 'enrolled') то приходит 3 письма, 2 с аттачем третье без. Не подскажете - где проблема?
Добавить комментарий