Testing And Troubleshooting
Use this checklist before moving a catalog or procurement integration to production.
Preflight Checklist
- Merchant account is active.
- Integrating user has
owneroradminaccess. - Target store exists.
- API key was created with the intended scope.
- API key lifetime matches the environment's rotation policy.
GET /api/v1/catalog/storesreturns the expected store.- Product source system can send stable
skuorexternalId. - 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
- List stores:
curl "https://merchant.thyris.cloud/api/v1/catalog/stores" \
-H "Authorization: Bearer tr_live_your_key_here"
- 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"
]
}'
- 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"
- 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
}
]
}'
- 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:
- Send
product.upsertedtohttps://webhooks.thyris.cloud/webhooks/catalog. - Confirm the response includes
success: true. - Confirm the product appears in the dashboard.
- Send the same payload again and confirm the response mode is
updated. - Send
product.deletedand confirm the product is removed or ignored if already absent.
Procurement inbound:
- Send
supplier.updatedtohttps://webhooks.thyris.cloud/webhooks/procurement. - Confirm the response includes
success: true. - Confirm the supplier appears in the procurement dashboard.
- Send
inventory.updatedfor a procurement inventory item. - Create an order request with
status=requestedand confirm the supplier quote request workflow starts. - Reply to the supplier email from the configured inbound mailbox and confirm the order moves to
quote_received.
Outbound:
- Create a destination URL in the dashboard.
- Add a secret if the receiver validates
x-webhook-secret. - Subscribe to a small event set first, for example
product.createdandproduct.updated. - Trigger a test event from the dashboard.
- Confirm the receiver returns
2xx. - 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
- 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.
- Create an API key with each expiration unit and with
Never; verify the raw-key result is cleared before opening the create dialog again. - 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. - Verify bulk API-key revoke processes only the non-revoked portion of a mixed selection and bulk delete accepts only an all-revoked selection.
- 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.
- 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
storeIdvalues. - Create a correctly scoped key if needed.
400 Invalid product payload
Cause:
- Missing
storeId,name, orprice. - 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
currencyis exactly 3 letters. - Send public URLs for
imageUrl, everyimageUrlsentry, andproductUrl.
400 Invalid procurement payload
Cause:
- Missing
storeIdornamefor suppliers or inventory items. - Procurement order or quote has no
items. - Order line is missing
nameor has invalidquantity. - Invalid supplier, inventory, or store UUID.
Fix:
- Validate request JSON before sending.
- Confirm the
storeIdis 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
skuorexternalId. - Use the returned product
idfor direct product endpoints.
409 SKU and externalId match different catalog products
Cause:
- The submitted
skumatches one product andexternalIdmatches 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
skuorexternalId. - Batch sync respects the 250 product inbound webhook batch limit.
- Procurement order workflows use statuses instead of carts.
- Webhook receiver returns
2xxquickly. - Monitoring exists for failed webhook deliveries and API error rates.
- A rollback process exists for disabling keys and outbound destinations.