воскресенье, 31 января 2010 г.

Америкосы тоже умеют шутить =)

Вчера ночью играл в покер на одном сайте, и один из игроков по имени Tom такую фразу зарядил:
Пара на тузах - она как Курникова, выглядит класно, но никогда не выигрывает!

суббота, 9 января 2010 г.

Написание платежных модулей

Я хочу поделиться своим, в общем-то немалым (уже более десятка модулей), опытом написания платежных модулей для Magento. Я не буду заниматься пересказом статьи из Magento wiki освещающей основы создания платежных модулей. Я просто напишу несколько совсем не очевидных, но тем не менее, весьма полезных приемов/советов которые я вывел для себя.  Они не являются обязательными, но если вы последуете им то пользователи ваших модулей скажут вам спасибо.
1. Всегда храните важные данные платежных модулей(пароли, секретные слова для формирования подписи и тд) зашифрованными:
  1. <security_code translate="label">
  2.     <label>Security code</label>
  3.     <frontend_type>text</frontend_type>
  4.     <backend_model>adminhtml/system_config_backend_encrypted</backend_model>
  5.     <sort_order>50</sort_order>
  6.     <show_in_default>1</show_in_default>
  7.     <show_in_website>1</show_in_website>
  8.     <show_in_store>1</show_in_store>
  9. </security_code>
* This source code was highlighted with Source Code Highlighter.
Расшифровывать их совсем не сложно:
  1. Mage::helper('core')->decrypt($this->getConfigData("security_code"));
* This source code was highlighted with Source Code Highlighter.
2. Не ленитесь выносить в конфиг название платежки, флаг для включения/выключения платежки и поле для сортировки платежек на странице чекаута. Это не потребует от вас много усилий, но зато сильно упростит жизнь вашим пользователям. Нужно только прописать в конфиге поля с именами "active", "title", "sort_order", остальное Magento берет на себя:
  1. <active translate="label">
  2.     <label>Enabled</label>
  3.     <frontend_type>select</frontend_type>
  4.     <source_model>adminhtml/system_config_source_yesno</source_model>
  5.     <sort_order>10</sort_order>
  6.     <show_in_default>1</show_in_default>
  7.     <show_in_website>1</show_in_website>
  8.     <show_in_store>0</show_in_store>
  9. </active>
  10. <title translate="label">
  11.     <label>Title</label>
  12.     <frontend_type>text</frontend_type>
  13.     <sort_order>60</sort_order>
  14.     <show_in_default>1</show_in_default>
  15.     <show_in_website>1</show_in_website>
  16.     <show_in_store>1</show_in_store>
  17. </title>
  18. <sort_order translate="label">
  19.     <label>Sort order</label>
  20.     <frontend_type>text</frontend_type>
  21.     <sort_order>70</sort_order>
  22.     <show_in_default>1</show_in_default>
  23.     <show_in_website>1</show_in_website>
  24.     <show_in_store>1</show_in_store>
  25. </sort_order>
* This source code was highlighted with Source Code Highlighter.
Вы можете задастся вопросом, почему эти переменные должны называться именно "active", "title", "sort_order". Ответ кроется в классе Mage_Payment_Model_Method_Abstract, от которого наследуются все модели платежных модулей.

3. Сохраняйте в ордере идентификаторы полученные от платежной системы(transaction id и тд) чтобы можно было легко соотносить ордера со статистикой предоставляемой платежной системой . Для этого нужно добавить атрибут для сущности 'order_payment':
  1. /sql/mymodule_setup/mysql4-install-1.0.0.php:
  2. $setup = new Mage_Eav_Model_Entity_Setup('core_setup');
  3.  
  4. //create attribute for order
  5. $setup->addAttribute('order_payment', 'some_transaction_number', array(
  6.      'type' => 'varchar',
  7.      'user_defined' => 0,
  8.      'input' => '',
  9.      'visible' => 1,
  10.      'label' => 'Some transaction number',
  11.      'global' => 1,
  12.      'is_configurable' => 1,
  13.      'group' => 'General',
  14.      'default' => ''
  15.      )
  16. );
* This source code was highlighted with Source Code Highlighter.
Написать в /etc/config.xml о том что мы хотим выполнить кое-какие скрипты при установке:
  1. <global>
  2.     ......
  3.     <resources>
  4.         <alertpay_setup>
  5.             <setup>
  6.                 <module>Cool_Module</module>
  7.             </setup>
  8.             <connection>
  9.                 <use>core_setup</use>
  10.             </connection>
  11.         </alertpay_setup>
  12.         <alertpay_write>
  13.             <use>core_write</use>
  14.         </alertpay_write>
  15.         <alertpay_read>
  16.             <use>core_read</use>
  17.         </alertpay_read>
  18.     </resources>
  19.     .....
  20. </global>
* This source code was highlighted with Source Code Highlighter.
И при получении подтверждения о совершении платежа сохранять эту информацию в ордер:
  1. $order->getPayment()->setData('some_transaction_number', $some_transaction_number);
  2. .....
  3. $order->save();
* This source code was highlighted with Source Code Highlighter.
4. Выносите отношения <статус платежа> ->  <статус ордера> в конфиг, если не все то по крайней мере основные:
  1. <new_order_status translate="label">
  2.     <label>New payment status</label>
  3.     <frontend_type>select</frontend_type>
  4.     <source_model>adminhtml/system_config_source_order_status</source_model>
  5.     <sort_order>80</sort_order>
  6.     <show_in_default>1</show_in_default>
  7.     <show_in_website>1</show_in_website>
  8.     <show_in_store>0</show_in_store>
  9. </new_order_status>
  10. <approved_order_status translate="label">
  11.     <label>Approved payment status</label>
  12.     <frontend_type>select</frontend_type>
  13.     <source_model>adminhtml/system_config_source_order_status</source_model>
  14.     <sort_order>90</sort_order>
  15.     <show_in_default>1</show_in_default>
  16.     <show_in_website>1</show_in_website>
  17.     <show_in_store>0</show_in_store>
  18. </approved_order_status>
* This source code was highlighted with Source Code Highlighter.
Если вам кажется что это же очевидно, новый ордер - ставим в pending, оплаченный ордер в processing - то я вас огорчу. Всегда найдется десяток индивидуумов со своим "особым" видением бизнес логики, у которых все будет ровным счетом наоборот. И они вам непременно напишут, при чем в независимости от того какой модуль - платный или нет. Поэтому лучше дать возможность пользователю самому выбрать, этим вы сбережете нервы и себе и своим клиентам.
5. Еще один достаточно спорный вопрос - это посылка email оповещения об ордере. Лично для себя я решил посылать это оповещение только при получении подтверждения оплаты:
  1. $order->sendNewOrderEmail();
  2. $order->setEmailSent(true);
  3. $order->save();
* This source code was highlighted with Source Code Highlighter.

6. Если разрабатываемый платежный метод может быть использован из админки(оформление заказа по телефону/факсу/email), то следует добавить в модель платежного метода строку:
  1. protected $_canUseInternal         = true;
  2. // И возможно эту, если платежный модуль должен использоваться только из админки:
  3. protected $_canUseCheckout         = true;
* This source code was highlighted with Source Code Highlighter.