E-Commerce Integration Guide

Connect your platform to PCC for seamless labor law poster fulfillment

API Base URL

All requests go to:

https://api.postercompliance.com

DROPSHIP Quick Start for Dropship Partners

As a dropship partner, you send orders and we ship directly to your customers under your contracted rates. Here's your simplified flow:

1. Get Products GET /v1/products
2. Submit Order POST /v1/checkout
3. Get Tracking GET /v1/orders/.../tracking
How Dropship Works:
  • You send orders - Submit customer details and products via API
  • We handle pricing - Send $0 for prices, we apply your contracted rates
  • We calculate tax - Send $0 for tax, we calculate based on ship-to address
  • We ship to your customer - Direct fulfillment from our warehouse
  • We invoice you - Consolidated billing per your agreement

Complete Dropship Checkout Example

Here's exactly what your checkout request should look like:

POST /v1/checkout HTTP/1.1
Host: api.postercompliance.com
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json

{
  "account": {
    "name": "John Smith",
    "email": "john.smith@example.com",
    "phone": "555-123-4567",
    "shippingAddress": {
      "line1": "123 Main Street",
      "line2": "Suite 100",
      "city": "Austin",
      "stateOrProvince": "TX",
      "postalCode": "78701",
      "country": "US"
    }
  },
  "order": {
    "externalOrderNumber": "YOUR-ORDER-12345",
    "orderType": "New",
    "lineItems": [
      {
        "sku": "1-P-SP-TX-XX-A-E-L-0325",
        "quantity": 1,
        "pricePerUnit": 0
      }
    ],
    "shippingAmount": 0,
    "taxAmount": 0,
    "payment": {
      "transactionId": "YOUR-ORDER-12345",
      "paymentDate": "2026-02-15T10:00:00Z",
      "amount": 0
    }
  }
}

Note: All pricing fields are $0 because PCC applies your contracted rates automatically. Use "orderType": "Renewal" with originalOrderNumber for subscription renewals. Add "testMode": true to test without creating real orders.

Full Integration Guide

1

Authentication

PCC will provide you with an API token. Include it in all requests:

Authorization: Bearer YOUR_API_TOKEN

Your token determines:

2

Get Products

Retrieve our product catalog. Cache this data and refresh daily or weekly.

GET /v1/products

Request:

GET /v1/products HTTP/1.1
Host: api.postercompliance.com
Authorization: Bearer YOUR_API_TOKEN

Response:

{
  "success": true,
  "message": "Successfully retrieved 150 available products (price source: Default)",
  "data": {
    "products": [
      {
        "name": "California State & Federal Labor Law Poster - 1 Year Plan - AIO - English",
        "productNumber": "1-P-SP-CA-XX-A-E-L-0325",
        "price": 149.99,
        "longDescription": "Comprehensive California state and federal labor law poster with all required postings, updated automatically for 1 year.",
        "photoUrl": "https://api.postercompliance.com/v1/products/1-P-SP-CA-XX-A-E-L-0325/photo",
        "details": {
          "posterType": "SP",
          "posterTypeDescription": "State Poster",
          "state": "CA",
          "stateName": "California",
          "cityCounty": "XX",
          "cityCountyDescription": "California Only",
          "language": "English",
          "languageDescription": "English",
          "isStateFederal": true,
          "isCityCounty": false,
          "planTerm": 1,
          "productType": "Plan",
          "productTypeDescription": "1 Yr Plan",
          "posterFormat": "AllInOne",
          "posterFormatDescription": "All In One"
        }
      }
    ],
    "totalCount": 150,
    "priceLevelApplied": null,
    "pricesOverridden": 0
  }
}

Key Product Fields

Field Description
productNumber Use this when placing orders. Unique product SKU identifier.
price Retail price. Dropship partners: your contracted rate may differ.
details.productType "Plan" (annual subscription with updates) or "Set" (one-time purchase)
details.posterFormat "AllInOne" (single poster) or "SeparatePosters" (multiple posters)
details.state 2-letter state code (e.g., "CA", "TX", "NY")
photoUrl Product image URL (can be null)
longDescription Extended product description from Dynamics (can be null)
Filter by type: Add ?productType=Plan for subscriptions only, or ?productType=Set for one-time purchases.
Important: Use the productNumber value as the sku field when placing checkout orders.
3

Calculate Tax (Optional for Dropship)

