基于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
相关产品推荐
相关产品推荐

