What happens when things go wrong — and exactly what to do about it.
The samples below call the REST API with fetch (Node 18 and later, nothing to install), placing the same order every quickstart places, through this helper. Every call works with a test key (ps_test_) for $0. A declined card, unprintable artwork and a cancel production refuses happen only to a live order.
const API = "https://portal.printedsimply.com/api/v1"
const order = {
"items": [
{ "sku": "sticker-die-cut-3x3", "quantity": 100,
"artwork_url": "https://printedsimply.com/samples/sticker-3x3.png" }
],
"address_to": {
"name": "Jane Doe", "address1": "123 Main St",
"city": "Austin", "state": "TX", "zip": "78701", "country": "US"
},
"shipping": { "method": "standard" }
}
// Every call: the key in x-api-key, JSON both ways. Resolves to { data } on
// success, or to { status, error } (the error envelope) when it is refused.
async function api(method, path, body, idempotencyKey) {
const res = await fetch(API + path, {
method,
headers: {
'x-api-key': process.env.PRINTEDSIMPLY_API_KEY,
'Content-Type': 'application/json',
...(idempotencyKey ? { 'Idempotency-Key': idempotencyKey } : {}),
},
body: body === undefined ? undefined : JSON.stringify(body),
})
const json = await res.json()
return res.ok ? { data: json.data } : { status: res.status, error: json.error }
}An order the facility cannot finish moves to issue_flagged and sends order.issue. When the facility's status says why, the order and the event carry issue_reason. It is null on the order, and absent from the event, when no reason below fits. The flag clears when the facility moves the order on.
Simulate the flag on a test order and the order takes the same status and issue_reason a live one would, and order.issue is sent to your test-mode webhooks. Leave out issue_reason to rehearse a flag with none. The sandbox clock stops on a flag; simulate a later state (for example shipped) to move the order on, or cancel it. A live key is refused with test_mode_only.
curl -X POST https://portal.printedsimply.com/api/v1/order/test_ord_abc123/simulate \
-H "x-api-key: ps_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"target_state": "issue_flagged", "issue_reason": "artwork_unprintable"}'// order.issue: branch on why, and keep a default for a flag with no reason
if (event.event === 'order.issue') {
switch (event.data.issue_reason) {
case 'artwork_unprintable':
await askCustomerForNewArtwork(event.data.order_id)
break
case 'address_undeliverable':
await askCustomerToConfirmAddress(event.data.order_id)
break
default:
// shipment_exception, on_hold, cancellation_pending, or no issue_reason
await flagForReview(event.data.order_id)
}
}