Dropship Partners: You can skip this step. When you submit an order with $0 for tax, we calculate it automatically based on the shipping address.

For standard integrations where you collect payment, get the tax estimate first:

POST /v1/orders/estimate
POST /v1/orders/estimate HTTP/1.1
Host: api.postercompliance.com
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json

{
  "shippingDestinations": [
    {
      "destinationId": "1",
      "shippingAddress": {
        "street": "123 Main Street",
        "city": "Austin",
        "state": "TX",
        "zipCode": "78701"
      },
      "items": [
        {
          "productNumber": "1-P-SP-TX-XX-A-E-L-0325",
          "quantity": 1,
          "unitPrice": 149.99
        }
      ],
      "shippingAmount": 14.99
    }
  ]
}

Response:

{
  "success": true,
  "message": "Successfully calculated estimate for 1 destinations",
  "data": {
    "orderId": null,
    "destinationResults": [
      {
        "destinationId": "1",
        "shippingAddress": {
          "street": "123 Main Street",
          "city": "Austin",
          "state": "TX",
          "zipCode": "78701",
          "country": "US"
        },
        "subtotal": 149.99,
        "shippingAmount": 14.99,
        "taxAmount": 13.61,
        "total": 178.59,
        "lineItemTaxes": [
          {
            "lineId": null,
            "productNumber": "1-P-SP-TX-XX-A-E-L-0325",
            "quantity": 1,
            "unitPrice": 149.99,
            "extendedPrice": 149.99,
            "taxAmount": 12.37,
            "totalWithTax": 162.36
          }
        ],
        "taxCloudCartId": "abc123-def456",
        "isExempt": false,
        "taxCalculationSuccess": true,
        "taxCalculationError": null
      }
    ],
    "totalTax": 13.61,
    "totalSubtotal": 149.99,
    "totalShipping": 14.99,
    "grandTotal": 178.59
  }
}
Important: Check taxCalculationSuccess. If false, the tax couldn't be calculated - don't proceed to checkout.
4

Submit Order

Submit the order for fulfillment. Choose the tab that matches your scenario.

POST /v1/checkout
{
  "account": {
    "name": "Customer Name",
    "email": "customer@email.com",
    "phone": "555-123-4567",
    "shippingAddress": {
      "line1": "123 Main Street",
      "city": "Austin",
      "stateOrProvince": "TX",
      "postalCode": "78701",
      "country": "US"
    }
  },
  "order": {
    "externalOrderNumber": "YOUR-ORDER-ID",
    "orderType": "New",
    "lineItems": [
      {
        "sku": "1-P-SP-TX-XX-A-E-L-0325",
        "quantity": 1,
        "pricePerUnit": 0
      }
    ],
    "shippingAmount": 0,
    "taxAmount": 0,
    "payment": {
      "transactionId": "YOUR-ORDER-ID",
      "paymentDate": "2026-02-15T10:00:00Z",
      "amount": 0
    }
  }
}

Dropship: All pricing fields are $0 - PCC applies your contracted rates.
Standard: Include actual prices. Total must match: lineItems + shipping + tax = payment.amount

{
  "order": {
    "externalOrderNumber": "YOUR-RENEWAL-ORDER-456",
    "orderType": "Renewal",
    "originalOrderNumber": "SO-2025-00001234",
    "lineItems": [
      {
        "sku": "1-P-SP-TX-XX-A-E-L-0326",
        "quantity": 1,
        "pricePerUnit": 0
      }
    ],
    "shippingAmount": 0,
    "taxAmount": 0,
    "payment": {
      "transactionId": "YOUR-RENEWAL-ORDER-456",
      "paymentDate": "2026-02-15T10:00:00Z",
      "amount": 0
    }
  }
}

Account is auto-resolved: For renewals, the shipping account is automatically looked up from the original order - you don't need to provide account details.
Update info on renewal: If you include account with new info (name, email, address), the account will be updated in our system and the new info used for this order.
Save the orderNumber from each order result to use as originalOrderNumber for future renewals.

{
  "account": {
    "name": "Test Customer",
    "email": "test@example.com",
    "shippingAddress": {
      "line1": "123 Test Street",
      "city": "Austin",
      "stateOrProvince": "TX",
      "postalCode": "78701",
      "country": "US"
    }
  },
  "order": {
    "externalOrderNumber": "TEST-ORDER-001",
    "orderType": "New",
    "testMode": true,
    "lineItems": [
      {
        "sku": "1-P-SP-TX-XX-A-E-L-0325",
        "quantity": 1,
        "pricePerUnit": 0
      }
    ],
    "shippingAmount": 0,
    "taxAmount": 0,
    "payment": {
      "transactionId": "TEST-ORDER-001",
      "paymentDate": "2026-02-15T10:00:00Z",
      "amount": 0
    }
  }
}

