У меня возникла проблема со сравнением 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
}
Как точно «JSON.stringify» в php (codeigniter4) в соответствии с Node/express JSON.stringify для проверки Sha256? ⇐ Php
Кемеровские программисты php общаются здесь
1774694868
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"
]
}
Я пытаюсь добиться того, чтобы [b]гарантировалось, что мой PHP-код выполняет логику точно так же, как образец узла.[/b]
Я использую php. пример расчета веб-перехватчика основан на узле.
образец переменной взят из запроса, отправленного сервером веб-перехватчика.
Сейчас я все еще пытаюсь понять, как решить эту проблему. хэш/подпись по-прежнему не совпадают.
[b]ОБНОВЛЕНИЕ: РЕШЕНИЕ[/b] (очевидно, секретный ключ не является ключом 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
}
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия