Nexus Gateway
EnglishRomână
OpenAPI

An order is a priced cart plus your own order ID, the customer’s contact details and how the order is paid. The connection ID in the URL decides which location receives it.

Build the request

FieldYour responsibility
external_order_idGenerate once per purchase, persist before submission, and keep unchanged during retries. Maximum 100 ASCII letters, digits, underscores or hyphens.
menu_revisionUse the exact revision used to price this cart.
customerName and phone. No other customer details are accepted.
items1–100 lines, each with a published product ID, integer quantity from 1–99 and distinct selections.
totalGrand total in bani after published promotions and any checkout coupon; include deposits, packaging, staff tip and delivery fee when applicable.
notesUp to 1,000 characters for the order. Each line also accepts notes up to 500 characters.

Send JSON with Content-Type: application/json. The request body limit is 4 MiB. Unknown fields are rejected. See the schema reference for all field limits and defaults.

Pickup or delivery

Pickup: set fulfillment: "pickup", omit address or send null, and do not add a delivery fee.

Delivery: set fulfillment: "delivery", provide address.city and address.street, optionally add address.details, and include the menu’s fixed delivery fee once. Delivery zones and address eligibility remain your website/restaurant’s responsibility; the API has no delivery quotation or driver booking endpoint.

Declare how payment is collected

MethodWhen to use itReference
paid_onlineYour payment provider has confirmed collection for this purchase.Required, non-empty, maximum 200 characters.
cash_on_fulfillmentThe restaurant collects cash on pickup/delivery.Omit or null.
card_on_fulfillmentThe restaurant collects payment through its terminal.Omit or null.
The gateway does not charge a card. Online payment is a trusted declaration from your backend. Confirm it with your payment provider before sending paid_online. Never send card numbers, security codes or payment credentials.

All incoming Website orders are treated as paid in Retail, including cash and card on fulfillment. Send the actual payment method: cash_on_fulfillment maps to Retail Cash, card_on_fulfillment to CardPOS, and paid_online to ModernPayment. No separate paid/unpaid field is required. Acceptance records the receipt under that method without another Register collection step or terminal charge. This Retail convention does not prove customer payment: your website, restaurant or courier remains responsible for actual collection. Order status describes preparation and delivery.

Handle payment and order outcomes separately

A captured payment does not guarantee the restaurant will accept the order. Agree how your business handles rejection, cancellation and refunds, and communicate that to customers. Capture, voids and refunds remain with your payment provider. Use the refund reporting endpoint to record its final outcome in Nexus.

After a timeout, keep the original payment reference and order payload. Do not capture another payment or generate another order ID to recover. Resolve the submission using the retry protocol.

Interpret the response correctly

  • 201 Created: the restaurant has received the order. Its status is pending_acceptance until staff accept or reject it.
  • 200 OK: a completed identical replay returns the original intake receipt.
  • 503 or a timeout: you don’t know whether the restaurant received it. Resend the same request; never create a new order ID.

Once intake is confirmed, receive progress through webhooks. Use GET /v1/connections/{connection_id}/orders/{external_order_id} to reconcile current state after missed notifications or when webhooks are unavailable. Do not use repeated POSTs to poll progress.

Complete request examples

Pickup · pizza paid online 37.00 RON
order-pickup.json
{
  "external_order_id": "shop-1001",
  "menu_revision": "example-menu-1",
  "currency": "RON",
  "fulfillment": "pickup",
  "customer": {
    "name": "Example Customer",
    "phone": "0700000000"
  },
  "payment": {
    "method": "paid_online",
    "reference": "payment-example-1001"
  },
  "items": [
    {
      "product_id": "pizza-margherita",
      "quantity": 1,
      "modifiers": [
        {
          "group_id": "pizza-extras",
          "option_id": "cheese"
        }
      ],
      "notes": "Please slice the pizza"
    }
  ],
  "total": 3700,
  "notes": "Pickup by Alex"
}
Delivery · two bundle meals, cash 74.00 RON
order-delivery.json
{
  "external_order_id": "shop-1002",
  "menu_revision": "example-menu-1",
  "currency": "RON",
  "fulfillment": "delivery",
  "customer": {
    "name": "Example Customer",
    "phone": "0700000000"
  },
  "address": {
    "city": "Iași",
    "street": "Example Street 10",
    "details": "Apartment 2, ring the bell"
  },
  "payment": {
    "method": "cash_on_fulfillment"
  },
  "items": [
    {
      "product_id": "burger-meal",
      "quantity": 2,
      "modifiers": [
        {
          "group_id": "size",
          "option_id": "large"
        },
        {
          "group_id": "drink",
          "option_id": "water"
        },
        {
          "group_id": "meal-extras",
          "option_id": "sauce"
        }
      ]
    }
  ],
  "total": 7400
}

