CSharpAmazonSpAPI: Amazon Selling Partner API Binding for .NET C#

repository·main·Indexed 42 days ago

https://github.com/abuzuhri/amazon-sp-api-csharp

A strongly-typed .NET C# API binding for the Amazon Selling Partner API (SP-API). It provides models generated from Amazon's OpenAPI specifications to interact with Seller and Vendor APIs, including Orders, Reports, Finances, Feeds, and Catalog items. Features include automatic rate limit handling, SQS notification support, and a ReportManager for automating report retrieval and conversion into C# classes.

Tokens
11.2K
Snippets
21
Records
27
Agent score
4%

What's inside CSharpAmazonSpAPI

  1. Handle Usage Plans and Rate Limits

    main

    The library automatically handles Amazon SP-API rate limits by reading the x-amzn-RateLimit-Limit header to calculate necessary waiting times.

    If you wish to disable this automatic rate limit handling, set IsActiveLimitRate = false within your AmazonCredential configuration.

    var amazonConnection = new AmazonConnection(new AmazonCredential()
    {
          // ... other properties
          IsActiveLimitRate = false
    });
  2. Manage Reports and use ReportManager

    main

    The library provides two ways to handle Amazon reports:

    1. Direct API calls: Use amazonConnection.Reports to create reports, check status, and download documents. For reports containing PII, use GetReportDocument(reportId, true).
    2. ReportManager: A high-level abstraction that automates the process of requesting a report and converting the returned file into strongly-typed C# classes/lists. This is available for specific report types like GET_MERCHANT_LISTINGS_ALL_DATA or GET_FBA_INVENTORY_AGED_DATA.
    // Using ReportManager for easy conversion
    ReportManager reportManager = new ReportManager(amazonConnection);
    var products = reportManager.GetProducts(); // GET_MERCHANT_LISTINGS_ALL_DATA
    var inventoryAging = reportManager.GetInventoryAging(); // GET_FBA_INVENTORY_AGED_DATA
    
    // Direct API usage for a custom report
    var parameters = new ParameterCreateReportSpecification();
    parameters.reportType = ReportTypes.GET_FLAT_FILE_ALL_ORDERS_DATA_BY_LAST_UPDATE_GENERAL;
    parameters.dataStartTime = DateTime.UtcNow.AddDays(-30);
    parameters.dataEndTime = DateTime.UtcNow.AddDays(-10);
    parameters.marketplaceIds = new MarketplaceIds();
    parameters.marketplaceIds.Add(MarketPlace.UnitedArabEmirates.ID);
    
    var report = amazonConnection.Reports.CreateReport(parameters);
  3. Enable Debug Mode for HTTP Logging

    main

    To inspect all outgoing HTTP requests and incoming responses, enable debug mode by setting IsDebugMode = true in your AmazonCredential object.

    var amazonConnection = new AmazonConnection(new AmazonCredential()
    {
          // ... other properties
          IsDebugMode = true
    });
  4. Rotate LWA Client Secret (Application Management v2023-11-30)

    main

    Rotating the LWA client secret is an asynchronous process. The new secret is delivered via an SQS queue subscribed to the APPLICATION_OAUTH_CLIENT_NEW_SECRET notification.

    Rotation Workflow

    1. Subscribe: Use amazonConnection.Notification.CreateSubscription with NotificationType.APPLICATION_OAUTH_CLIENT_NEW_SECRET and your destinationId (SQS).
    2. Trigger: Call amazonConnection.ApplicationManagement.RotateApplicationClientSecret(). The SDK handles the special auth path internally.
    3. Receive: Poll SQS. The payload contains NewClientSecret, NewClientSecretExpiryTime, and OldClientSecretExpiryTime.

    Auto-applying Secrets

    Use RotationApplyingMessageReceiver to wrap your existing NotificationService receiver. This automatically updates amazonConnection.Credentials with the new secret.

    Important: You must persist all four fields from the payload to your database:

    • payload.ClientId: The row key.
    • payload.NewClientSecret: Store encrypted.
    • payload.NewClientSecretExpiryTime: When the new secret expires.
    • payload.OldClientSecretExpiryTime: The deadline to finish the cutover (after this, only the new secret works).
    // 1. Subscribe to rotation notifications
    amazonConnection.Notification.CreateSubscription(new ParameterCreateSubscription
    {
        notificationType = NotificationType.APPLICATION_OAUTH_CLIENT_NEW_SECRET,
        destinationId    = yourSqsDestinationId,
        payloadVersion   = "1.0",
    });
    
    // 2. Trigger rotation
    amazonConnection.ApplicationManagement.RotateApplicationClientSecret();
    
    // 3. Auto-apply using RotationApplyingMessageReceiver
    var wrapped = new RotationApplyingMessageReceiver(
        inner: myReceiver,
        credentials: amazonConnection.Credentials,
        onRotated: payload =>
        {
            // Persist these to your DB
            myDb.SaveRotatedSecret(
                clientId:                 payload.ClientId,
                newClientSecret:          payload.NewClientSecret,
                newClientSecretExpiresAt: payload.NewClientSecretExpiryTime,
                oldClientSecretExpiresAt: payload.OldClientSecretExpiryTime);
        });
    
    NotificationService.StartReceivingNotificationMessages(param, wrapped);
  5. Access support and community discussions

    main
    If you have questions or need assistance with the library, you can participate in the GitHub Discussions section of the repository. For professional consultation regarding Amazon SP-API, the maintainers offer booking services via Calendly.
  6. Configure AmazonConnection and AmazonCredential

    main

    To use the library, initialize an AmazonConnection by providing an AmazonCredential object. You can specify the marketplace using either the MarketPlace enum or a specific MarketPlaceID string.

    Note on Marketplace: You can use MarketPlace.UnitedArabEmirates or provide a specific ID via MarketPlace.GetMarketPlaceByID("...").

    // Option 1: Using Marketplace enum
    AmazonConnection amazonConnection = new AmazonConnection(new AmazonCredential()
    {
         ClientId = "amzn1.application-XXX-client.XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         ClientSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         RefreshToken= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         MarketPlace = MarketPlace.UnitedArabEmirates,
    });
    
    // Option 2: Using MarketPlaceID string
    AmazonConnection amazonConnection = new AmazonConnection(new AmazonCredential()
    {
         ClientId = "amzn1.application-XXX-client.XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         ClientSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         RefreshToken= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         MarketplaceID = "A2VIGQ35RCS4UG"
    });
  7. Handle Amazon Notifications via SQS

    main

    The library supports receiving Amazon notifications through SQS.

    Setup Workflow

    1. Create Destination: Use CreateDestination to register your SQS ARN or EventBridge.
    2. Create Subscription: Use CreateSubscription to link a destinationId to a NotificationType. Note that you must create one subscription per type.
    3. Read Messages: Use NotificationService.StartReceivingNotificationMessagesAsync to start a long-polling loop.

    Best Practices

    • Long Polling: Enabled by default (20s). Avoid setting WaitTimeSeconds to 0 unless you want short polling.
    • Deduplication: SQS may deliver messages more than once. Implement deduplication in your IMessageReceiver using the NotificationId.
    • Graceful Shutdown: Use a CancellationToken in a restart loop to handle transient errors and allow for clean exits.
    // 1. Create Destination
    var destination = amazonConnection.Notification.CreateDestination(new Notifications.CreateDestinationRequest()
    {
        Name = "CompanyName_SQS",
        ResourceSpecification = new Notifications.DestinationResourceSpecification
        {
            Sqs = new Notifications.SqsResource("arn:aws:sqs:us-east-2:9999999999999:NAME")
        }
    });
    
    // 2. Create Subscription
    var result = amazonConnection.Notification.CreateSubscription(new ParameterCreateSubscription()
    {
        destinationId = destination.DestinationId,
        notificationType = NotificationType.ANY_OFFER_CHANGED,
        payloadVersion = "1.0"
    });
    
    // 3. Start Receiving Loop
    var param = new ParameterMessageReceiver(accessKey, secretKey, SQS_URL, Region, WaitTimeSeconds: 20);
    var messageReceiver = new CustomMessageReceiver();
    var cts = new CancellationTokenSource();
    
    await NotificationService.StartReceivingNotificationMessagesAsync(param, messageReceiver, cancellationToken: cts.Token);
  8. Configure required API keys

    main

    To use the library, you must obtain and provide the following credentials from your Amazon Developer account:

    NameDescription
    MarketplaceThe marketplace region (e.g., North America, Europe, Far East).
    ClientIdYour Amazon application ID.
    ClientSecretYour Amazon application secret.
    RefreshTokenThe refresh token obtained during the authorization process.

    Setup Steps:

    1. Create and configure IAM policies and entities.
    2. Register your Application.
    3. Authorize Selling Partner API applications.
  9. Configure connection using a proxy

    main

    The AmazonCredential object accepts a Proxy property which takes any IWebProxy implementation. This is useful for routed traffic or authenticated proxies. Proxy configuration is optional.

    // Standard proxy
    AmazonConnection amazonConnection = new AmazonConnection(new AmazonCredential()
    {
         ClientId = "amzn1.application-XXX-client.XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         ClientSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         RefreshToken= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         MarketplaceID = "A2VIGQ35RCS4UG",
         Proxy = new System.Net.WebProxy("http://xxx.xxx.xxx.xxx:xxxx"),
    });
    
    // Authenticated proxy
    AmazonConnection amazonConnection = new AmazonConnection(new AmazonCredential()
    {
         ClientId = "amzn1.application-XXX-client.XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         ClientSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         RefreshToken= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         MarketplaceID = "A2VIGQ35RCS4UG",
         Proxy = new System.Net.WebProxy("http://xxx.xxx.xxx.xxx:xxxx")
         {
             Credentials = new System.Net.NetworkCredential("username", "password")
         },
    });