Guides
View as MarkdownCheckout and order confirmation
Sending the shopper to checkout
Before showing Buy now, read the cart and confirm every line is available.
Link the button to buyLink. It opens Groupon's checkout page for that cart. If you have added
CJ, the shopper passes through CJ first; this is what credits your commission. The page shows
your logo if you gave one (see Get your API key).
Keep the cartId in the shopper's server-side session so you can tie the returning shopper to
the cart they bought.
The return redirect
If you gave no redirect URL, the shopper ends on Groupon's receipt page and gets Groupon's
confirmation email, and your site does not receive a grouponOrderUuid.
If you gave a redirect URL, Groupon redirects the shopper's browser there after a successful payment, with the order id added:
https://your-site.example/checkout/complete?grouponOrderUuid=5d0c2f3a-8b1e-4c7d-a9f0-1e2d3c4b5a69Your handler for that URL must:
- Read
grouponOrderUuidand check it looks like a UUID. Ignore any other parameter. Handle eachgrouponOrderUuidonce: a repeat visit shows the result you saved. - Call the booking endpoint from your server.
- Match the order's items to the cart in the shopper's session. If there is no session or no match, show a neutral "check your Groupon email" page and do not mark any cart as purchased.
- Keep the
cartIdand a snapshot of its lines until the order status is final. On success, mark the cart as purchased. OnREJECTEDorEXPIRED, read the cart; if it is gone, create a new one from the snapshot. - Render the confirmation page.
A shopper who closes the tab before the redirect still has a valid order: they receive Groupon's confirmation email and can find the purchase in their Groupon account.
Reading the order
curl -s "https://api-staging-core.livingsocial.com/partner_storefront/bookings/5d0c2f3a-8b1e-4c7d-a9f0-1e2d3c4b5a69" \
-H "Authorization: Bearer $GROUPON_API_KEY" \
-H "User-Agent: MyStore/1.0 (+https://mystore.example)"The order's own facts sit at the top level. Everything about what was bought is under items:
one entry per product and option, in the order they were bought. An order placed from a cart has
one item per cart line, and every unit item belongs to exactly one item.
This example is an order from a two-line cart. The second line is still awaiting fulfilment, so
the whole order reads ON_HOLD:
{
"id": "5d0c2f3a-8b1e-4c7d-a9f0-1e2d3c4b5a69",
"status": "ON_HOLD",
"supplierReference": "LG-ABCD-1234-EFGH",
"createdAt": "2026-09-18T12:10:44Z",
"items": [
{
"productId": "0b6f7a52-3c1d-4e8a-9f20-5d7c1a2b3c4d",
"optionId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"quantity": 2,
"status": "CONFIRMED",
"unitItems": [
{ "id": "a1b2c3d4-0000-4000-8000-000000000001", "status": "CONFIRMED",
"myGrouponUrl": "https://www.groupon.com/mygroupons/users/<purchaserId>/details/a1b2c3d4-0000-4000-8000-000000000001?inventory_service=vis" },
{ "id": "a1b2c3d4-0000-4000-8000-000000000002", "status": "CONFIRMED",
"myGrouponUrl": "https://www.groupon.com/mygroupons/users/<purchaserId>/details/a1b2c3d4-0000-4000-8000-000000000002?inventory_service=vis" }
]
},
{
"productId": "1c7e8b63-4d2e-4f9b-a031-6e8d2b3c4d5e",
"optionId": "8d0f7780-8536-41ef-a55f-f18fd2a01bf8",
"quantity": 1,
"status": "ON_HOLD",
"unitItems": [
{ "id": "a1b2c3d4-0000-4000-8000-000000000003", "status": "ON_HOLD",
"myGrouponUrl": "https://www.groupon.com/mygroupons/users/<purchaserId>/details/a1b2c3d4-0000-4000-8000-000000000003?inventory_service=vis" }
]
}
]
}The full field list is in the API reference.
Matching an order to your cart
items[].productId and items[].optionId are the same ids you sent as productId and
optionId on the cart lines, and the same as the ids from the products list. Join each order
item to your cart and your catalog on optionId without any translation. If productId is
null, the product has since left Groupon's catalog; optionId still identifies what was
bought.
Status meaning
| Status | Meaning | What to show |
|---|---|---|
| ON_HOLD | No payment has been taken yet, or it was taken but the vouchers' state could not be read yet. Normal for the first seconds after the redirect. | "Finalizing your order..." and poll again. |
| CONFIRMED | Paid. Vouchers are issued. | Success page. |
| REDEEMED | Every voucher has been used at the merchant. | Success page, marked as used. |
| REJECTED | Payment failed. No order was completed. | "Payment failed" and a link back to the cart. |
| CANCELLED | The order was cancelled or refunded. | "This order was cancelled." |
| EXPIRED | The order was not paid for in time. | "This order was not completed" and a link back to the cart. |
| PENDING | Payment is being processed, or it has been taken and the vouchers are still being issued. | "Finalizing your order..." and poll again. |
The same statuses apply at three levels: the order (status), each item (items[].status) and
each voucher (items[].unitItems[].status). The order's status is never more advanced than its
least-advanced item: one item still ON_HOLD keeps the whole order ON_HOLD, and the order
reads REDEEMED only when every item does.
Cancelled items are set aside. An item is CANCELLED once all its vouchers are, and the order
once all its items are. An order with some items cancelled takes the status of the rest, and
each cancelled voucher reads CANCELLED in unitItems.
Treat any status you do not recognize as unresolved: show it as not completed, keep the cart, and never start a new purchase because of it. This keeps your code working if a new status is added.
Polling
Right after the redirect the status is often ON_HOLD or PENDING. Poll from your server: wait
2 s, then 4 s, 8 s, 15 s, 30 s (about one minute in total). Stop as soon as the status is neither
ON_HOLD nor PENDING. If it is still ON_HOLD or PENDING after the last try, show "Your
order is being processed, you will receive a confirmation email from Groupon" together with the
voucher buttons below.
The voucher buttons
Each item's unitItems has one entry per purchased unit of that item: an item with quantity: 2
has two entries. Render the order grouped by item. For each item, show the product and option
(joined to your catalog on optionId), then for each of its unitItems render a button such as
"View voucher 1 on Groupon" whose href is that entry's myGrouponUrl.
The shopper must log in to their Groupon account to open it. That page is where they view and redeem the voucher.
An item can still be ON_HOLD or PENDING while others are CONFIRMED. Show the buttons you
have and a "still processing" note on that item.
A voucher whose status is CANCELLED was cancelled or refunded. Show it as cancelled, without a
voucher button.
Treat grouponOrderUuid as sensitive. Do not log it in analytics or expose it on public pages.
Errors
See Handling errors for the full code table. On the booking endpoint,
INVALID_BOOKING_UUID means no order with that id, or the order was not placed from one of your
carts: do not retry, show a neutral message. A booking read never changes the order, so it is
always safe to retry UPSTREAM_UNAVAILABLE with the same backoff as polling.