You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Amazon SP-API创建订单变更Webhook的实现咨询

亚马逊SP-API订单状态变更Webhook实现(C#)

背景

我们公司正在调整亚马逊订单处理流程,当前通过SP-API的GetOrders接口拉取未发货订单,再用受限令牌获取PPE数据。但随着业务增长订单量增加,加上服务器例行维护或停机时,限流问题愈发严重。调研发现亚马逊通知系统已新增ORDER_STATUS_CHANGE事件,计划用Webhook方案替代轮询,已了解需要设置订阅、队列并提交Webhook目标,也找到了注册目标的代码示例,但缺少接收Webhook的C#服务基础代码(本人很少进行HTTP原生通信编程)。

一、注册Webhook目标的代码(优化版)

以下是注册Webhook目标的C#代码,替换配置项即可使用:

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace AmazonSpApiWebhook
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // 替换为对应地区的SP-API端点(北美/欧洲/亚太)
            string endpoint = "https://sellingpartnerapi-na.amazon.com";
            // 替换为你的SP-API访问令牌
            string accessToken = "YOUR_ACCESS_TOKEN";
            // 替换为你的卖家ID
            string sellerId = "YOUR_SELLER_ID";
            // 替换为目标 marketplace ID
            string marketplaceId = "YOUR_MARKETPLACE_ID";
            // 替换为你的HTTPS Webhook接收地址
            string webhookUrl = "YOUR_HTTPS_WEBHOOK_URL";
            // 自定义Webhook目标名称
            string destinationName = "OrderStatusChangeWebhook";

            using HttpClient client = new HttpClient();
            client.BaseAddress = new Uri(endpoint);
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            // 注意:事件类型指定为需要的ORDER_STATUS_CHANGE
            string requestBody = $"{{\"name\": \"{destinationName}\", \"resourceSpecification\": {{\"resourceType\": \"orders\", \"eventTypes\": [\"ORDER_STATUS_CHANGE\"]}}, \"destinationResource\": {{\"intendedState\": \"ACTIVE\", \"resourceType\": \"URL\", \"value\": \"{webhookUrl}\"}}}}";

            HttpResponseMessage response = await client.PostAsync(
                $"/notifications/v1/destinations?marketplaceIds={marketplaceId}&sellerId={sellerId}",
                new StringContent(requestBody, Encoding.UTF8, "application/json")
            );

            string responseContent = await response.Content.ReadAsStringAsync();

            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine("Webhook目标注册成功");
                Console.WriteLine("响应内容:" + responseContent);
            }
            else
            {
                Console.WriteLine($"注册失败,状态码:{response.StatusCode}");
                Console.WriteLine("错误信息:" + responseContent);
            }
        }
    }
}

二、接收Webhook的基础服务代码示例(ASP.NET Core)

基于ASP.NET Core Web API实现,无需手动处理HTTP底层细节,适合新手快速搭建:

using Microsoft.AspNetCore.Mvc;
using System.Text.Json;

namespace AmazonSpApiWebhookReceiver.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class AmazonWebhookController : ControllerBase
    {
        // 亚马逊会向该接口发送POST请求
        [HttpPost("OrderStatusChange")]
        public async Task<IActionResult> ReceiveOrderStatusChange()
        {
            try
            {
                // 1. 验证亚马逊请求签名(必须实现,防止恶意请求)
                bool isSignatureValid = ValidateAmazonSignature(Request);
                if (!isSignatureValid)
                {
                    return Unauthorized("无效的请求签名");
                }

                // 2. 读取请求体中的事件数据
                using var reader = new StreamReader(Request.Body);
                string requestBody = await reader.ReadToEndAsync();
                var webhookEvent = JsonSerializer.Deserialize<AmazonOrderStatusChangeEvent>(requestBody);

                // 3. 处理订单状态变更业务逻辑
                ProcessOrderStatusChange(webhookEvent);

                // 4. 返回200 OK,避免亚马逊重试
                return Ok();
            }
            catch (Exception ex)
            {
                // 记录错误日志
                Console.WriteLine($"处理Webhook失败:{ex.Message}");
                // 返回500会触发亚马逊重试,根据业务场景调整
                return StatusCode(500);
            }
        }

        // 签名验证占位方法,需替换为亚马逊官方文档指定的验证逻辑
        private bool ValidateAmazonSignature(HttpRequest request)
        {
            string signature = request.Headers["x-amz-signature"].ToString();
            string timestamp = request.Headers["x-amz-timestamp"].ToString();
            string signatureVersion = request.Headers["x-amz-signature-version"].ToString();

            // 需按照亚马逊文档步骤,用SP-API私钥验证签名,此处仅做占位
            return !string.IsNullOrEmpty(signature);
        }

        // 模拟订单状态变更处理逻辑
        private void ProcessOrderStatusChange(AmazonOrderStatusChangeEvent? webhookEvent)
        {
            if (webhookEvent == null) return;

            Console.WriteLine($"收到订单状态变更事件:");
            Console.WriteLine($"订单ID:{webhookEvent.Payload.OrderId}");
            Console.WriteLine($"新状态:{webhookEvent.Payload.OrderStatus}");
            Console.WriteLine($"事件ID:{webhookEvent.EventId}");

            // 此处添加业务逻辑:调用SP-API获取PPE数据、更新本地订单状态等
        }
    }

    // 对应亚马逊ORDER_STATUS_CHANGE事件的简化JSON结构
    public class AmazonOrderStatusChangeEvent
    {
        public string EventId { get; set; } = string.Empty;
        public string EventType { get; set; } = string.Empty;
        public DateTime EventTime { get; set; }
        public OrderStatusPayload Payload { get; set; } = new OrderStatusPayload();
    }

    public class OrderStatusPayload
    {
        public string OrderId { get; set; } = string.Empty;
        public string OrderStatus { get; set; } = string.Empty;
        // 可根据亚马逊文档补充更多字段
    }
}

关键注意事项

  • HTTPS要求:亚马逊强制Webhook接收地址为HTTPS,本地开发可使用ngrok等工具暴露HTTPS地址。
  • 签名验证:必须严格实现亚马逊官方的签名验证逻辑,防止伪造请求。
  • 幂等性:处理逻辑需保证幂等,避免重复接收同一事件导致业务异常。
  • 事件类型:注册Webhook时需指定ORDER_STATUS_CHANGE,而非示例中的ORDER_COMPLETED。

内容的提问来源于stack exchange,提问作者j.hull

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 10:07:45