unPLUGDevelopers

Orders and refunds API

Create an order

POST/v1/orders

Credits a paid order: the member earns points, and every redemption in redemption_ids is captured. Send it once payment is captured, not when the order is placed, so a declined card never earns.

Permissions: Secret key with checkout:write.

Request headers#

  • Idempotency-KeystringRequired
    Required on this endpoint. Any string up to 255 characters; use a UUID v4. Missing returns 400 idempotency_key_required.
    Max Length 255

Request body#

  • external_order_idstringRequired
    Your order id, up to 128 characters. Unique in your brand forever.
    Max Length 128
  • member_idstring (uuid)
    Leave it out for a guest order. It is recorded but earns nothing.
  • location_idstring (uuid)Required
  • channelstringRequired
    app or web.
    One of app, web
  • fulfillmentstringRequired
    pickup, delivery, curbside or dine_in.
    One of pickup, delivery, curbside, dine_in
  • currencystringRequired
    USD.
  • subtotal_centsintegerRequired
    Before discounts, tax and tip.
    Min 0
  • itemsarray of CartItemRequired
    Show attributesCartItem
    • line_idstringRequired
      Your id for the line, unique within the cart.
    • pos_item_idstring
      Square catalog item variation id.
    • namestringRequired
    • quantityintegerRequired
      Min 1
    • unit_price_centsintegerRequired
      Integer cents.
      Min 0
    • pos_category_idsarray of string
    • modifiersarray of object
      Show attributesHide attributes
      • pos_modifier_idstring
      • namestring
      • price_centsinteger
        Integer cents.
        Min 0
  • placed_atstring (date-time)Required
    RFC 3339 time the guest placed the order.
  • discount_centsintegerRequired
    All discounts. 0 if none.
    Min 0
  • tax_centsintegerRequired
    Integer cents.
    Min 0
  • tip_centsintegerRequired
    0 if none.
    Min 0
  • total_centsintegerRequired
    What the guest paid.
    Min 0
  • redemption_idsarray of string (uuid)
    The reserved redemption this order uses. One at launch.
    Max Items 1
  • attributionobjectComing soon
    Coming soon.
    Show attributesHide attributes
    • link_idstring
      Coming soon The tracked link that brought the guest, from an unPLUG message.

The subtotal after discounts is $12.50 minus $3.50, so $9.00. At 10 Beans per dollar that is 90 Beans. Maya goes from 420 to 510 Beans, and the wallet item is used. member is a snapshot right after the order. It's on this response and in the order.credited webhook, but not when you read the order later. Webhooks order.credited, points.changed and reward.redeemed fire.

Response fields#

Returns 201 with Order

  • idstring (uuid)
    unPLUG's id for the order.
  • external_order_idstringNullable
    Your order id. Unique in your brand, forever.
  • statusstring
    credited, partially_refunded or refunded. See Order statuses.
    One of credited, partially_refunded, refunded
  • member_idstring (uuid)Nullable
    null for a guest order, which earns nothing.
  • location_idstring (uuid)
  • channelstring
    app or web for orders you send. Points earned at the register also show up, as orders with in_store. May grow.
    One of app, web, in_store
  • fulfillmentstringNullable
    pickup, delivery, curbside or dine_in.
  • placed_atstring (date-time)
    When the guest placed the order. The earn rate and bonuses in force at this time apply.
  • currencystring
    USD.
  • subtotal_centsinteger
    Sum of the lines, before discounts, tax and tip.
    Min 0
  • discount_centsinteger
    All discounts on the order, including the unPLUG redemption.
    Min 0
  • tax_centsinteger
    Recorded for reports. They never earn.
    Min 0
  • tip_centsinteger
    Recorded for reports. They never earn.
    Min 0
  • total_centsinteger
    What the guest paid: subtotal minus discount, plus tax and tip.
    Min 0
  • itemsarray of CartItem
    The cart lines, same shape as preview.
    Show attributesCartItem
    • line_idstring
      Your id for the line, unique within the cart.
    • pos_item_idstring
      Square catalog item variation id.
    • namestring
    • quantityinteger
      Min 1
    • unit_price_centsinteger
      Integer cents.
      Min 0
    • pos_category_idsarray of string
    • modifiersarray of object
      Show attributesHide attributes
      • pos_modifier_idstring
      • namestring
      • price_centsinteger
        Integer cents.
        Min 0
  • points_earnedinteger
    Points from the earn rate, on the subtotal after discounts, rounded down.
  • bonus_pointsinteger
    Extra points from promotions in force at placed_at.
  • redemptionsarray of object
    [{ "id", "status" }] for each redemption the order used.
    Show attributesHide attributes
    • idstring (uuid)
    • statusstring
  • memberobjectNullable
    { "points_balance", "tier" } right after the order was credited. Only on the create response and the order.credited webhook.
    Show attributesHide attributes
    • points_balanceinteger
    • Show attributesTierRef
      • idstring (uuid)
      • namestring
  • created_atstring (date-time)
    When unPLUG recorded the order.

Retries and duplicates#

  • Timeout or 5xx. Send the same body with the same Idempotency-Key. You get the original response, with Idempotent-Replayed: true.
  • Retry after 24 hours, or with a new key. external_order_id still blocks a second credit: you get 409 order_already_exists with the existing order's id. Treat it as success.
  • Expired hold. If a redemption in redemption_ids is unknown, canceled or expired, the whole request fails with 422 redemption_expired and nothing is written. The guest has already paid the discounted price, so decide your policy: send the order without redemption_ids so it still earns, then reconcile the discount.
Response409
{
  "type": "https://docs.unplugdining.com/reference/errors#order_already_exists",
  "title": "Order already exists",
  "status": 409,
  "code": "order_already_exists",
  "detail": "An order with external_order_id app-30417 already exists.",
  "param": "external_order_id",
  "order_id": "c9e5a3f1-7d2b-4e8c-a0f6-3b1d9e5c7a24",
  "request_id": "req_7Hq2kD9xLm"
}

Coming soon Guests who order without signing in will be able to claim the order's points later.

Error descriptions#

400Bad request
idempotency_key_required

The Idempotency-Key header is missing.

400Bad request
missing_param

, 400 invalid_param A required field is missing or has the wrong format. param names it.

404Not found
member_not_found

, 404 location_not_found An id doesn't exist in your brand.

409Conflict
order_already_exists

This external_order_id was already credited.

409Conflict
request_in_progress

A request with this key is still running. Retry after a second.

410Gone
member_deleted

The member was deleted. Send the order without member_id.

422Unprocessable
redemption_expired

A redemption is unknown, canceled or expired. Nothing was written.

422Unprocessable
one_redemption_per_order

redemption_ids has more than one id.

422Unprocessable
idempotency_key_reused

This key was used with a different body.

Any endpoint can also return the common errors.