moved website outside of panel folder
This commit is contained in:
parent
92ac778956
commit
08f07dca97
10328 changed files with 90 additions and 501 deletions
|
|
@ -1,312 +0,0 @@
|
|||
<?php
|
||||
require_once(__DIR__ . '/includes/config_loader.php');
|
||||
if (is_file(__DIR__ . '/includes/log.php')) require_once(__DIR__ . '/includes/log.php');
|
||||
|
||||
// Derive active credentials via helper functions (falls back to old globals gracefully)
|
||||
$_wh_sandbox = function_exists('gsp_paypal_is_sandbox') ? gsp_paypal_is_sandbox() : ($paypal_sandbox ?? true);
|
||||
$_wh_client_id = function_exists('gsp_paypal_get_client_id') ? gsp_paypal_get_client_id() : ($paypal_client_id ?? '');
|
||||
$_wh_client_secret = function_exists('gsp_paypal_get_client_secret') ? gsp_paypal_get_client_secret() : ($paypal_client_secret ?? '');
|
||||
$_wh_webhook_id = function_exists('gsp_paypal_get_webhook_id') ? gsp_paypal_get_webhook_id() : ($paypal_webhook_id ?? '');
|
||||
$_wh_api_base = function_exists('gsp_paypal_get_api_base') ? gsp_paypal_get_api_base() : ($_wh_sandbox ? 'https://api-m.sandbox.paypal.com' : 'https://api-m.paypal.com');
|
||||
|
||||
$config = [
|
||||
'sandbox' => $_wh_sandbox,
|
||||
'client_id' => $_wh_client_id,
|
||||
'client_secret' => $_wh_client_secret,
|
||||
'webhook_id' => $_wh_webhook_id,
|
||||
'data_dir' => rtrim(
|
||||
(defined('SITE_DATA_DIR') ? SITE_DATA_DIR : '') ?: ($SITE_DATA_DIR ?? ''),
|
||||
DIRECTORY_SEPARATOR
|
||||
),
|
||||
'log_file' => __DIR__ . '/data/webhook.log',
|
||||
];
|
||||
|
||||
if (!$config['data_dir']) {
|
||||
$config['data_dir'] = realpath(__DIR__ . '/') . DIRECTORY_SEPARATOR . 'data';
|
||||
}
|
||||
|
||||
function log_line($m){global $config; @file_put_contents($config['log_file'],'['.date('c')."] $m\n",FILE_APPEND);}
|
||||
function api_base(){global $_wh_api_base; return $_wh_api_base;}
|
||||
|
||||
http_response_code(200);
|
||||
@mkdir($config['data_dir'], 0775, true);
|
||||
|
||||
$raw = file_get_contents('php://input');
|
||||
$headers = array_change_key_case(getallheaders() ?: [], CASE_UPPER);
|
||||
if (function_exists('site_log_info')) site_log_info('webhook_hit', ['ip'=>($_SERVER['REMOTE_ADDR']??''),'bytes'=>strlen($raw)]);
|
||||
else log_line("HIT ip=".($_SERVER['REMOTE_ADDR']??'') ." bytes=".strlen($raw));
|
||||
if (!$raw) { log_line("NO_BODY"); exit; }
|
||||
|
||||
// 1) OAuth2
|
||||
$ch = curl_init(api_base().'/v1/oauth2/token');
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER=>true,
|
||||
CURLOPT_POST=>true,
|
||||
CURLOPT_POSTFIELDS=>'grant_type=client_credentials',
|
||||
CURLOPT_HTTPHEADER=>['Accept: application/json'],
|
||||
CURLOPT_USERPWD=>$config['client_id'].':'.$config['client_secret'],
|
||||
]);
|
||||
$tokenResp = curl_exec($ch);
|
||||
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
$o = ['http'=>$http,'resp'=>substr($tokenResp,0,400)];
|
||||
if ($http!==200){ if (function_exists('site_log_warn')) site_log_warn('oauth_fail',$o); else log_line("OAUTH_FAIL http=$http resp=$tokenResp"); exit; }
|
||||
$access_token = json_decode($tokenResp, true)['access_token'] ?? null;
|
||||
if (!$access_token){ if (function_exists('site_log_warn')) site_log_warn('oauth_no_token', []); else log_line("OAUTH_NO_TOKEN"); exit; }
|
||||
|
||||
// 2) Verify webhook signature
|
||||
$verifyPayload = [
|
||||
'transmission_id' => $headers['PAYPAL-TRANSMISSION-ID'] ?? '',
|
||||
'transmission_time' => $headers['PAYPAL-TRANSMISSION-TIME'] ?? '',
|
||||
'cert_url' => $headers['PAYPAL-CERT-URL'] ?? '',
|
||||
'auth_algo' => $headers['PAYPAL-AUTH-ALGO'] ?? '',
|
||||
'transmission_sig' => $headers['PAYPAL-TRANSMISSION-SIG'] ?? '',
|
||||
'webhook_id' => $config['webhook_id'],
|
||||
'webhook_event' => json_decode($raw, true),
|
||||
];
|
||||
$ch = curl_init(api_base().'/v1/notifications/verify-webhook-signature');
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER=>true,
|
||||
CURLOPT_POST=>true,
|
||||
CURLOPT_POSTFIELDS=>json_encode($verifyPayload),
|
||||
CURLOPT_HTTPHEADER=>[
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Bearer '.$access_token
|
||||
],
|
||||
]);
|
||||
$verifyResp = curl_exec($ch);
|
||||
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
$verifyJson = json_decode($verifyResp, true);
|
||||
if ($http!==200 || ($verifyJson['verification_status'] ?? '') !== 'SUCCESS'){
|
||||
if (function_exists('site_log_warn')) site_log_warn('verify_fail', ['http'=>$http,'status'=>($verifyJson['verification_status']??'NONE')]);
|
||||
else log_line("VERIFY_FAIL http=$http status=".($verifyJson['verification_status']??'NONE'));
|
||||
exit;
|
||||
}
|
||||
if (function_exists('site_log_info')) site_log_info('verify_ok', ['http'=>$http]);
|
||||
else log_line("VERIFY_OK");
|
||||
|
||||
// 3) Parse and persist
|
||||
$evt = json_decode($raw, true);
|
||||
$type = $evt['event_type'] ?? '';
|
||||
$res = $evt['resource'] ?? [];
|
||||
|
||||
$invoice = $res['invoice_id'] ?? ($res['invoice_number'] ?? null);
|
||||
$custom = $res['custom_id'] ?? ($res['custom'] ?? null);
|
||||
|
||||
$amount = $res['amount']['value'] ?? ($res['amount']['total'] ?? null);
|
||||
$currency = $res['amount']['currency_code'] ?? ($res['amount']['currency'] ?? null);
|
||||
$payer = $res['payer']['email_address'] ?? ($res['payer']['payer_info']['email'] ?? null);
|
||||
|
||||
$items = [];
|
||||
if (isset($res['purchase_units'][0]['items']) && is_array($res['purchase_units'][0]['items'])) {
|
||||
$items = $res['purchase_units'][0]['items'];
|
||||
}
|
||||
|
||||
if (!$items && $type === 'PAYMENT.CAPTURE.COMPLETED') {
|
||||
$orderId = $res['supplementary_data']['related_ids']['order_id'] ?? null;
|
||||
if (!$orderId && isset($res['links']) && is_array($res['links'])) {
|
||||
foreach ((array)$res['links'] as $lnk) {
|
||||
if (!empty($lnk['href']) && !empty($lnk['rel']) && stripos($lnk['href'], '/v2/checkout/orders/') !== false) {
|
||||
$orderId = basename(parse_url($lnk['href'], PHP_URL_PATH));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($orderId) {
|
||||
$ch = curl_init(api_base()."/v2/checkout/orders/".urlencode($orderId));
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_HTTPHEADER => [ 'Authorization: Bearer '.$access_token, 'Content-Type: application/json' ],
|
||||
]);
|
||||
$orderJson = curl_exec($ch);
|
||||
$httpOrder = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
if ($httpOrder === 200) {
|
||||
$order = json_decode($orderJson, true);
|
||||
if (isset($order['purchase_units'][0]['items']) && is_array($order['purchase_units'][0]['items'])) {
|
||||
$items = $order['purchase_units'][0]['items'];
|
||||
}
|
||||
if (!$invoice) { $invoice = $order['purchase_units'][0]['invoice_id'] ?? $invoice; }
|
||||
if (!$custom) { $custom = $order['purchase_units'][0]['custom_id'] ?? $custom; }
|
||||
} else {
|
||||
if (function_exists('site_log_warn')) site_log_warn('order_fetch_fail', ['orderId'=>$orderId,'http'=>$httpOrder]);
|
||||
else log_line("ORDER_FETCH_FAIL id=$orderId http=$httpOrder");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$status = 'IGNORED';
|
||||
if (in_array($type, ['PAYMENT.CAPTURE.COMPLETED','PAYMENT.SALE.COMPLETED'], true)) {
|
||||
$record = [
|
||||
'event_type' => $type,
|
||||
'status' => 'PAID',
|
||||
'amount' => $amount,
|
||||
'currency' => $currency,
|
||||
'payer' => $payer,
|
||||
'invoice' => $invoice,
|
||||
'custom' => $custom,
|
||||
'resource_id' => $res['id'] ?? null,
|
||||
'items' => $items,
|
||||
'ts' => date('c'),
|
||||
];
|
||||
$name = $invoice ?: 'NO-INVOICE-'.bin2hex(random_bytes(4));
|
||||
@file_put_contents($config['data_dir']."/".$name.".json", json_encode($record, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
|
||||
$status = 'WROTE_FILE';
|
||||
|
||||
// Attempt to mark order paid in DB
|
||||
require_once(__DIR__ . '/includes/payment_processor.php');
|
||||
try {
|
||||
process_payment_record($record);
|
||||
} catch (Exception $e) {
|
||||
if (function_exists('site_log_error')) site_log_error('process_payment_fail',['err'=>$e->getMessage()]);
|
||||
else log_line('PROC_FAIL '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (function_exists('site_log_info')) site_log_info('webhook_event',['type'=>$type,'invoice'=>($invoice ?: 'none'),'items_count'=>count((array)$items),'status'=>$status]);
|
||||
else log_line("EVENT $type invoice=".($invoice ?: 'none')." items_count=".count((array)$items)." status=$status");
|
||||
|
||||
?>
|
||||
|
||||
|
||||
http_response_code(200);
|
||||
@mkdir($config['data_dir'], 0775, true);
|
||||
|
||||
$raw = file_get_contents('php://input');
|
||||
$headers = array_change_key_case(getallheaders() ?: [], CASE_UPPER);
|
||||
if (function_exists('site_log_info')) site_log_info('webhook_hit', ['ip'=>($_SERVER['REMOTE_ADDR']??''),'bytes'=>strlen($raw)]);
|
||||
else log_line("HIT ip=".($_SERVER['REMOTE_ADDR']??'') ." bytes=".strlen($raw));
|
||||
if (!$raw) { log_line("NO_BODY"); exit; }
|
||||
|
||||
// 1) OAuth2
|
||||
$ch = curl_init(api_base().'/v1/oauth2/token');
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER=>true,
|
||||
CURLOPT_POST=>true,
|
||||
CURLOPT_POSTFIELDS=>'grant_type=client_credentials',
|
||||
CURLOPT_HTTPHEADER=>['Accept: application/json'],
|
||||
CURLOPT_USERPWD=>$config['client_id'].':'.$config['client_secret'],
|
||||
]);
|
||||
$tokenResp = curl_exec($ch);
|
||||
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
$o = ['http'=>$http,'resp'=>substr($tokenResp,0,400)];
|
||||
if ($http!==200){ if (function_exists('site_log_warn')) site_log_warn('oauth_fail',$o); else log_line("OAUTH_FAIL http=$http resp=$tokenResp"); exit; }
|
||||
$access_token = json_decode($tokenResp, true)['access_token'] ?? null;
|
||||
if (!$access_token){ if (function_exists('site_log_warn')) site_log_warn('oauth_no_token', []); else log_line("OAUTH_NO_TOKEN"); exit; }
|
||||
|
||||
// 2) Verify webhook signature
|
||||
$verifyPayload = [
|
||||
'transmission_id' => $headers['PAYPAL-TRANSMISSION-ID'] ?? '',
|
||||
'transmission_time' => $headers['PAYPAL-TRANSMISSION-TIME'] ?? '',
|
||||
'cert_url' => $headers['PAYPAL-CERT-URL'] ?? '',
|
||||
'auth_algo' => $headers['PAYPAL-AUTH-ALGO'] ?? '',
|
||||
'transmission_sig' => $headers['PAYPAL-TRANSMISSION-SIG'] ?? '',
|
||||
'webhook_id' => $config['webhook_id'],
|
||||
'webhook_event' => json_decode($raw, true),
|
||||
];
|
||||
$ch = curl_init(api_base().'/v1/notifications/verify-webhook-signature');
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER=>true,
|
||||
CURLOPT_POST=>true,
|
||||
CURLOPT_POSTFIELDS=>json_encode($verifyPayload),
|
||||
CURLOPT_HTTPHEADER=>[
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Bearer '.$access_token
|
||||
],
|
||||
]);
|
||||
$verifyResp = curl_exec($ch);
|
||||
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
$verifyJson = json_decode($verifyResp, true);
|
||||
if ($http!==200 || ($verifyJson['verification_status'] ?? '') !== 'SUCCESS'){
|
||||
if (function_exists('site_log_warn')) site_log_warn('verify_fail', ['http'=>$http,'status'=>($verifyJson['verification_status']??'NONE')]);
|
||||
else log_line("VERIFY_FAIL http=$http status=".($verifyJson['verification_status']??'NONE'));
|
||||
exit;
|
||||
}
|
||||
if (function_exists('site_log_info')) site_log_info('verify_ok', ['http'=>$http]);
|
||||
else log_line("VERIFY_OK");
|
||||
|
||||
// 3) Parse and persist
|
||||
$evt = json_decode($raw, true);
|
||||
$type = $evt['event_type'] ?? '';
|
||||
$res = $evt['resource'] ?? [];
|
||||
|
||||
$invoice = $res['invoice_id'] ?? ($res['invoice_number'] ?? null);
|
||||
$custom = $res['custom_id'] ?? ($res['custom'] ?? null);
|
||||
|
||||
$amount = $res['amount']['value'] ?? ($res['amount']['total'] ?? null);
|
||||
$currency = $res['amount']['currency_code'] ?? ($res['amount']['currency'] ?? null);
|
||||
$payer = $res['payer']['email_address'] ?? ($res['payer']['payer_info']['email'] ?? null);
|
||||
|
||||
$items = [];
|
||||
if (isset($res['purchase_units'][0]['items']) && is_array($res['purchase_units'][0]['items'])) {
|
||||
$items = $res['purchase_units'][0]['items'];
|
||||
}
|
||||
|
||||
if (!$items && $type === 'PAYMENT.CAPTURE.COMPLETED') {
|
||||
$orderId = $res['supplementary_data']['related_ids']['order_id'] ?? null;
|
||||
if (!$orderId && isset($res['links']) && is_array($res['links'])) {
|
||||
foreach ((array)$res['links'] as $lnk) {
|
||||
if (!empty($lnk['href']) && !empty($lnk['rel']) && stripos($lnk['href'], '/v2/checkout/orders/') !== false) {
|
||||
$orderId = basename(parse_url($lnk['href'], PHP_URL_PATH));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($orderId) {
|
||||
$ch = curl_init(api_base()."/v2/checkout/orders/".urlencode($orderId));
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_HTTPHEADER => [ 'Authorization: Bearer '.$access_token, 'Content-Type: application/json' ],
|
||||
]);
|
||||
$orderJson = curl_exec($ch);
|
||||
$httpOrder = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
if ($httpOrder === 200) {
|
||||
$order = json_decode($orderJson, true);
|
||||
if (isset($order['purchase_units'][0]['items']) && is_array($order['purchase_units'][0]['items'])) {
|
||||
$items = $order['purchase_units'][0]['items'];
|
||||
}
|
||||
if (!$invoice) { $invoice = $order['purchase_units'][0]['invoice_id'] ?? $invoice; }
|
||||
if (!$custom) { $custom = $order['purchase_units'][0]['custom_id'] ?? $custom; }
|
||||
} else {
|
||||
if (function_exists('site_log_warn')) site_log_warn('order_fetch_fail', ['orderId'=>$orderId,'http'=>$httpOrder]);
|
||||
else log_line("ORDER_FETCH_FAIL id=$orderId http=$httpOrder");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$status = 'IGNORED';
|
||||
if (in_array($type, ['PAYMENT.CAPTURE.COMPLETED','PAYMENT.SALE.COMPLETED'], true)) {
|
||||
$record = [
|
||||
'event_type' => $type,
|
||||
'status' => 'PAID',
|
||||
'amount' => $amount,
|
||||
'currency' => $currency,
|
||||
'payer' => $payer,
|
||||
'invoice' => $invoice,
|
||||
'custom' => $custom,
|
||||
'resource_id' => $res['id'] ?? null,
|
||||
'items' => $items,
|
||||
'ts' => date('c'),
|
||||
];
|
||||
$name = $invoice ?: 'NO-INVOICE-'.bin2hex(random_bytes(4));
|
||||
@file_put_contents($config['data_dir']."/".$name.".json", json_encode($record, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
|
||||
$status = 'WROTE_FILE';
|
||||
|
||||
// Attempt to mark order paid in DB
|
||||
require_once(__DIR__ . '/includes/payment_processor.php');
|
||||
try {
|
||||
process_payment_record($record);
|
||||
} catch (Exception $e) {
|
||||
if (function_exists('site_log_error')) site_log_error('process_payment_fail',['err'=>$e->getMessage()]);
|
||||
else log_line('PROC_FAIL '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (function_exists('site_log_info')) site_log_info('webhook_event',['type'=>$type,'invoice'=>($invoice ?: 'none'),'items_count'=>count((array)$items),'status'=>$status]);
|
||||
else log_line("EVENT $type invoice=".($invoice ?: 'none')." items_count=".count((array)$items)." status=$status");
|
||||
|
||||
?>
|
||||
Loading…
Add table
Add a link
Reference in a new issue