Публикация в группе: Плагин WP-Recall - Личный кабинет на WordPress

Категории группы: Полезное

Внимание! Данная инструкция устарела и представляет только исторический интерес. Актуальный алгоритм реализации подключения к платежной системе на базе плагина WP-Recall описан в этой статье.

----------------------------

Начиная с версии 13.5.5 плагина Wp-Recall стало возможным расширять список доступных подключений к платежным системам путем подключения своего кода к основному классу плагина Rcl_Payment. В этой статье рассмотрим общий принцип подключения плагина Wp-Recall к какой то произвольной платежной системе.

Плагин Wp-Recall использует выбранное подключение к платежной системе для пополнения личного счета пользователей и оплаты заказов, сформированных через дополнение Recall Commerce.

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

class Rcl_Custom_Payment extends Rcl_Payment{
	
	//идентификатор платежной системы
    public $form_pay_id;
	
	//регистрация подключения
    function register_payment($form_pay_id){
        
    }
	//добавление опций подключения в общие настройки плагина
    function add_options(){
       
    }
	//добавляем название настроек
    function options($options){

    }
	//добавляем настройки нового подключения
    function child_options($child){

    }
	//данные формы платежа
    function pay_form($data){

    }
	//обработка запроса RESULT
    function result($data){

    }
	//обработка запроса SUCCEESS
    function success(){

    }

}

Формирование платежа внутри приведенного выше класса можно условно разделить на четыре этапа:

  • регистрация подключения
  • добавление настроек подключения
  • построение формы платежа
  • обработка ответа

Пойдем по порядку и рассмотрим каждый этап формирования платежа внутри дочернего класса.

Регистрация подключения

Для регистрации нового подключения к платежной системе необходимо использовать метод register_payment(), который необходимо вызвать за пределами нашего класса при срабатывании хука init.

Внутрь метода мы передаем идентификатор нашего нового подключения, в нашем случае, это 'custom'. В содержимом метода register_payment обязательно необходимо указать параметр 'request' для которого необходимо назначить некий GET или POST-параметр, в нашем случае 'get_param', который платежная система согласно ее API обязательно будет передавать на наш сервер при проведении платежа. По этому параметру наш алгоритм будет узнавать, что необходимо запускать инициализацию платежа именно от этой платежной системы, а не от какой то другой. Т.е. мы сообщаем алгоритму подключения, что когда на наш сервер поступит запрос $_REQUEST['get_param'], то пусть начинает работать с нашим классом Rcl_Custom_Payment.

add_action('init','rcl_add_custom_payment');
function rcl_add_custom_payment(){
    $pm = new Rcl_Custom_Payment();
    $pm->register_payment('custom');
}

class Rcl_Custom_Payment extends Rcl_Payment{
	
    //идентификатор платежной системы
    public $form_pay_id;
	
    //регистрация подключения
    function register_payment($form_pay_id){
        $this->form_pay_id = $form_pay_id;
        parent::add_payment($this->form_pay_id, array(
           'class'=>get_class($this),
           'request'=>'get_param',
           'name'=>'My Custom Gateway',
           'image'=>rcl_addon_url('assets/icon.jpg',__FILE__)
        ));
        if(is_admin()) $this->add_options();
    }
}

Добавление настроек подключения

После регистрации платежной системы, наступает через добавления настроек необходимых для подключения нашей платежной системы. Фактически, настройки подключения - это некие данные, используемые сервером и самой платежной системой для организации взаимодействия. Это могут быть логины, какие-то идентификаторы, различные ключи и тп. Вы должны сами определить, какие именно настройки потребуются при подключении и вывести их для заполнения. Допустим для организации нашего подключения потребуется логин пользователя в платежной системе и некий секретный ключ, добавим наши настройки прописав необходимые данные в методах нашего класса:

function add_options(){
	add_filter('rcl_pay_option',(array($this,'options')));
	add_filter('rcl_pay_child_option',(array($this,'child_options')));
}

function options($options){
	$options[$this->form_pay_id] = __('My Custom Payment','rcl');
	return $options;
}

function child_options($child){

	$opt = new Rcl_Options();

	$child .= $opt->child(
		array(
			'name'=>'connect_sale',
			'value'=>$this->form_pay_id
		),
		array(
			$opt->title(__('Настройки подключения "Custom Payment"','rcl')),
			$opt->label(__('Логин аккаунта','rcl')),
			$opt->option('text',array('name'=>'custom_login')),
			$opt->label(__('Секретный ключ','rcl')),
			$opt->option('password',array('name'=>'custom_key'))			
		)
	);

	return $child;
}

Основная работа производится внутри метода child_options(), именно там прописываются те настройки, которые и будем использовать при отправке запросов на сервер платежной системы и обработки запросов принятых от этого сервиса. Правила формирования настроек подключения подробно описаны в этой статье.

Формирование запроса платежа

