Panel/Panel/modules/website/api/capture_order.php

80 lines
2.8 KiB
PHP

<?php
declare(strict_types=1);
require_once dirname(__DIR__) . '/includes/bootstrap.php';
header('Content-Type: application/json');
$user = website_current_user();
if (!$user) {
http_response_code(401);
echo json_encode(['error' => 'login_required']);
exit;
}
$input = json_decode((string)file_get_contents('php://input'), true);
$invoiceId = (int)($input['invoice_id'] ?? 0);
$paypalOrderId = trim((string)($input['order_id'] ?? ''));
$config = website_paypal_config();
$db = website_db();
if (!$config['enabled'] || $paypalOrderId === '' || !$db instanceof mysqli) {
http_response_code(400);
echo json_encode(['error' => 'invalid_request']);
exit;
}
$invoiceTable = website_table('billing_invoices');
$uid = (int)$user['user_id'];
$stmt = $db->prepare("SELECT * FROM `{$invoiceTable}` WHERE `invoice_id` = ? AND `user_id` = ? AND `status` = 'due' LIMIT 1");
$stmt->bind_param('ii', $invoiceId, $uid);
$stmt->execute();
$invoice = $stmt->get_result()->fetch_assoc();
$stmt->close();
if (!is_array($invoice) || (string)($invoice['paypal_order_id'] ?? '') !== $paypalOrderId) {
http_response_code(404);
echo json_encode(['error' => 'invoice_not_found']);
exit;
}
$access = website_paypal_oauth($config);
if (!$access) {
http_response_code(502);
echo json_encode(['error' => 'paypal_oauth_failed']);
exit;
}
$ch = curl_init(website_paypal_api_base($config) . '/v2/checkout/orders/' . rawurlencode($paypalOrderId) . '/capture');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Authorization: Bearer ' . $access],
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if (($http !== 200 && $http !== 201) || !is_string($response)) {
website_log('PayPal capture failed for invoice ' . $invoiceId);
http_response_code(502);
echo json_encode(['error' => 'paypal_capture_failed']);
exit;
}
$json = json_decode($response, true);
$status = (string)($json['status'] ?? '');
$capture = $json['purchase_units'][0]['payments']['captures'][0] ?? [];
$captureId = (string)($capture['id'] ?? '');
$payerEmail = (string)($json['payer']['email_address'] ?? '');
$paidAmount = (float)($capture['amount']['value'] ?? 0);
$currency = (string)($capture['amount']['currency_code'] ?? '');
if ($status !== 'COMPLETED' || $captureId === '' || abs($paidAmount - (float)$invoice['amount']) > 0.01 || $currency !== (string)$invoice['currency']) {
http_response_code(409);
echo json_encode(['error' => 'payment_not_verified']);
exit;
}
website_mark_invoice_paid($invoiceId, 'paypal', $paypalOrderId, $captureId, $payerEmail, ['paypal_status' => $status]);
echo json_encode(['status' => 'COMPLETED', 'invoice_id' => $invoiceId]);