Приветствую.
По аналогии с модулем 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 например