На данном этапе, необходимо используя полученную информацию из описания API нашей платежной системы и имеющихся  данных сформировать платежную форму, которая и будет отправлять данные платежа в платежную систему. Построение формы платежа производится внутри метода pay_form(). Данный метод принимает объект текущего платежа и отправляет их для построения платежной формы в метод form() родительского класса Rcl_Payment, где и происходит непосредственная генерация HTML-кода платежной формы.

Объект $data содержит четыре основных параметра платежа:

  • pay_id - внутренний идентификатор платежа
  • user_id - идентификатор пользователя
  • pay_summ - сумма платежа
  • pay_type - тип платежа (1-пополнение счета, 2-оплата заказа)

Рассмотрим пример формирования данных платежной формы внутри метода pay_form()

function pay_form($data){
	global $rmag_options;
	
	//получаем данные из настроек подключения
	$login = $rmag_options['custom_login'];
	//формируем описание платежа по его типу
	$desc = ($data->pay_type==1)? 'Пополнение личного счета': 'Оплата заказа';
	
	//формируем массив данных полей формы платежа, 
	//где ключами массива являются имена параметров отправляемых 
	//в платежную систему, а значениями - отправляемые данные
	$fields = array(
		'FORM_FIELD_1'=>$login,
		'FORM_FIELD_2'=>$data->pay_summ,
		'FORM_FIELD_3'=>$data->pay_id,
		'FORM_FIELD_4'=>$desc,
		'FORM_FIELD_5'=>$data->user_id,
		'FORM_FIELD_6'=>$data->pay_type
	);
	
	//Третьим параметром указываем куда именно будут отправляться данные платежа
	$form = parent::form($fields,$data,"https://merchant.webmoney.ru/lmi/payment.asp");

	return $form;
}

В результате работы данного метода будет сформирована платежная форма, которая и отправит данные платежа в нашу платежную систему, где они будут обработаны согласно API платежной системы.

Обработка ответа

Если присланные данные были сформированы верно и платежная системы их успешно обработала, то, как правило, на наш сервер присылается ответ, благодаря которому мы узнаем о статусе платежа и производим какие-то действия.

Ответ от платежной системы содержит набор неких данных, которые мы должны получить и обработать.

Обработка ответа от платежной системы производится методом result() и методом success(). Данные методы срабатывают когда платежная система обращается к страницам нашего сайта созданным для этих целей. Для срабатывания этих методов страницы RESULT и SUCCESS должны быть созданы на сайте, указаны в настройках подключения плагина Wp-Recall и указаны в технических настройках самой платежной системы.

Как правило, основная работа по проверке данных присланных от платежной системы и пополнение личного счета или оплата сформированного заказа пользователя производится в методе result(). Содержимое этого метода зависит от API платежной системы и логики обработки данных полученных от нее. Обычно внутри этого метода:

  1. Принимаются данные от платежной системы о статусе платежа
  2. формируется проверочных хеш и сравнивается с присланным от самой платежной системы
  3. если хеш совпадает, то платеж проводится на самом сайте
  4. если хеш не совпадает или статус платежа не соответствует требуемому, то платежной системе отправляется сообщение об соответствующей ошибке

Примерный алгоритм работы алгоритма result():

function result($data){
	global $rmag_options;
	
	//получаем необходимые данные от платежной системы
	$data->pay_summ = $_REQUEST['FORM_FIELD_2'];
	$data->pay_id = $_REQUEST['FORM_FIELD_3'];
	$data->user_id = $_REQUEST['FORM_FIELD_5'];
	$data->pay_type = $_REQUEST['FORM_FIELD_6'];
	
	//формируем хеш, согласно алгоритма платежной системы
	$sign = strtoupper(hash( 'sha256',
			  $_REQUEST['FORM_FIELD_1']
			. $_REQUEST['FORM_FIELD_2']
			. $_REQUEST['FORM_FIELD_3']
			. $_REQUEST['FORM_FIELD_4']
			. $_REQUEST['FORM_FIELD_5']
			));
	
	//сверяем полученный хеш и присланный
	if($sign!=$_REQUEST['HASH']){
		//если хеш не совпадает, то отправляем письмо об ошибке
		//и прекращаем работу скрипта
		rcl_mail_payment_error($sign);
		exit;
	}
	
	//Проверяем наличие платежа
	//и если его нет, то произвоидим платеж
	if(!parent::get_pay($data)){
		parent::insert_pay($data);
	}
}

Метод success() срабатывает при обращении платежной системы к странице созданной для SUCCESS. Как правило, платежная система тоже присылает данные платежа. Мы можем проверить эти данные и перенаправить пользователя на страницу с текстом об успешной оплате.

Например:

function success(){
	global $rmag_options;
	//получаем ИД платежа и ИД пользователя в массив
	$data = array(
		'pay_id' => $_REQUEST['FORM_FIELD_3'],
		'user_id' => $_REQUEST['FORM_FIELD_5']
	);
	//Передаем полученный массив в родительский класс на проверку
	if(parent::get_pay((object)$data)){
		//Если платеж присутствует, то перенаправляем пользователя
		//на страницу с текстом об удачной оплате
		wp_redirect(get_permalink($rmag_options['page_successfully_pay'])); exit;
	} else {
		wp_die('Платеж не найден в базе данных!');
	}

}

 

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

