Skip to main content

Testing And Troubleshooting

Use this checklist before moving a catalog or procurement integration to production.

Preflight Checklist​

  • Merchant account is active.
  • Integrating user has owner or admin access.
  • Target store exists.
  • API key was created with the intended scope.
  • API key lifetime matches the environment's rotation policy.
  • GET /api/v1/catalog/stores returns the expected store.
  • Product source system can send stable sku or externalId.
  • Product and procurement image URLs are public HTTPS URLs; galleries contain no more than 20 valid URLs.
  • Product page URLs are public HTTPS URLs.
  • Procurement suppliers and inventory inputs have stable external IDs when syncing from ERP or supplier systems.
  • Webhook destination URL is public HTTPS if outbound webhooks are used.
  • Staging and production use separate API keys.

See Dashboard Setup if any merchant, store, sub-merchant, or API key setup item is missing.

Use Merchant Readiness Checklist to confirm merchant-side catalog, cart, checkout, delivery, security, and operations readiness.

REST API Test Flow​

  1. List stores:
curl "https://merchant.thyris.cloud/api/v1/catalog/stores" \
-H "Authorization: Bearer tr_live_your_key_here"
  1. Upsert a product:
curl -X POST "https://merchant.thyris.cloud/api/v1/catalog/products" \
-H "Authorization: Bearer tr_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"storeId": "STORE_UUID",
"sku": "QA-SKU-001",
"externalId": "qa_product_001",
"name": "QA Product",
"price": 9.99,
"currency": "USD",
"status": "active",
"inStock": true,
"inventoryQuantity": 10,
"imageUrls": [
"https://cdn.example.com/qa-product.png",
"https://cdn.example.com/qa-product-back.png"
]
}'
  1. Search the product:
curl "https://merchant.thyris.cloud/api/v1/catalog/products?storeId=STORE_UUID&q=QA-SKU-001" \
-H "Authorization: Bearer tr_live_your_key_here"
  1. Create a cart using the returned catalogId:
curl -X POST "https://merchant.thyris.cloud/api/v1/catalog/carts" \
-H "Authorization: Bearer tr_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"storeId": "STORE_UUID",
"items": [
{
"catalogId": "1234567890",
"quantity": 1
}
]
}'
  1. Complete the order using the returned checkoutId:
curl -X POST "https://merchant.thyris.cloud/api/v1/catalog/orders" \
-H "Authorization: Bearer tr_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"checkoutId": "chk_1234567890abcdef12345678",
"payment": {
"id": "pay_qa_1234567890",
"status": "paid",
"provider": "qa"
},
"customer": {
"name": "QA Customer",
"email": "qa@example.com"
},
"shippingAddress": {
"line1": "QA Street 1",
"city": "Example City",
"country": "US",
"postalCode": "10001"
}
}'

Webhook Test Flow​

Catalog inbound:

  1. Send product.upserted to https://webhooks.thyris.cloud/webhooks/catalog.
  2. Confirm the response includes success: true.
  3. Confirm the product appears in the dashboard.
  4. Send the same payload again and confirm the response mode is updated.
  5. Send product.deleted and confirm the product is removed or ignored if already absent.

Procurement inbound:

  1. Send supplier.updated to https://webhooks.thyris.cloud/webhooks/procurement.
  2. Confirm the response includes success: true.
  3. Confirm the supplier appears in the procurement dashboard.
  4. Send inventory.updated for a procurement inventory item.
  5. Create an order request with status=requested and confirm the supplier quote request workflow starts.
  6. Reply to the supplier email from the configured inbound mailbox and confirm the order moves to quote_received.

Outbound:

  1. Create a destination URL in the dashboard.
  2. Add a secret if the receiver validates x-webhook-secret.
  3. Subscribe to a small event set first, for example product.created and product.updated.
  4. Trigger a test event from the dashboard.
  5. Confirm the receiver returns 2xx.
  6. Review delivery logs in the dashboard.

