Sandbox
Build and test your whole integration against a copy of a real program, with fake guests and no real money. Here is what the sandbox contains, how to get one, and where it behaves differently from production.
Available at launch
What the sandbox is#
The sandbox is a separate environment with its own host and its own data. Nothing you create there touches production, and nothing reaches real guests.
| Sandbox | Production | |
|---|---|---|
| Host | https://sandbox.api.unplugdining.com/v1 | https://api.unplugdining.com/v1 |
| Secret keys | uk_test_... | uk_live_... |
Webhook livemode | false | true |
| Square account | unPLUG's Square sandbox account | Your Square account |
Test keys work only on the sandbox host and live keys only on production. Sending one to the other host returns 401 invalid_api_key.
Your sandbox brand is connected to unPLUG's Square sandbox account, so locations and menu items carry real Square sandbox ids. Item rewards match on those ids at checkout, the same way they will against your production Square catalog.
The demo environment#
Every sandbox starts as a copy of the same demo environment: a coffee brand with two locations, a menu and a loyalty program. Support sends you the ids for your copy; the Square ids below are the same in every copy.
Program#
- Points are called Beans.
- Earning: 10 Beans per $1 on the subtotal after discounts, rounded down. Tax and tip don't earn.
- Tiers on lifetime Beans: Green from 0, Gold from 2,000 with a 200 Bean upgrade bonus.
- Default time zone:
America/Chicago. Points don't expire.
Locations#
| Name | Square location id | Time zone |
|---|---|---|
| South Congress | LQ7H2XK9M3RTB | America/Chicago |
| Riverside | L5VDN8P2WZ4KC | America/Chicago |
The unPLUG location ids (UUIDs) are different in each sandbox brand. Get yours from GET /v1/locations.
Menu#
Send these as pos_item_id and pos_category_ids on cart items. They are Square catalog item variation ids and category ids.
| Item | Price | pos_item_id | Category |
|---|---|---|---|
| Drip coffee, 12 oz | $3.25 | 3NZQ7XKJ2Y5PLVKCW6RQ4G2T | Coffee |
| Oat latte, 12 oz | $5.75 | HV4MZ2TQ7LW3KXRB5P8NJ6DC | Coffee |
| Cold brew, 16 oz | $4.75 | Q2XWB7KJ5MTR4PLZ9N3HC6VD | Coffee |
| Butter croissant | $3.50 | 7PKD3RXN2WQ6ZLHM4TB5JV8C | Pastries |
| Blueberry muffin | $3.75 | LT5W9QZ3HKXM2PNC7RB4DJ6V | Pastries |
| Breakfast taco | $4.25 | W8JC4NR6TK2ZQ5XHM3PLB7DV | Food |
| Category | pos_category_id |
|---|---|
| Coffee | C4RZ8NQ2MXK7WTP3LHB6V5JD |
| Pastries | P9MT2XQ6KZR4WLN8HCB3J7VD |
| Food | F6KW3TZ8QNM2XRB5HLC7J4VD |
One modifier is set up: Extra shot, $0.75, pos_modifier_id ZK3R7WQ5NP2XTM8HB4LC6JDV.
Rewards and codes#
| Reward | Cost | What it does |
|---|---|---|
| Free drip coffee | 500 Beans | One drip coffee free. |
| Free pastry | 700 Beans | One item from Pastries free. |
| $5 off | 900 Beans | $5.00 off an order of $5.00 or more. |
The shared code WELCOME10 takes 10% off one order. Each member can use it once, and guests without a member can use it too.
One wallet offer is set up: Fall pastry on us, one item from Pastries free, in the app or on the web. It's a granted offer, so it reaches a member as a wallet item with source: "offer", and each wallet item lasts 14 days. To put one in a test member's wallet, call POST /v1/test/members/{id}/wallet with its reward id.
Request a sandbox#
Email support@unplugdining.com with the subject "Sandbox: your brand name" and include:
- Your brand name, as it appears in the unPLUG dashboard.
- Name and email of your technical contact. Security notices and webhook failure emails go there.
- Platforms you're building: iOS, Android, web.
- A webhook URL, if you want us to register an endpoint for you. You can also do it yourself with the key.
- Email addresses that may receive sandbox emails. Sandbox email goes only to this allowlist.
- Whether you want to test push. If yes, we send a secure upload link for your test Firebase and APNs credentials.
You get back a uk_test_ key with every scope, the ids for your sandbox brand, the Square sandbox location and item ids, and your webhook endpoint if you asked for one. Don't put a secret key in an email, and don't send credentials as attachments; we never ask for either.
Test phone numbers#
Numbers from +15005550100 to +15005550199 count as verified in the sandbox. Use them when you test phone linking, for example to enroll a guest who already earned at the register. Treat any other number as unverified in the sandbox.
Test helpers#
Sandbox-only endpoints that set up states that are slow or impossible to reach through the normal API. They take your secret key and exist only on the sandbox host.
| Endpoint | What it does |
|---|---|
POST /v1/test/in_store_orders | Simulates a visit at a Square register for a member, so you see points and webhooks from in-store earning. |
POST /v1/test/members/{id}/wallet | Puts a reward in a member's wallet. |
POST /v1/test/webhooks | Sends any event type with sample data to your endpoints. |
POST /v1/test/members/{id}/expire_wallet_items | Expires all of a member's wallet items now. |
POST /v1/test/reset | Deletes all members and orders in your sandbox brand. |
Request and response details are on Test helpers.
What the sandbox doesn't do#
- No pushes to guests. Push and in-app messages go only to devices you register in the sandbox with
PUT /v1/members/me/devices/{device_id}. - No real emails. Email goes only to the addresses on your allowlist.
- No payments. unPLUG never charges cards. Use your payment processor's test mode next to the sandbox.
- No connection to your Square account. The sandbox uses unPLUG's Square sandbox, so ids from your production catalog won't match any item.
Gotchas#
- Ids differ per environment. Member, location, reward and Square ids in the sandbox are not the ones you'll see in production. Keep them in per-environment config, not in code.
external_order_idnever frees up. It's unique per brand forever, so a test script that reusesweb-1gets409 order_already_existson the second run. Add a run id to it, or callPOST /v1/test/resetfirst.- Fixed Idempotency-Keys replay. A hard-coded key returns the first response for 24 hours, with
Idempotent-Replayed: true. Generate a new UUID per operation. - Everything happens at once. The sandbox processes account deletion and other background work instantly. In production a deletion can take up to 30 days (usually minutes), so don't build flows that wait on it.
- Rate limits are real. The sandbox applies the same rate limits as production. A parallel test suite can hit
429 rate_limited. - Data doesn't last. Sandbox data older than 90 days may be cleared. Seed what your tests need with a script.
WELCOME10works once per member. Create a new member to test it again.