154 lines
4.0 KiB
PHP
154 lines
4.0 KiB
PHP
<?php
|
|
require __DIR__ . '/config.php';
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
http_response_code(405);
|
|
echo json_encode(['error' => 'Method not allowed']);
|
|
exit;
|
|
}
|
|
|
|
$rawBody = file_get_contents('php://input');
|
|
|
|
if (!$rawBody) {
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'Empty body']);
|
|
exit;
|
|
}
|
|
|
|
$payload = json_decode($rawBody, true);
|
|
|
|
if ($payload === null) {
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'Invalid JSON']);
|
|
exit;
|
|
}
|
|
|
|
// Verify HMAC signature if secret is configured
|
|
if (BTCPAY_WEBHOOK_SECRET) {
|
|
$sigHeader = $_SERVER['HTTP_BTCPAY_SIG'] ?? '';
|
|
$expectedSig = 'sha256=' . hash_hmac('sha256', $rawBody, BTCPAY_WEBHOOK_SECRET);
|
|
|
|
if (!hash_equals($expectedSig, $sigHeader)) {
|
|
http_response_code(403);
|
|
echo json_encode(['error' => 'Invalid signature']);
|
|
exit;
|
|
}
|
|
}
|
|
|
|
$type = $payload['type'] ?? null;
|
|
|
|
if (!$type) {
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'Missing type']);
|
|
exit;
|
|
}
|
|
|
|
// Only handle settled invoices
|
|
if ($type !== 'InvoiceSettled' && $type !== 'InvoicePaymentSettled') {
|
|
echo json_encode(['ok' => true, 'action' => 'ignored', 'type' => $type]);
|
|
exit;
|
|
}
|
|
|
|
// Read listingId directly from webhook payload metadata
|
|
$listingId = $payload['metadata']['listingId'] ?? null;
|
|
|
|
if (!$listingId) {
|
|
echo json_encode(['ok' => true, 'action' => 'skipped', 'reason' => 'No listingId in metadata']);
|
|
exit;
|
|
}
|
|
|
|
// Update listing in Directus: publish + set paid
|
|
$expiresAt = date('c', strtotime('+30 days'));
|
|
$now = date('c');
|
|
|
|
$directusPayload = json_encode([
|
|
'status' => 'published',
|
|
'payment_status' => 'paid',
|
|
'paid_at' => $now,
|
|
'expires_at' => $expiresAt,
|
|
]);
|
|
|
|
$directusUrl = DIRECTUS_URL . '/items/listings/' . urlencode($listingId);
|
|
|
|
$ch = curl_init($directusUrl);
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_CUSTOMREQUEST => 'PATCH',
|
|
CURLOPT_POSTFIELDS => $directusPayload,
|
|
CURLOPT_HTTPHEADER => [
|
|
'Content-Type: application/json',
|
|
'Authorization: Bearer ' . DIRECTUS_TOKEN,
|
|
],
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => 10,
|
|
CURLOPT_CONNECTTIMEOUT => 5,
|
|
]);
|
|
|
|
$directusResponse = curl_exec($ch);
|
|
$directusStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
$curlError = curl_error($ch);
|
|
curl_close($ch);
|
|
|
|
if ($directusResponse === false || $curlError) {
|
|
http_response_code(502);
|
|
echo json_encode([
|
|
'error' => 'Connection to Directus failed',
|
|
'listingId' => $listingId,
|
|
'curl_error' => $curlError,
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
if ($directusStatus >= 400) {
|
|
http_response_code(502);
|
|
echo json_encode([
|
|
'error' => 'Directus returned error',
|
|
'status' => $directusStatus,
|
|
'listingId' => $listingId,
|
|
'response' => substr($directusResponse, 0, 500),
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
// Fetch listing to get owner
|
|
$getUrl = DIRECTUS_URL . '/items/listings/' . urlencode($listingId) . '?fields=user_created';
|
|
$gch = curl_init($getUrl);
|
|
curl_setopt_array($gch, [
|
|
CURLOPT_HTTPHEADER => [
|
|
'Authorization: Bearer ' . DIRECTUS_TOKEN,
|
|
],
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => 5,
|
|
]);
|
|
$getResponse = curl_exec($gch);
|
|
curl_close($gch);
|
|
|
|
$listingData = json_decode($getResponse, true);
|
|
$userCreated = $listingData['data']['user_created'] ?? null;
|
|
|
|
// Create notification for listing owner
|
|
if ($userCreated) {
|
|
$notifPayload = json_encode([
|
|
'user_hash' => $userCreated,
|
|
'type' => 'listing_published',
|
|
'reference_id' => $listingId,
|
|
'read' => false,
|
|
]);
|
|
|
|
$notifUrl = DIRECTUS_URL . '/items/notifications';
|
|
$nch = curl_init($notifUrl);
|
|
curl_setopt_array($nch, [
|
|
CURLOPT_POST => true,
|
|
CURLOPT_POSTFIELDS => $notifPayload,
|
|
CURLOPT_HTTPHEADER => [
|
|
'Content-Type: application/json',
|
|
'Authorization: Bearer ' . DIRECTUS_TOKEN,
|
|
],
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => 5,
|
|
]);
|
|
curl_exec($nch);
|
|
curl_close($nch);
|
|
}
|
|
|
|
echo json_encode(['ok' => true, 'listingId' => $listingId, 'action' => 'published']);
|