Приветствую.
По аналогии с модулем Liqpay написал свой модуль для связи с другим банком. Форма создается, на страницу оплаты направляет, только проблема в том что потом не происходит серверная обработка оплаты (Сервисная страница платежной системы), не приходят деньги человеку в личном кабинете. Я сервисную страницу не могу передавать в настройках самой формы (как это реализовано в Liqpay) а сразу передал банку куда обращаться в случаи оплаты. Перед этим был тестовый скрипт в корне сайта который успешно принимал данные от банка, но когда я переключил уже на сам модуль (на сервисную страницу платежной системы в настройках Rcl Commerce) то ничего не происходит.
1) Вопрос такой, при каком условии идет обращение к функции result() и success()? Банковская система отравляет данные как-бы методом POST но на самом деле данных в массиве POST нет, их приходиться читать через file_get_contents('php://input'), может проблема в этом? Если да
то я пробовал и такой вот код:
global $wp_filesystem; if (empty($wp_filesystem)) { require_once (ABSPATH . '/wp-admin/includes/file.php'); WP_Filesystem(); } $readPostData = $wp_filesystem->get_contents('php://input');
После этого даже попробовал только сохранять одну строчку в текстовый файл и все, больше никакого кода в функциях result() и в success() не было, но и это не сработало. Деньги человеку не приходят.
2) Я в модуль оплаты Liqpay для теста добавил логирование в функции result() и в success().
Код самой функции:
function log($message) { $wp_upload_dir = wp_get_upload_dir(); $log_path = $wp_upload_dir['basedir'] . '/wp_recall_liqpay.log'; if (is_array($message) || is_object($message)) { $message = print_r($message, true); } file_put_contents($log_path, sprintf('[%s] DEBUG: %s', date('Y-m-d H:i:s'), $message) . "n", FILE_APPEND); }
А в сами функции в начало добавил вызов
$this->log( "TEST" );
Но почему-то не происходит сохранение в текстовый файл, он даже не создался, хотя деньги при оплате приходят на счет пользователя, получается что функции вызываются. Ошибок на сервере нет. Не могу понять с чем это связано.
function pay_form($data){ global $rmag_options; $user_first_name = get_user_meta( $data->user_id, "first_name", true ); $user_last_name = get_user_meta( $data->user_id, "last_name", true ); $user_display_name = strlen($user_first_name) > 0 && strlen($user_last_name) > 0 ? $user_first_name." ".$user_last_name : ""; $lang = "UK"; $transaction_uuid = $rmag_options['pumb_mode'] ? $this->generate_uuid() : $data->pay_id; if(strlen($user_display_name) > 0) { $formDescription = "Пополнение личного счета пользователя - ".$user_display_name.". Номер заказа ".$data->pay_id; } else { $formDescription = "Пополнение личного счета пользователя. Номер заказа ".$data->pay_id; } $baggage_data = ($data->baggage_data)? $data->baggage_data: false; $orderData = [ 'baggage_data' => $baggage_data, 'pay_type' => $data->pay_type, 'user_id' => $data->user_id, 'order_id' => $data->pay_id ]; if(is_int($data->submit_value)) $orderData['separate_payment'] = $data->submit_value; $link = $this->api_request( '/frames/links/pga', [ 'external_id' => $transaction_uuid, 'options' => [ 'ttl' => 0, 'create_short_url' => true, 'backurl' => [ 'success' => get_permalink($rmag_options['page_success_pay']), 'error' => get_permalink($rmag_options['page_fail_pay']), 'cancel' => get_permalink($rmag_options['page_fail_pay']) ] ], 'lang' => $lang, 'amount' => bcmul( $data->pay_summ, 100 ), 'title' => get_bloginfo( 'name' ), 'description' => $formDescription, 'short_description' => base64_encode(json_encode($orderData)), 'merchant_config_id' => $rmag_options['pumb_merchant_config_id'], 'config_id' => $rmag_options['pumb_config_id'], 'params' => [ 'shop_url' => get_home_url() ] ], 'POST', true ); if (isset($link['url'])) { $fields = [ "id" => $link['id'], "signature" => $link['signature'] ]; $form = parent::form($fields,$data,$link['url']); return $form; } else { $this->log(__METHOD__, $link); } }
Callback url я не передаю через форму так как у банка не настроен так функционал как у Liqpay, но обращение на страничку точно идет, я связывался с банком и они сказали что получают ответ 200 от странички.
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ /** * Description of rcl_pumb_form * * @author Андрей Куценко */ if(class_exists('Rcl_Payment')){ add_action('init','rcl_add_pumb_payment'); function rcl_add_pumb_payment(){ $pm = new Rcl_Pumb_Payment(); $pm->register_payment('pumb'); } class Rcl_Pumb_Payment extends Rcl_Payment{ public $form_pay_id; public $token; 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'=>'signature', 'name'=>'Pumb', 'image'=>rcl_addon_url('assets/pumb.png',__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] = __('Pumb','rcl-pumb'); return $options; } function child_options($child){ global $rmag_options; $opt = new Rcl_Options(); $options = array( array( 'type' => 'text', 'slug' => 'pumb_config_id', 'title' => __( 'Config ID', 'rcl-pumb' ) ), array( 'type' => 'text', 'slug' => 'pumb_merchant_config_id', 'title' => __( 'Merchant Config ID', 'rcl-pumb' ) ), array( 'type' => 'text', 'slug' => 'pumb_login', 'title' => __( 'Login', 'rcl-pumb' ) ), array( 'type' => 'password', 'slug' => 'pumb_password', 'title' => __( 'Password', 'rcl-pumb' ) ), array( 'type' => 'select', 'slug' => 'pumb_mode', 'title' => __( 'Режим работы', 'rcl-pumb' ), 'values' => array( __( 'Рабочий', 'rcl-pumb' ), __( 'Тестовый', 'rcl-pumb' ) ) ) ); $child .= $opt->child( array( 'name'=>'connect_sale', 'value'=>$this->form_pay_id ), array( $opt->options_box( __('Настройки подключения Pumb','rcl-pumb'), $options) ) ); return $child; } function pay_form($data){ global $rmag_options; $user_first_name = get_user_meta( $data->user_id, "first_name", true ); $user_last_name = get_user_meta( $data->user_id, "last_name", true ); $user_display_name = strlen($user_first_name) > 0 && strlen($user_last_name) > 0 ? $user_first_name." ".$user_last_name : ""; $lang = "UK"; $transaction_uuid = $rmag_options['pumb_mode'] ? $this->generate_uuid() : $data->pay_id; if(strlen($user_display_name) > 0) { $formDescription = "Пополнение личного счета пользователя- ".$user_display_name.". Номер заказа ".$data->pay_id; } else { $formDescription = "Пополнение личного счета пользователя. Номер заказа ".$data->pay_id; } $baggage_data = ($data->baggage_data)? $data->baggage_data: false; $orderData = [ 'baggage_data' => $baggage_data, 'pay_type' => $data->pay_type, 'user_id' => $data->user_id, 'order_id' => $data->pay_id ]; if(is_int($data->submit_value)) $orderData['separate_payment'] = $data->submit_value; $link = $this->api_request( '/frames/links/pga', [ 'external_id' => $transaction_uuid, 'options' => [ 'ttl' => 0, 'create_short_url' => true, 'backurl' => [ 'success' => get_permalink($rmag_options['page_success_pay']), 'error' => get_permalink($rmag_options['page_fail_pay']), 'cancel' => get_permalink($rmag_options['page_fail_pay']) ] ], 'lang' => $lang, 'amount' => bcmul( $data->pay_summ, 100 ), 'title' => get_bloginfo( 'name' ), 'description' => $formDescription, 'short_description' => base64_encode(json_encode($orderData)), 'merchant_config_id' => $rmag_options['pumb_merchant_config_id'], 'config_id' => $rmag_options['pumb_config_id'], 'params' => [ 'shop_url' => get_home_url() ] ], 'POST', true ); if (isset($link['url'])) { $fields = [ "id" => $link['id'], "signature" => $link['signature'] ]; $form = parent::form($fields,$data,$link['url']); return $form; } else { $this->log(__METHOD__, $link); } } function result($data){ $this->log( "TESTING: ", "WORK" ); // global $wp_filesystem; // if (empty($wp_filesystem)) { // require_once (ABSPATH . '/wp-admin/includes/file.php'); // WP_Filesystem(); // } // // $readPostData = $wp_filesystem->get_contents('php://input'); // пробовал оба варианта обрабатывать запрос //$readPostData = file_get_contents('php://input'); // if(strlen($readPostData) > 0){ // $jsonData = json_decode($readPostData, TRUE); // // if (json_last_error() === JSON_ERROR_NONE) { // if(array_key_exists('status', $jsonData) and $jsonData['status'] == "PROCESSED") { // $odredInfo = json_decode(base64_decode($jsonData['short_description']), TRUE); // // $data->pay_summ = intval($jsonData['amount']) / 100; // $data->pay_id = $odredInfo['order_id']; // $data->user_id = $odredInfo['user_id']; // $data->pay_type = $odredInfo['pay_type']; // $data->baggage_data = $odredInfo['baggage_data']; // // if(isset($odredInfo['separate_payment'])){ // $data->separate_payment = $odredInfo['separate_payment']; // } // // if(!parent::get_pay($data)) parent::insert_pay($data); // // echo "OK".$data->pay_id."n"; exit(); // } // } // } } function success(){ $this->log( "TESTING: ", "WORK2" ); } private function api_request( $url, $data = [], $method = 'GET', $auth = false, $timeout = 3 ) { global $rmag_options; $pumbDebug = $rmag_options['pumb_mode']; $api_base_url = $pumbDebug ? 'https://innsmouth.payhub.com.ua' : 'https://rlyeh.payhub.com.ua'; $response = []; $headers = []; if ( $method == 'GET' && ! empty( $data ) ) { $url = $url . '/' . implode( '/', $data ); } $url = $api_base_url . $url; if ( $pumbDebug ) { $this->log( __METHOD__, $url ); } $ch = curl_init(); curl_setopt( $ch, CURLOPT_URL, $url ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $ch, CURLOPT_TIMEOUT, $timeout ); curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 0 ); if ( $method == 'POST' ) { curl_setopt( $ch, CURLOPT_POST, true ); curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $data ) ); $headers[] = 'Content-Type: application/json'; } if ( $auth ) { if ( ! $this->token ) { $token = $this->api_request( '/auth/token', [ 'login' => $rmag_options['pumb_login'], 'password' => $rmag_options['pumb_password'], 'client' => 'transacter' ], 'POST' ); if ( isset( $token['access_token'] ) ) { $headers[] = 'Authorization: Bearer ' . $token['access_token']; $this->token = $token['access_token']; } } else { $headers[] = 'Authorization: Bearer ' . $this->token; } } curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers ); if ( $pumbDebug ) { if ( $url == $api_base_url . '/auth/token' ) { $data['password'] = '***'; } $this->log( __METHOD__, $data ); } $response = curl_exec( $ch ); if ( $pumbDebug ) { $this->log( __METHOD__, $response ); } $ch_info = curl_getinfo( $ch ); curl_close( $ch ); if ( $response ) { $response = json_decode( $response, true ); $response = isset( $response['data'] ) ? $response['data'] : $response; } return $response; } private function log($event, $message) { $wp_upload_dir = wp_get_upload_dir(); $log_path = $wp_upload_dir['basedir'] . '/wp_recall_pumb.log'; if (is_array($message) || is_object($message)) { $message = print_r($message, true); } file_put_contents($log_path, sprintf('[%s] DEBUG: %s %s', date('Y-m-d H:i:s'), $event, $message) . "n", FILE_APPEND); } private function generate_uuid() { return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0x0fff ) | 0x4000, mt_rand( 0, 0x3fff ) | 0x8000, mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ) ); } } }
Андрей CS сказал(а)
Вы взяли какое то устаревшее дополнение за основу, оно точно не будет работать с последней версией плагина.
Скачайте последнюю версию подключения к Liqpay с этого сайта, возьмите его код за основу.
У меня и версия wprecall устаревшая также, устанавливал ее еще 3 года назад и после этого не обновлял так как вносил некоторые изменения небольшие + некоторых плагинов уже вообще нет на новой версии.
У меня ведь код Liqpay отрабатывает отлично, в нем все работает, я его брал за основу и просто вписал другое подключение, по этому должен и этот отрабатывать, только почему это не происходит я не могу понять.
Именно по этому прошу помочь именно с этой версией кода.
в параметре
'request'
укажите один из параметров запроса, который платежка посылает в момент оповещения, вы можете сами добавить гет-параметр к урлу оповещения на стороне платежной системы и указать его в 'request', по нему алгоритм узнает, что при оповещении должен отработать ваш класс
Андрей CS сказал(а)
в параметре
'request'
укажите один из параметров запроса, который платежка посылает в момент оповещения, вы можете сами добавить гет-параметр к урлу оповещения на стороне платежной системы и указать его в 'request', по нему алгоритм узнает, что при оповещении должен отработать ваш класс
Ви имеете ввиду вот здесь:
parent::add_payment($this->form_pay_id, array( 'class'=>get_class($this), <strong>'request'=>'signature',</strong> 'name'=>'Pumb', 'image'=>rcl_addon_url('assets/pumb.png',__FILE__) ));
Я не хотел создавать отдельно свой класс. Я хочу понять почему две функции вообще не запускаются. По какой логике к ним происходит переход и они выполняются? И почему даже в рабочем модуле Liqpay функции которые отрабатывают нормально не выполняется часть кода, а именно просто запись текста в лог файл.
Я не вижу ни ошибок в своем коде ни причин почему он не работает. Аналогичный код с Liqpay отрабатывает ведь.
Preci сказал(а)
У вас в request указано signature, это означает что когда придет оповещение от платежки, оно должно быть с быть GET (возможно и POST подойдет) параметром signature, что бы дальше передать обработку классу с вашим подключением
Сделал вот так:
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'=>'signature', 'name'=>'Pumb', 'image'=>rcl_addon_url('assets/pumb.png',__FILE__) )); if(is_admin()) $this->add_options(); }
Не помогло, что-то может еще делаю не так?
А как это поможет? Вы вообще убрали параметр request.
Страница на которую платежки шлют информацию и платеже одна, а подключений разных может быть множество. Что бы когда придет запрос от платежки можно было определить какое подключение должно его обрабатывать - нужен параметр request, он должен быть у каждого подключения уникальным.
Вам нужно в настройках платежки указать url куда будут приходить оповещения о платеже с параметром ?signature=1 например