Итог

Итак, полный код нашего подключения выглядит так:

add_action('init','rcl_add_custom_payment');
function rcl_add_custom_payment(){
    $pm = new Rcl_Custom_Payment();
    $pm->register_payment('custom');
}

class Rcl_Custom_Payment extends Rcl_Payment{

    public $form_pay_id;

    function register_payment($form_pay_id){
        $this->form_pay_id = $form_pay_id;
        parent::add_payment($this->form_pay_id, array(
           'class'=>get_class($this),
           'request'=>'get_param',
           'name'=>'My Custom Gateway',
           'image'=>rcl_addon_url('assets/icon.jpg',__FILE__)
        ));
        if(is_admin()) $this->add_options();
    }

	function add_options(){
		add_filter('rcl_pay_option',(array($this,'options')));
		add_filter('rcl_pay_child_option',(array($this,'child_options')));
	}

	function options($options){
		$options[$this->form_pay_id] = __('My Custom Payment','rcl');
		return $options;
	}

	function child_options($child){

		$opt = new Rcl_Options();

		$child .= $opt->child(
			array(
				'name'=>'connect_sale',
				'value'=>$this->form_pay_id
			),
			array(
				$opt->title(__('Настройки подключения "Custom Payment"','rcl')),
				$opt->label(__('Логин аккаунта','rcl')),
				$opt->option('text',array('name'=>'custom_login')),
				$opt->label(__('Секретный ключ','rcl')),
				$opt->option('password',array('name'=>'custom_key'))			
			)
		);

		return $child;
	}

	function pay_form($data){
		global $rmag_options;
		
		//получаем данные из настроек подключения
		$login = $rmag_options['custom_login'];
		//формируем описание платежа по его типу
		$desc = ($data->pay_type==1)? 'Пополнение личного счета': 'Оплата заказа';
		
		//формируем массив данных полей формы платежа, 
		//где ключами массива являются имена параметров отправляемых 
		//в платежную систему, а значениями - отправляемые данные
		$fields = array(
			'FORM_FIELD_1'=>$login,
			'FORM_FIELD_2'=>$data->pay_summ,
			'FORM_FIELD_3'=>$data->pay_id,
			'FORM_FIELD_4'=>$desc,
			'FORM_FIELD_5'=>$data->user_id,
			'FORM_FIELD_6'=>$data->pay_type
		);
		
		//Третьим параметром указываем куда именно будут отправляться данные платежа
		$form = parent::form($fields,$data,"https://merchant.webmoney.ru/lmi/payment.asp");

		return $form;
	}

	function result($data){
		global $rmag_options;
		
		//получаем необходимые данные от платежной системы
		$data->pay_summ = $_REQUEST['FORM_FIELD_2'];
		$data->pay_id = $_REQUEST['FORM_FIELD_3'];
		$data->user_id = $_REQUEST['FORM_FIELD_5'];
		$data->pay_type = $_REQUEST['FORM_FIELD_6'];
		
		//формируем хеш, согласно алгоритма платежной системы
		$sign = strtoupper(hash( 'sha256',
				  $_REQUEST['FORM_FIELD_1']
				. $_REQUEST['FORM_FIELD_2']
				. $_REQUEST['FORM_FIELD_3']
				. $_REQUEST['FORM_FIELD_4']
				. $_REQUEST['FORM_FIELD_5']
				));
		
		//сверяем полученный хеш и присланный
		if($sign!=$_REQUEST['HASH']){
			//если хеш не совпадает, то отправляем письмо об ошибке
			//и прекращаем работу скрипта
			rcl_mail_payment_error($sign);
			exit;
		}
		
		//Проверяем наличие платежа
		//и если его нет, то произвоидим платеж
		if(!parent::get_pay($data)){
			parent::insert_pay($data);
		}
	}

	function success(){
		global $rmag_options;
		//получаем ИД платежа и ИД пользователя в массив
		$data = array(
			'pay_id' => $_REQUEST['FORM_FIELD_3'],
			'user_id' => $_REQUEST['FORM_FIELD_5']
		);
		//Передаем полученный массив в родительский класс на проверку
		if(parent::get_pay((object)$data)){
			//Если платеж присутствует, то перенаправляем пользователя
			//на страницу с текстом об удачной оплате
			wp_redirect(get_permalink($rmag_options['page_successfully_pay'])); exit;
		} else {
			wp_die('Платеж не найден в базе данных!');
		}

	}
}

Таким образом, для настройки подключения новой платежной системы или агрегатора к плагину Wp-Recall потребуется создать только один класс с несколькими методами и настроить взаимодействие согласно API платежной системы. Точно по такому принципу работают все существующие подключения платежных систем в плагине.

2

Автор публикации

не в сети 8 часов

Андрей CS

12K
рассматриваю задания
Комментарии: 2744Публикации: 481Регистрация: 30-11--0001Продаж/Покупок: 0/0