Scheduled fulfillment

Scheduled orders are always supported (scheduling.enabled is true). Send scheduled_for as an ISO 8601 timestamp with an explicit offset. Omit it for immediate fulfillment. There is no minimum notice or maximum advance limit; the website chooses the requested time. The gateway checks opening hours, holiday overrides and product schedules at the requested time, and current stock and manual pauses at submission. A menu that is closed now may still accept a valid future slot.

The order still waits for staff acceptance. Acceptance records estimated_ready_at; if staff accept late, this can be later than the requested time. Follow the returned estimate rather than promising the requested time as a guarantee. Retrying an already reserved order preserves its original timestamp and prices, even after the booking window changes.

For a scheduled slot, read GET /v1/connections/{connection_id}/menu?fulfillment_at=2026-12-25T12%3A00%3A00%2B02%3A00 using a timestamp within the current booking window. URL-encode the offset. The returned flags reflect that slot while stock and manual pauses remain current. Send the same instant as scheduled_for in the order.

Customer cancellation

Call POST /v1/connections/{connection_id}/orders/{external_order_id}/cancel with {"request_id":"cancel-123","reason":"customer_request"}. Reasons are customer_request, duplicate, ordered_by_mistake or other. Save the request ID and body before sending; retry them unchanged after a timeout or 503.

Immediate orders can be cancelled before acceptance. Accepted scheduled orders can be cancelled strictly before the saved preparation start time, only while still waiting for preparation. At or after that time, or once preparation starts, ask the restaurant to approve cancellation in Retail. Completed orders cannot be cancelled. Retry the identical request after a timeout or 503; 409 cancellation_not_allowed means the order is no longer eligible. Existing receipts remain for staff reconciliation in Nexus ERP, and online refunds remain the website’s responsibility.

Courier and delivery updates

For delivery orders, call POST /v1/connections/{connection_id}/orders/{external_order_id}/delivery with {"request_id":"courier-1","status":"assigned","courier_name":"Example courier"}. Assign a courier after acceptance; optionally report arrived. Report picked_up only when the restaurant marks the order ready, then delivered. These update the Retail delivery state without collecting payment.

Optional courier_phone, estimated_pickup_at and estimated_delivery_at support handoff coordination. Estimates require an explicit offset. Omitted values preserve previous data. Courier contacts are visible to restaurant staff, but excluded from public status and webhook payloads. Use a new request ID for each change, at most 100 per order; retry identical IDs and bodies after an uncertain result. Replays return current progress and never move it backwards.

Scheduled kitchen tickets print on acceptance with the scheduled time. The Kitchen display holds the order until its preparation time.

Report refunds performed by your provider

After your payment provider returns a final refund outcome, call POST /v1/connections/{connection_id}/orders/{external_order_id}/refunds with {"request_id":"refund-1","processor_reference":"provider-refund-1","outcome":"succeeded","amount":1200}. Outcomes are succeeded or failed. Use a unique processor reference per order and a stable request ID; retries must repeat the same body. A failed refund is final for that reference; a new attempt uses new IDs. Only paid_online orders qualify, including completed, rejected or cancelled orders. At most 100 reports are retained per order, and successful amounts may not exceed the original total.

This endpoint records your declaration. Nexus does not contact the processor, move money, verify success, cancel the order or reverse its fiscal receipt. Arrange any required fiscal reconciliation with the restaurant. Status exposes refund.reported_refunded_amount, the sum of reported successful refunds. Processor references are excluded from status and webhooks.

Nexus GatewayWebsite Ordering API · v1.0.0

Type to search the integration guides.