Acumatica · Integration

Acumatica Amazon Marketplace Integration — A Complete Guide

Acumatica Amazon Marketplace Integration — A Complete Guide is the kind of integration that pays for itself the first time it runs without intervention.

John Kihiu12 min read

Every Amazon marketplace integration I've built for an Acumatica client starts with the same disappointment: there is no webhook. Amazon's Selling Partner API (SP-API) is pull-based for orders, and the client always expects push. Once that expectation is reset, the actual engineering is manageable: it's just a different shape of problem than a Shopify or Jumia webhook feed.

SP-API auth: LWA tokens, not a static API key

SP-API uses Login with Amazon (LWA) OAuth, layered with AWS Signature V4 signing on top for restricted operations. In practice this means your integration needs a refresh token (obtained once, during the seller's authorization flow) exchanged for a short-lived access token before every batch of calls:

C# · SP-API token refresh
public async Task<string> GetAccessTokenAsync()
{
    var req = new HttpRequestMessage(HttpMethod.Post, "https://api.amazon.com/auth/o2/token")
    {
        Content = new FormUrlEncodedContent(new Dictionary<string, string>
        {
            ["grant_type"] = "refresh_token",
            ["refresh_token"] = _settings.RefreshToken,
            ["client_id"] = _settings.LwaClientId,
            ["client_secret"] = _settings.LwaClientSecret,
        })
    };
    var resp = await _httpClient.SendAsync(req);
    resp.EnsureSuccessStatusCode();
    var payload = JsonSerializer.Deserialize<LwaTokenResponse>(await resp.Content.ReadAsStringAsync());
    return payload.AccessToken; // valid ~1 hour, cache it, don't refresh per-call
}

Access tokens last about an hour. I cache mine in a Business Events-triggered scheduled process's static state for the duration of a sync run rather than requesting a fresh token per order. Amazon rate-limits the token endpoint too, and a naive per-call refresh will get you throttled before you've pulled a single order.

Polling orders: getOrders with a rolling window, not a full scan

Since there's no webhook for new orders, I run a scheduled process (I use Acumatica's Automation Schedules, invoked every 5-10 minutes for active sellers) that calls the Orders API with a LastUpdatedAfter timestamp tracked in a small custom DAC. Never rely on CreatedAfter alone, because Amazon updates order status in place (payment confirmed, shipped, refunded) and you need those transitions, not just new-order creation.

C# · incremental order pull
var lastSync = PXSelect<UsrAmazonSyncState>.Select(Base).RowCast<UsrAmazonSyncState>().FirstOrDefault();
var since = lastSync?.LastUpdatedAfter ?? DateTime.UtcNow.AddHours(-1);

var url = $"https://sellingpartnerapi-na.amazon.com/orders/v0/orders" +
          $"?MarketplaceIds={marketplaceId}&LastUpdatedAfter={since:o}";
// SP-API responses are paginated via NextToken, loop until it's null
Store the watermark from the response, not from your local clock

Advance LastUpdatedAfter using the latest LastUpdateDate seen in the response payload, not DateTime.UtcNow at the moment your process ran. If your scheduled process runs late or SP-API is slow to respond, using the local clock as your watermark silently skips orders that updated in the gap. This is the single most common bug I've had to fix in other developers' Amazon integrations.

Mapping an Amazon order into SOOrder

Amazon order line items don't carry your internal Inventory ID; they carry an ASIN and a SellerSKU. I maintain a mapping DAC (UsrAmazonSkuMap) keyed on SellerSKU rather than trying to make ASIN the join key, because sellers control SKU but not ASIN, and SKU is what you set up during listing. Unmapped SKUs go into a "review" status rather than failing the whole order import: one bad mapping shouldn't block forty good orders in the same batch.

FBA changes the shipment side entirely

If the seller fulfills through FBA (Fulfilled by Amazon), Acumatica never actually ships the order; Amazon does, from Amazon's warehouse, using Amazon's own inventory pool. Your integration's job for FBA orders is financial reconciliation (matching settlement report line items to the order, since Amazon nets fees before paying out) rather than warehouse fulfillment. FBM (Fulfilled by Merchant) orders are the ones that flow through your normal SOOrder-to-shipment pipeline, calling Confirm Shipment back to SP-API with tracking once your warehouse ships. Building one integration and assuming it handles both fulfillment types identically is a mistake I've seen cost a client a full re-architecture six months in. Check the order's FulfillmentChannel field on ingest and branch early.

Settlement reports are where the real accounting work is

Amazon doesn't pay out per order. It pays out on a roughly bi-weekly settlement cycle, netting referral fees, FBA fees, refunds, and advertising spend against gross sales. The Finances API's settlement report is a flat file of hundreds or thousands of line items per period, and matching it back to individual SOOrder records for accurate GL posting is genuinely the hardest part of this integration, harder than the order sync itself, and I land the raw settlement lines in a staging DAC first, then run a reconciliation process that matches by order ID and posts fee/refund adjustments as separate AP-side transactions rather than trying to force everything through the original AR invoice.

Wrapping up

Amazon SP-API integration for Acumatica is a scheduled-poll pattern with LWA token caching, a SKU mapping table that survives the seller relisting products under new ASINs, an early fork between FBA and FBM handling, and a settlement reconciliation process that deserves its own attention rather than being bolted onto order sync as an afterthought. Budget real time for the settlement side: it's where the accounting actually lives.

John Kihiu
Acumatica ERP Developer · Laravel Engineer

Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.