Pricing
Login
All Blogs
Launch Week

Launch Week Day 2: Test Mode

A full sandbox environment to build and test your integration without placing real orders.

Launch Week Day 2: Test Mode

Today we're launching test mode for Zinc.

You've been asking for this for a while: a completely isolated environment where you can build your entire integration without placing real orders, dealing with cancellations, or spending money.

Why this matters

Until now, testing meant one of two things: place real orders and cancel them, or just hope your code works when it hits production.

Neither is great. Real orders cost real money, even if you cancel them. And "hope it works" isn't a testing strategy. It's how you find bugs in production when a customer's order fails and you don't know why.

We wanted something better. If you've ever integrated with Stripe, you know what good looks like: a test environment that behaves exactly like production, but with fake data and no real consequences. Flip a toggle, use test credentials, and build with confidence.

That's what we built.

How it works

There are two ways to enable test mode.

You can use a test API key, which is prefixed with zn_test_:

curl https://api.zinc.io/v2/orders \
  -H "Authorization: Bearer zn_test_abc123..."

Or you can add a header to any request:

curl https://api.zinc.io/v2/orders \
  -H "Authorization: Bearer zn_live_abc123..." \
  -H "X-Test-Mode: true"

Test products

The point of a test environment isn't just to see the happy path. It's to verify your integration handles failures correctly.

Real orders fail in specific ways. An item goes out of stock mid-checkout. The price changes and exceeds your max. The address doesn't validate. A variant is required but wasn't selected. Your wallet balance is too low.

You need to know your app handles all of these before you're processing real orders for real customers.

So we created test product URLs that trigger each scenario:

  • test-success — order completes successfully
  • test-out-of-stock — product unavailable
  • test-price-exceeded — total exceeds your max_price
  • test-invalid-address — shipping address fails validation
  • test-invalid-variant — variant selection required
  • test-shipping-unavailable — can't ship to that address
  • test-insufficient-funds — wallet balance too low
curl -X POST https://api.zinc.io/v2/orders \
  -H "Authorization: Bearer zn_test_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "products": [{"url": "https://zinc.io/shop/products/test-out-of-stock"}],
    "shipping_address": {...},
    "max_price": 5000
  }'

That order will fail with product_out_of_stock, exactly like it would in production if the item wasn't available.

Synchronous vs asynchronous errors

Some errors happen immediately, some happen later.

Synchronous errors, like an invalid address or unreachable URL, come back right away in the API response. You can catch these and show the user an error before anything else happens.

Asynchronous errors, like out of stock or price exceeded, happen during order processing. The order is created successfully, but fails later when we're actually checking out on the retailer's site. These show up when you poll the order status.

This matches how real orders behave. Some problems we can catch upfront. Some we only discover mid-checkout. Your integration needs to handle both, and now you can test both.

Data isolation

Test mode and production are completely separate. Test orders don't appear in your production order list. Production orders don't appear in test mode.

You can build your entire integration in test mode, verify everything works, then swap to a live API key and go.

Try it for yourself!

Switch to test mode directly in the dashboard. Create orders, trigger errors, and verify your integration handles everything correctly without spending a dollar.

For the full list of test products and error scenarios, check out Sandbox & Testing in our docs.

Tomorrow we're shipping something that makes async errors a lot easier to deal with.