Как точно «JSON.stringify» в php (codeigniter4) в соответствии с Node/express JSON.stringify для проверки Sha256?Php

Кемеровские программисты php общаются здесь
Ответить
Anonymous
 Как точно «JSON.stringify» в php (codeigniter4) в соответствии с Node/express JSON.stringify для проверки Sha256?

Сообщение Anonymous »

У меня возникла проблема со сравнением sha256 для проверки веб-перехватчика из этой документации:
Документация API: docs.api.delyva.com
Руководство по API: блог delyva
Проверка веб-перехватчика (пример от поставщика API/delyva):
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());

app.post('/webhooks/delyva', (req, res) => {
const payload = JSON.stringify(req.body);
const signature = req.headers['x-delyvax-hmac-sha256'];
const expected = crypto.createHmac('sha256', process.env.DELYVA_API_SECRET)
.update(payload).digest('base64');
if (signature !== expected) return res.status(401).send('Invalid signature');
// handle event...
res.send('ok');
});

app.listen(3000, () => console.log('listening'));

Мой код в CodeIgniter4 (песочница):
public function postTracking(): ResponseInterface
{

// Set your API secret
$apiSecret = 'dx6ed8365ad507451595c151b6b61e3dbdcfbb987f';

// Get the raw POST body
$parsedBody = $this->request->getJSON();
$payload = json_encode($parsedBody, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

// Get the signature from headers
$signature = $this->request->getHeaderLine('X-Delyvax-Hmac-Sha256');

// Calculate expected signature
$expected = base64_encode(
hash_hmac('sha256', $payload, $apiSecret, true)
);

// Handle event...
return $this->respond([
'status' => 'success',
'sign' => $signature,
'computed' => $expected,
]);
}

Переменная для справки:
$apiSecret = 'dx6ed8365ad507451595c151b6b61e3dbdcfbb987f';

X-Delyvax-Hmac-Sha256 = f8vncFdUbn+STSRVnS3oa6Rr+50tEGevZaYc7LrRncw=

Тело json (запрос полезной нагрузки):
{
"id": "cfa3d6ff-3d37-4d8f-8d14-e7a064d520ab",
"companyId": "9e0aed8a-5c67-42a4-82b6-e01bf7687f31",
"userId": "06a8b310-fcfd-11f0-9353-1fee8250c30f",
"customerId": 126004,
"serviceId": 3234,
"serviceCode": "GDEXMY-WM",
"price": {
"amount": 0,
"currency": "MYR"
},
"revenue": {
"amount": 0,
"currency": "MYR"
},
"commission": {
"amount": 0,
"currency": "MYR"
},
"distance": {
"unit": "km",
"value": 1
},
"weight": {
"unit": "kg",
"value": 14.54
},
"cod": {
"amount": 0,
"currency": "MYR"
},
"consignmentNo": "DX0010241MY",
"paymentTerm": "debit",
"itemType": "PARCEL",
"itemTypeId": null,
"dimension": {
"unit": "cm",
"width": 0,
"height": 0,
"length": 0
},
"statusCode": 100,
"status": "created",
"createdAt": "2026-03-26T05:15:58.847Z",
"updatedAt": "2026-03-26T05:16:00.720Z",
"deletedAt": null,
"failedReason": "",
"promoCode": "",
"vehicleId": null,
"invoiceId": null,
"discountPrice": "0.00",
"discount": "0.00",
"personnelId": null,
"note": "",
"extId": "",
"extIdType": "",
"serviceAddon": null,
"rating": null,
"ratingNote": "",
"agentCommission": null,
"billing": {
"city": "",
"name": "gobisnes solutions enterprise",
"email": "nmaa3003@gmail.com",
"phone": "60103213012",
"state": "",
"mobile": "",
"unitNo": "",
"country": "MY",
"address1": "",
"address2": "",
"postcode": ""
},
"paymentMethodId": null,
"cancelledReason": null,
"source": "",
"promoValue": "0.00",
"cron": 0,
"metadata": {
"taskId": 468160
},
"personnel": {},
"commodityId": "",
"pluginId": null,
"surcharge": "0.00",
"requestPickup": null,
"insurance": {
"amount": 0,
"currency": "MYR"
},
"extTrackUrl": "",
"smsRate": "0.00",
"smsCredit": 0,
"smsUsed": 0,
"nanoId": "0mSeliGu",
"extId2": "",
"tip": "0.00",
"ip": "43.205.48.39",
"platformFee": "0.00",
"branded": false,
"pickupId": null,
"codStatus": null,
"referenceNo": null,
"multiPcs": null,
"multiPcsMaxWeight": 0,
"codDueAt": null,
"waRate": "0.00",
"waCredit": 0,
"waUsed": 0,
"rtsReason": null,
"pickupManifestId": null,
"quoteId": null,
"subConsignmentNo": [],
"labelS3Key": null,
"claimStatus": null,
"claimNotes": null,
"claimCreatedAt": null,
"slaPickupMin": null,
"slaDeliveryMin": null,
"slaCodProcessingMin": null,
"slaCodSettlementMin": null,
"slaClaimsMin": null,
"deliveryDueAt": null,
"pickupDueAt": null,
"waypoint": [
{
"id": "wp_t44MJUwwaLhKVF6qVGDcMg",
"orderId": "cfa3d6ff-3d37-4d8f-8d14-e7a064d520ab",
"no": 1,
"inventory": [
{
"name": "Apparel",
"type": "PARCEL",
"price": {
"amount": 60,
"currency": "MYR"
},
"action": "P",
"weight": {
"unit": "kg",
"value": 14.54
},
"quantity": 1,
"dimension": {
"unit": "cm",
"width": 10,
"height": 33,
"length": 30
},
"description": "-"
}
],
"contact": {
"city": "Kuala Lumpur",
"name": "GoBisnes Solutions Enterprise",
"coord": {
"lat": "3.07591",
"lon": "101.70577"
},
"phone": "60103213012",
"state": "Kuala Lumpur",
"unitNo": "",
"country": "MY",
"address1": "Lot 33, Jln Pauh Punggah",
"address2": "Kg Malaysia Raya",
"postcode": "57100",
"sortCode": "MW01"
},
"type": "PICKUP",
"description": "-",
"status": "pending",
"note": "-",
"scheduledAt": "2026-03-26T05:15:59.023Z",
"createdAt": "2026-03-26T05:15:58.847Z",
"updatedAt": "2026-03-26T05:16:00.720Z",
"deletedAt": null,
"cash": {
"amount": 0,
"currency": "MYR"
},
"placeId": null,
"actualScheduledAt": null,
"startAt": "2026-03-27T02:00:59.023Z",
"actualStartAt": null,
"extId": ""
},
{
"id": "wp_kdJYATv24G6rk7RLHWZrfB",
"orderId": "cfa3d6ff-3d37-4d8f-8d14-e7a064d520ab",
"no": 2,
"inventory": [
{
"name": "Apparel",
"type": "PARCEL",
"price": {
"amount": 60,
"currency": "MYR"
},
"action": "D",
"weight": {
"unit": "kg",
"value": 14.54
},
"quantity": 1,
"dimension": {
"unit": "cm",
"width": 10,
"height": 33,
"length": 30
},
"description": "-"
}
],
"contact": {
"city": "Sungai Besi",
"name": "Nik",
"phone": "60132017736",
"state": "Kuala Lumpur",
"unitNo": "",
"country": "MY",
"address1": "Jalan kenangan",
"address2": "",
"postcode": "12345",
"sortCode": "MW01"
},
"type": "DROPOFF",
"description": "-",
"status": "pending",
"note": "-",
"scheduledAt": "2026-03-26T14:00:59.023Z",
"createdAt": "2026-03-26T05:15:58.847Z",
"updatedAt": "2026-03-26T05:16:00.720Z",
"deletedAt": null,
"cash": {
"amount": 0,
"currency": "MYR"
},
"placeId": null,
"actualScheduledAt": null,
"startAt": "2026-03-26T05:17:59.969Z",
"actualStartAt": null,
"extId": ""
}
],
"orderId": "cfa3d6ff-3d37-4d8f-8d14-e7a064d520ab",
"consignmentNos": [
"DX0010241MY"
]
}

Я пытаюсь добиться того, чтобы гарантировалось, что мой PHP-код выполняет логику точно так же, как образец узла.
Я использую php. пример расчета веб-перехватчика основан на узле.
образец переменной взят из запроса, отправленного сервером веб-перехватчика.
Сейчас я все еще пытаюсь понять, как решить эту проблему. хэш/подпись по-прежнему не совпадают.
ОБНОВЛЕНИЕ: РЕШЕНИЕ (очевидно, секретный ключ не является ключом API для интеграции Delyva. Только что получил его от команды разработчиков):
// Get raw request body (for signature verification)
$rawBody = $this->request->getBody();

// Get signature from header
$signature = $this->request->getHeaderLine('X-Delyvax-Hmac-Sha256');

// Parse JSON data
$jsonData = json_decode($rawBody, true);

// Get API secret from merchant record
$apiSecret = 'YOUR SECRET KEY';

// Verify signature (if signature header is present)
if ($signature) {
$expected = hash_hmac('sha256', $rawBody, $apiSecret, true);
$expectedBase64 = base64_encode($expected);

if (!hash_equals($expectedBase64, $signature)) {
log_message('error', 'Invalid webhook signature for order: ' . $courierOrderId);
return $this->failUnauthorized('Invalid signature');
}

log_message('info', 'Webhook signature verified for order: ' . $courierOrderId);
} else {
log_message('warning', 'No signature header received for order: ' . $courierOrderId);
// You may choose to reject or accept based on your security needs
}
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Php»