fix(track): send UpsertSmallBag auth via HTTP headers

Track SignatureValidationFilter reads appKey/timestamp/sign from headers, not query. Reverts e642f08 query transport and aligns debug script.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zzh 2026-06-29 12:35:39 +08:00
parent eac7b84f6a
commit bd1288edc9
3 changed files with 25 additions and 22 deletions

View File

@ -1,6 +1,6 @@
# 单独调试 POST /OrderV2/UpsertSmallBag(与 SmallBagTrackOrderClient 一致)
# 单独调试 POST /OrderV2/UpsertSmallBag(与 SmallBagTrackOrderClient 一致:鉴权走 Header)
param(
[string]$BaseUrl = "http://api.nanafa.com/track",
[string]$BaseUrl = "https://api.nanafa.com/track",
[string]$AppKey = "W2606001",
[string]$AppSecret = "ziK8UzlQ39m3kdL346XEBg8nljY8os52",
[string]$OrderNo = "",
@ -40,19 +40,18 @@ $body = @{
}
} | ConvertTo-Json -Depth 5 -Compress
$base = $BaseUrl.TrimEnd('/')
$url = "$base/OrderV2/UpsertSmallBag?appKey=$([uri]::EscapeDataString($AppKey))&timestamp=$timestamp&sign=$([uri]::EscapeDataString($sign))"
$url = ($BaseUrl.TrimEnd('/')) + "/OrderV2/UpsertSmallBag"
Write-Host "========== UpsertSmallBag Debug ==========" -ForegroundColor Cyan
Write-Host "URL: $url"
Write-Host "Timestamp: $timestamp"
Write-Host "Sign: $sign"
Write-Host "Headers: appKey=$AppKey, timestamp=$timestamp, sign=$sign"
Write-Host "Body:"
Write-Host ($body | ConvertFrom-Json | ConvertTo-Json -Depth 5)
Write-Host "========================================" -ForegroundColor Cyan
try {
$response = Invoke-WebRequest -Uri $url -Method POST `
-Headers @{ appKey = $AppKey; timestamp = "$timestamp"; sign = $sign } `
-ContentType "application/json; charset=utf-8" `
-Body ([System.Text.Encoding]::UTF8.GetBytes($body)) `
-UseBasicParsing
@ -64,12 +63,12 @@ catch {
$reader = New-Object System.IO.StreamReader($_.Exception.Response.GetResponseStream())
$errBody = $reader.ReadToEnd()
Write-Host "HTTP $([int]$_.Exception.Response.StatusCode)" -ForegroundColor Red
if ($errBody) { Write-Host $errBody } else { Write-Host "(empty body — 请核对 appKey/appSecret 或联系轨迹平台)" }
if ($errBody) { Write-Host $errBody } else { Write-Host "(empty body)" }
}
else {
Write-Host $_.Exception.Message -ForegroundColor Red
}
Write-Host ""
Write-Host "Tip: start OMS and POST /order/debug/track-upsert-small-bag with optional body fields." -ForegroundColor Yellow
Write-Host "Tip: track SignatureValidationFilter reads appKey/timestamp/sign from HTTP Headers." -ForegroundColor Yellow
exit 1
}

View File

@ -67,13 +67,25 @@ internal sealed class SmallBagTrackOrderClient(
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
var sign = SmallBagTrackSignHelper.GenerateSign(appKey, timestamp, settings.AppSecret.Trim());
var body = SmallBagTrackUpsertApiRequest.FromBusinessRequest(request);
var url = SmallBagTrackUpsertApiRequest.BuildRequestUrl(settings.BaseUrl, appKey, timestamp, sign);
var requestJson = JsonSerializer.Serialize(body, JsonOptions);
var url = SmallBagTrackUpsertApiRequest.BuildEndpointUrl(settings.BaseUrl);
var requestJson = JsonSerializer.Serialize(
new
{
auth = new { appKey, timestamp, sign, transport = "header" },
body
},
JsonOptions);
using var httpRequest = new HttpRequestMessage(HttpMethod.Post, url);
httpRequest.Headers.TryAddWithoutValidation("appKey", appKey);
httpRequest.Headers.TryAddWithoutValidation("timestamp", timestamp.ToString());
httpRequest.Headers.TryAddWithoutValidation("sign", sign);
httpRequest.Content = JsonContent.Create(body, options: JsonOptions);
var client = httpClientFactory.CreateClient(HttpClientName);
client.Timeout = TimeSpan.FromSeconds(Math.Max(5, settings.TimeoutSeconds));
using var response = await client.PostAsJsonAsync(url, body, cancellationToken);
using var response = await client.SendAsync(httpRequest, cancellationToken);
var responseBody = await response.Content.ReadAsStringAsync(cancellationToken);
return new SmallBagTrackUpsertResult
{

View File

@ -1,7 +1,7 @@
namespace Oms.Application.Integrations.SmallBagTrack;
/// <summary>
/// POST /OrderV2/UpsertSmallBag 业务请求体(公共参数 appKey/timestamp/sign 走 Query)。
/// POST /OrderV2/UpsertSmallBag 业务请求体(公共参数 appKey/timestamp/sign 走 HTTP Header)。
/// </summary>
internal sealed class SmallBagTrackUpsertApiRequest
{
@ -34,14 +34,6 @@ internal sealed class SmallBagTrackUpsertApiRequest
Consignee = request.Consignee
};
public static string BuildRequestUrl(string baseUrl, string appKey, long timestamp, string sign)
{
var root = $"{baseUrl.Trim().TrimEnd('/')}/OrderV2/UpsertSmallBag";
var query = string.Join(
'&',
$"appKey={Uri.EscapeDataString(appKey)}",
$"timestamp={timestamp}",
$"sign={Uri.EscapeDataString(sign)}");
return $"{root}?{query}";
}
public static string BuildEndpointUrl(string baseUrl) =>
$"{baseUrl.Trim().TrimEnd('/')}/OrderV2/UpsertSmallBag";
}