Test mode validates without creating records - products, SKUs, tax calculation, and renewal links are all verified, but no accounts, orders, or invoices are created in Dynamics.
Perfect for development and integration testing. Response includes "testMode": true and simulated IDs (e.g., TEST-...).

Response:

{
  "success": true,
  "message": "Checkout queued successfully",
  "data": {
    "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "Pending",
    "externalOrderNumber": "YOUR-ORDER-ID",
    "testMode": false,
    "message": "Checkout order queued for processing",
    "statusUrl": "/v1/jobs/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}
What happens next: Orders are processed asynchronously. Save the jobId to check status.

Order Fields Reference

Field Required Description
accountNumber No PCC account number if known (skips account lookup). For renewals, auto-resolved from original order.
account.name New orders Customer or company name. For renewals: optional, but if provided will update the account.
account.email New orders Customer email address. For renewals: optional, but if provided will update the account.
account.shippingAddress New orders Where to ship. For renewals: optional, but if provided will update the account.
order.externalOrderNumber Yes Your order ID for reference
order.orderType No "New" (default) or "Renewal"
order.originalOrderNumber If renewal PCC order number from original order (e.g., "SO-2025-00001234")
order.testMode No Set to true for development testing (default: false)
order.lineItems Yes Products to order (sku, quantity, pricePerUnit)
order.payment Yes Payment reference (transactionId, paymentDate, amount)
5

Check Order Status

Poll the status endpoint to see when your order completes.

GET /v1/jobs/{jobId}
GET /v1/jobs/a1b2c3d4-e5f6-7890-abcd-ef1234567890 HTTP/1.1
Host: api.postercompliance.com
Authorization: Bearer YOUR_API_TOKEN

Response (Completed):

{
  "success": true,
  "message": "Job retrieved successfully",
  "data": {
    "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "jobType": "CheckoutOrder",
    "status": "Completed",
    "totalItems": 1,
    "processedItems": 1,
    "succeededItems": 1,
    "failedItems": 0,
    "progressPercent": 100,
    "createdAt": "2026-02-15T10:00:00Z",
    "startedAt": "2026-02-15T10:00:01Z",
    "completedAt": "2026-02-15T10:00:15Z",
    "errorMessage": null,
    "checkoutResults": {
      "success": true,
      "message": "Checkout completed successfully",
      "accountCreated": true,
      "account": {
        "accountId": "abc12345-1234-5678-9abc-def012345678",
        "accountNumber": "1234567",
        "name": "Customer Name",
        "isNew": true,
        "resolution": "Created new account"
      },
      "order": {
        "success": true,
        "message": "Order created successfully",
        "salesOrder": {
          "salesOrderId": "def45678-5678-9abc-def0-123456789abc",
          "orderNumber": "SO-2026-00001234",
          "subtotal": 149.99,
          "taxAmount": 13.61,
          "totalAmount": 178.59,
          "lineItemCount": 2,
          "lineItems": [
            {
              "lineItemId": "line-item-guid-1",
              "sku": "1-P-SP-TX-XX-A-E-L-0325",
              "productName": "Texas Labor Law Poster - 1 Year Plan",
              "quantity": 1,
              "pricePerUnit": 149.99,
              "extendedAmount": 149.99
            },
            {
              "lineItemId": "line-item-guid-2",
              "sku": "N-S-SH-SD-XX-X-X-X-0000",
              "productName": "Shipping Standard",
              "quantity": 1,
              "pricePerUnit": 14.99,
              "extendedAmount": 14.99
            }
          ]
        },
        "invoice": {
          "invoiceId": "inv-guid-12345",
          "invoiceNumber": "INV-2026-00001234",
          "totalAmount": 178.59,
          "taxAmount": 13.61,
          "status": "Posted"
        },
        "payment": {
          "paymentId": "pay-guid-12345",
          "amount": 178.59,
          "transactionId": "YOUR-ORDER-ID",
          "recorded": true
        },
        "processingSteps": [],
        "errors": []
      },
      "processingSteps": [],
      "errors": []
    }
  }
}
Key fields to save:
  • checkoutResults.account.accountNumber - Reuse for future orders from same customer
  • checkoutResults.order.salesOrder.orderNumber - Use to get tracking information

Status Values

Status Meaning Action
Pending Queued for processing Wait 3-5 seconds, check again
Processing Currently being processed Wait 3-5 seconds, check again
Completed Order created successfully Save the orderNumber
RetryPending Temporary failure, will retry automatically Wait for scheduled retry (see errorMessage)
Failed Error occurred (validation, bad data) Check errorMessage, fix and resubmit
PermanentlyFailed Failed after 5 retry attempts Contact support or resubmit manually
Automatic Retries: When our backend systems experience temporary issues, jobs are automatically retried up to 5 times with increasing delays (1 min, 5 min, 15 min, 30 min, 1 hour). You don't need to resubmit - just keep polling. The errorMessage field shows the retry schedule.

Most orders complete within 30-60 seconds.

6

Get Tracking

Once an order ships, retrieve the tracking number to share with your customer.

GET /v1/orders/{orderNumber}/tracking
GET /v1/orders/SO-2026-00001234/tracking HTTP/1.1
Host: api.postercompliance.com
Authorization: Bearer YOUR_API_TOKEN

Response (Shipped):

{
  "success": true,
  "message": "Tracking information retrieved for order SO-2026-00001234",
  "data": {
    "orderNumber": "SO-2026-00001234",
    "trackingNumber": "1Z999AA10123456784",
    "found": true,
    "isRenewal": false,
    "errorMessage": null
  }
}

Response (Not Yet Shipped):

{
  "error": "NotFound",
  "message": "Order 'SO-2026-00001234' not found or not in fulfilled status",
  "traceId": "0HN4ABC123"
}

Response (Renewal Order):

{
  "success": true,
  "message": "Renewal order SO-2026-00001234 - no shipping required",
  "data": {
    "orderNumber": "SO-2026-00001234",
    "trackingNumber": null,
    "found": true,
    "isRenewal": true,
    "errorMessage": "Renewal orders do not require shipping and will not have tracking numbers"
  }
}
When to check:
  • Orders typically ship within 1-3 business days
  • Start checking 24 hours after order submission
  • Check once every 4-6 hours until tracking is available
Renewal Orders:

Renewal orders do not require shipping and will not have tracking numbers. When you query tracking for a renewal order, it will return isRenewal: true with a message explaining that no shipping is required. You do not need to poll for tracking on renewal orders.

Bulk Tracking (Multiple Orders)

Check tracking for multiple orders at once:

POST /v1/orders/tracking

Request:

POST /v1/orders/tracking HTTP/1.1
Host: api.postercompliance.com
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json

{
  "orderNumbers": [
    "SO-2026-00001234",
    "SO-2026-00001235",
    "SO-2026-00001236"
  ]
}

Response:

{
  "success": true,
  "message": "Tracking information retrieved",
  "data": {
    "totalRequested": 3,
    "totalFound": 2,
    "results": [
      {
        "orderNumber": "SO-2026-00001234",
        "trackingNumber": "1Z999AA10123456784",
        "found": true,
        "isRenewal": false,
        "errorMessage": null
      },
      {
        "orderNumber": "SO-2026-00001235",
        "trackingNumber": null,
        "found": true,
        "isRenewal": true,
        "errorMessage": "Renewal orders do not require shipping and will not have tracking numbers"
      },
      {
        "orderNumber": "SO-2026-00001236",
        "trackingNumber": null,
        "found": false,
        "isRenewal": false,
        "errorMessage": "Order not found or not fulfilled"
      }
    ]
  }
}
!

Error Handling

When something goes wrong, you'll get a clear error response:

{
  "error": "ValidationError",
  "message": "Shipping address is required",
  "details": null,
  "traceId": "0HN4ABC123",
  "timestamp": "2026-02-15T10:00:00Z",
  "validationErrors": {
    "account.shippingAddress": [
      "Shipping address is required"
    ]
  }
}

HTTP Status Codes

Code Meaning What to Do
400 Bad request / validation error Check the error message and fix your request
401 Not authenticated Check your API token is correct
403 Not authorized Your token doesn't have access to this endpoint
404 Not found Check the order number or SKU exists
429 Too many requests Slow down and retry in a few seconds
500 Server error Retry later. Contact support if it persists.
Need help? Include the traceId from the error response when contacting support.