#php #paypal #payment #verification #vbulletin
#php #paypal #оплата #проверка #vbulletin
Вопрос:
Я пытаюсь обновить старый платежный скрипт из продукта vBulletin. Мне удалось заставить все работать до оплаты. Я могу завершить покупку, но когда я нажимаю кнопку "Return to merchant"
PayPal, она не выполняет проверку покупки. Покупка сохраняется в моей базе данных под "ma_purchases"
таблицей, но другая информация должна быть вставлена в другие таблицы после проверки, и она не вставляется. Затем (если правильно прочитать этот скрипт), как только покупка будет подтверждена, она должна переключить группу пользователей пользователя и вставить детали покупки в другие места.
<?php
// ####################### SET PHP ENVIRONMENT ###########################
error_reporting(E_ALL amp; ~ E_NOTICE);
// #################### DEFINE IMPORTANT CONSTANTS #######################
define('THIS_SCRIPT', 'mem_payment');
define('CSRF_PROTECTION', false);
define('SKIP_SESSIONCREATE', 1);
// #################### PRE-CACHE TEMPLATES AND DATA ######################
// get special phrase groups
$phrasegroups = array('subscription');
// get special data templates from the datastore
$specialtemplates = array();
// pre-cache templates used by all actions
$globaltemplates = array();
// pre-cache templates used by specific actions
$actiontemplates = array();
// ######################### REQUIRE BACK-END ############################
define('VB_AREA', 'Subscriptions');
define('CWD', (($getcwd = getcwd()) ? $getcwd : '.'));
require_once (CWD . '/includes/init.php');
require_once (CWD . '/includes/class_vbma.php');
$vbma = new vbma($vbulletin, $vbphrase);
$vbulletin->input->clean_array_gpc('p', array(
'item_number' => TYPE_STR,
'business' => TYPE_STR,
'receiver_email' => TYPE_STR,
'tax' => TYPE_STR,
'txn_type' => TYPE_STR,
'payment_status' => TYPE_STR,
'mc_currency' => TYPE_STR,
'mc_gross' => TYPE_STR,
'txn_id' => TYPE_STR
));
$transaction_id = $vbulletin->GPC['txn_id'];
$id = $vbulletin->GPC['item_number'];
$mc_gross = doubleval($vbulletin->GPC['mc_gross']);
$tax = doubleval($vbulletin->GPC['tax']);
$query = 'cmd=_notify-validate';
foreach ($_POST as $key => $value)
{
$value = urlencode(stripslashes($value));
$query .= "amp;$key=$value";
}
$used_curl = false;
//If you are ever messing around with Paypal it's a good idea to use the sandbox.
$usesandbox = false;
if ($usesandbox)
{
$script = 'www.sandbox.paypal.com';
}
else
{
$script = 'www.paypal.com';
}
if (function_exists('curl_init') and $ch = curl_init())
{
curl_setopt($ch, CURLOPT_URL, 'https://' . $script . '/cgi-bin/webscr');
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDSIZE, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'vBulletin via cURL/PHP');
$result = curl_exec($ch);
curl_close($ch);
if ($result !== false)
{
$used_curl = true;
}
}
if (!$used_curl)
{
$header = "POST /cgi-bin/webscr HTTP/1.0rn";
$header .= "Host: " . $script . "rn";
$header .= "Content-Type: application/x-www-form-urlencodedrn";
$header .= "Content-Length: " . strlen($query) . "rnrn";
if ($fp = fsockopen($script, 80, $errno, $errstr, 15))
{
socket_set_timeout($fp, 15);
fwrite($fp, $header . $query);
while (!feof($fp))
{
$result = fgets($fp, 1024);
if (strcmp($result, 'VERIFIED') == 0)
{
break;
}
}
fclose($fp);
}
}
if ($result == 'VERIFIED')
{
$purchase = $vbulletin->db->query_first("SELECT * FROM " . TABLE_PREFIX .
"ma_purchases WHERE id = '" . $id . "'");
$order = unserialize($purchase['order']);
if ($order[0] !== $vbulletin->GPC['business'])
{
$status_code = '503 Service Unavailable';
// Paypal likes to get told its message has been received
if (SAPI_NAME == 'cgi' or SAPI_NAME == 'cgi-fcgi')
{
header('Status: ' . $status_code);
}
else
{
header('HTTP/1.1 ' . $status_code);
}
}
unset($order[0]);
if ($purchase and !in_array($order[1], array('renew', 'upgrade')))
{
$product = $vbulletin->db->query_read("SELECT pur_group FROM " . TABLE_PREFIX .
"ma_products WHERE id = '" . $order[1] . "'");
$userinfo = fetch_userinfo($purchase['userid']);
$vbma->setCustomerNumber(unserialize($purchase['info']), $product['pur_group'], false,
$userinfo);
$rand = rand($vbulletin->options['memarea_numstart'], $vbulletin->options['memarea_numend']);
$licnum = substr(md5($prodid . rand(0, 20000) . $rand . $rand), 0, rand(10, $vbulletin->
options['memarea_custnumleng']));
$licensedm = datamanager_init('License', $vbulletin, ERRTYPE_ARRAY);
$licensedm->setr('userid', $userinfo['userid']);
$licensedm->setr('productid', $order[1]);
$licensedm->setr('licensenum', $licnum);
$licensedm->set('dateline', TIMENOW);
$licensedm->set('status', 2);
$licensedm->pre_save();
if (!empty($licensedm->errors))
{
var_dump($licensedm->errors);
}
else
{
$licensedm->save();
}
} elseif ($purchase and $order[1] == 'renew')
{
$licenseinfo = $vbma->getLicense($order[2], false, false, '', false, false);
$licensedm = datamanager_init('License', $vbulletin, ERRTYPE_ARRAY);
$licensedm->set_existing($licenseinfo);
$licensedm->set('dateline', TIMENOW);
$licensedm->set('status', 2);
$licensedm->pre_save();
if (!empty($licensedm->errors))
{
var_dump($licensedm->errors);
}
else
{
$licensedm->save();
}
} elseif ($purchase and $order[1] == 'upgrade')
{
$licenseinfo = $vbma->getLicense($order[2], false, false, '', false, false);
$licensedm = datamanager_init('License', $vbulletin, ERRTYPE_ARRAY);
$licensedm->set_existing($licenseinfo);
$licensedm->set('upgrades', serialize($order[3]));
$licensedm->pre_save();
if (!empty($licensedm->errors))
{
var_dump($licensedm->errors);
}
else
{
$licensedm->save();
}
}
$vbma->sendOutNewSaleEmail();
$vbulletin->db->query_write("DELETE FROM " . TABLE_PREFIX .
"ma_purchases WHERE id = '" . $id . "'");
$status_code = '200 OK';
// Paypal likes to get told its message has been received
if (SAPI_NAME == 'cgi' or SAPI_NAME == 'cgi-fcgi')
{
header('Status: ' . $status_code);
}
else
{
header('HTTP/1.1 ' . $status_code);
}
exit;
}
$status_code = '503 Service Unavailable';
// Paypal likes to get told its message has been received
if (SAPI_NAME == 'cgi' or SAPI_NAME == 'cgi-fcgi')
{
header('Status: ' . $status_code);
}
else
{
header('HTTP/1.1 ' . $status_code);
}
?>
Возможно, мне нужно больше, чтобы помочь мне с этим, но я просто спрашиваю, видит ли кто-нибудь какие-либо конфликты с этим платежным скриптом, поскольку он был написан еще в 2008 году.
Ответ №1:
- Вам нужно использовать HTTP / 1.1
- URL-адрес для обратной отправки теперь https://ipnpb.paypal.com/cgi-bin/webscr , в основном ipnpb вместо www
- Ваш сервер / среда может не иметь последних корневых сертификатов для проверки хоста paypal.com и сформируйте безопасное соединение HTTPS SSL для обратной передачи, и поэтому не сможете инициировать соединение и получить «ПРОВЕРЕННЫЙ» ответ
- Ваш сервер / среда также должны поддерживать протокол TLS 1.2
Прекратите использовать IPN, как только у вас появится возможность, и обновитесь до чего-то, основанного на API-интерфейсах v2 / orders / checkout (настройка / захват транзакции) и потоке утверждения сервером, потому что здравомыслие.
Комментарии:
1. Я попытался заменить www. на ipnpb (на localhost) и все равно получил тот же результат, однако у меня есть сертификат в моем домене, поэтому я попробую на своем живом сайте и посмотрю, работает ли это.
2. Однако я обнаружил, что если сделать продукт бесплатным, он заполняет все необходимые записи в базе данных (хотя это выполняется через другой файл)
3. Только что попробовал на моем сервере, который является HTTPS, и снова прошел платеж, но в базе данных больше ничего не было опубликовано. Я глубже изучил код и обнаружил, что если продукт бесплатный, он обрабатывает информацию о лицензии, иначе он обрабатывает данные paypal, СТРОКА 164 — это то, где она начинается. pastebin.com/0Y9k9y6c Мне нужно копнуть немного глубже в этих файлах.