Repeat the catalog outbound test through MCP: run catalog_upsert_product, catalog_create_cart, and catalog_complete_order, then confirm subscribed deliveries use direction=outbound, source=mcp, and the documented event names. Procurement MCP supplier/inventory operations also emit events but currently carry source=api; MCP procurement order creation defaults to source=mcp.

For procurement outbound, configure the destination under Store > Procurement > Integrations > Webhooks and start with a small event set such as procurement.order.created and procurement.order.sent.

Dashboard Regression Checks​

  1. Select rows in Catalog Products, Procurement Inventory, and Procurement Suppliers and verify Bulk Actions stays unavailable with no selection and deletes the selected rows after the common confirmation dialog.
  2. Create an API key with each expiration unit and with Never; verify the raw-key result is cleared before opening the create dialog again.
  3. Verify a revoked or expired key returns 401, the revoked date is shown, and an active or merely expired key cannot be deleted before revocation.
  4. Verify bulk API-key revoke processes only the non-revoked portion of a mixed selection and bulk delete accepts only an all-revoked selection.
  5. Confirm destructive flows use the styled application popup, without a decorative icon or native browser banner, and that Cancel has no background or border hover change.
  6. Compare server-rendered and hydrated API-key dates; both should render in English with the same deterministic timezone value.

Common Errors​

401 Unauthorized​

Cause:

  • Missing API key.
  • Invalid API key.
  • Revoked key.
  • Expired key.
  • Inactive merchant account.

Fix:

  • Confirm the header is Authorization: Bearer tr_live_....
  • Create a new key if the raw key was lost.
  • Confirm the merchant account is active.

403 Forbidden​

Cause:

  • API key scope does not include the requested store.
  • Store-scoped key attempted to access another store.
  • Custom key has no selected store access.

Fix:

  • Run GET /api/v1/catalog/stores.
  • Use one of the returned storeId values.
  • Create a correctly scoped key if needed.

400 Invalid product payload​

Cause:

  • Missing storeId, name, or price.
  • Invalid UUID.
  • Invalid URL.
  • More than 20 imageUrls, or a non-URL gallery entry.
  • Invalid currency length.
  • Invalid variant shape.

Fix:

  • Validate request JSON before sending.
  • Ensure currency is exactly 3 letters.
  • Send public URLs for imageUrl, every imageUrls entry, and productUrl.

400 Invalid procurement payload​

Cause:

  • Missing storeId or name for suppliers or inventory items.
  • Procurement order or quote has no items.
  • Order line is missing name or has invalid quantity.
  • Invalid supplier, inventory, or store UUID.

Fix:

  • Validate request JSON before sending.
  • Confirm the storeId is visible to the API key.
  • Use order statuses documented in Procurement REST API.

404 Product not found​

Cause:

  • Product UUID does not exist.
  • Product belongs to another store or merchant.
  • API key cannot access the product.

Fix:

  • Search by sku or externalId.
  • Use the returned product id for direct product endpoints.

409 SKU and externalId match different catalog products​

Cause:

  • The submitted sku matches one product and externalId matches another product in the same store.

Fix:

  • Correct source identifiers.
  • Merge or delete duplicate source records before retrying.

409 Cart or order conflict​

Cause:

  • Product is inactive.
  • Product is out of stock.
  • Requested quantity exceeds inventory.
  • Cart already has a checkout ID and cannot be cleared.
  • Checkout was already completed.

Fix:

  • Refresh product stock.
  • Use a new cart for a new checkout.
  • Do not retry completed checkout IDs as new orders.

Production Readiness​

  • API keys are stored securely.
  • Integration retries are idempotent.
  • Product upserts use stable sku or externalId.
  • Batch sync respects the 250 product inbound webhook batch limit.
  • Procurement order workflows use statuses instead of carts.
  • Webhook receiver returns 2xx quickly.
  • Monitoring exists for failed webhook deliveries and API error rates.
  • A rollback process exists for disabling keys and outbound destinations.