{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://apiv2.blizzfull.com/schema/standard-order.schema.json",
  "title": "StandardOrder",
  "description": "One restaurant order in Blizzfull's interchange format. The API returns orders in this shape, the point of sale saves them in it, and marketplace orders arrive in it.\n\nConventions:\n- Money is integer cents (USD) unless a field says otherwise. `coupons[]` is the one exception: it is internal engine state, in dollars.\n- Tax rates are percentages: `8.25` means 8.25%.\n- Times are ISO 8601 strings. Blizzfull's own orders use UTC with a `+00:00` offset; some marketplace orders omit the offset (UTC is implied). An unset time is `0000-00-00T00:00:00+00:00`.\n- Identifiers are pairs: `internal` is Blizzfull's, `external` is the point of sale's or marketplace's.\n- New fields may be added at any time. Ignore fields you don't recognise.",
  "type": "object",
  "required": ["id", "status", "type", "merchant", "customer", "items", "totals"],
  "properties": {
    "id": {
      "$ref": "#/$defs/Identifier",
      "description": "The order. `internal` is the Blizzfull order number as a numeric string (`\"2303306\"`), or `\"ex-<n>\"` for a marketplace order Blizzfull relayed. `external` is the marketplace's order ID, if any."
    },
    "status": {
      "type": "string",
      "enum": ["OPEN", "SUBMITTED", "ACCEPTED", "CANCELED", "FULFILLED"],
      "description": "Where the order is. `OPEN`: being built, not yet sent to the kitchen. `SUBMITTED`: placed, waiting for the restaurant. `ACCEPTED`: the restaurant confirmed it. `FULFILLED`: closed out. `CANCELED`: voided."
    },
    "providerStatus": {
      "type": "string",
      "description": "The marketplace's own status word, unchanged (for example `in_progress`). Empty for Blizzfull orders."
    },
    "providerOutcome": {
      "type": "string",
      "enum": ["ACTIVE", "COMPLETED", "CANCELED", "FAILED", "UNKNOWN"],
      "description": "A marketplace order's reporting outcome, kept apart from `status` (a marketplace failure still closes as `FULFILLED`). `UNKNOWN` for Blizzfull orders."
    },
    "currencyCode": {
      "type": "string",
      "enum": ["USD"],
      "description": "Always `USD`."
    },
    "note": {
      "type": "string",
      "description": "The customer's instructions for the whole order. Empty when there are none."
    },
    "createdTime": { "$ref": "#/$defs/Timestamp", "description": "When the order was started." },
    "orderedTime": { "$ref": "#/$defs/Timestamp", "description": "When the order was placed." },
    "acceptedTime": { "$ref": "#/$defs/Timestamp", "description": "When the restaurant accepted it. Unset until then." },
    "modifiedTime": { "$ref": "#/$defs/Timestamp", "description": "When the order last changed." },
    "pickupTime": {
      "$ref": "#/$defs/Timestamp",
      "description": "When the order will be ready. For Blizzfull orders this equals `deliveryTime` and the estimated ready time."
    },
    "deliveryTime": { "$ref": "#/$defs/Timestamp", "description": "When a delivery order is due. Equals `pickupTime` for Blizzfull orders." },
    "fulfillmentTime": {
      "$ref": "#/$defs/Timestamp",
      "description": "The time the customer asked for when `isFuture` is true; otherwise the estimated ready time."
    },
    "type": {
      "type": ["string", "null"],
      "enum": ["PICKUP", "DELIVERY", "DINE-IN", null],
      "description": "How the order is fulfilled. `PICKUP` covers take-out and curbside."
    },
    "sourceType": {
      "type": "string",
      "enum": ["PICKUP", "DELIVERY", "DINE-IN", "UNKNOWN"],
      "description": "The marketplace's own fulfilment type. A marketplace courier delivery arrives as `type: PICKUP` (the courier picks it up) with `sourceType: DELIVERY`. `UNKNOWN` for Blizzfull orders."
    },
    "isExternal": { "type": "boolean", "description": "True for a marketplace order Blizzfull relayed rather than took." },
    "isTest": { "type": "boolean", "description": "True for a test order. Test orders never move real money." },
    "taxRate": {
      "type": ["string", "number"],
      "description": "The order's tax rate as a percentage. Blizzfull orders send a decimal string with four places (`\"8.2500\"` is 8.25%); marketplace orders send a number. Older marketplace orders may hold a fraction (`0.1076`).",
      "examples": ["8.2500", 10.259]
    },
    "isFuture": {
      "type": "boolean",
      "description": "True when the customer scheduled the order for a later time (see `fulfillmentTime`). Stays true after that time passes."
    },
    "table": { "type": "string", "description": "The dine-in table. Empty for other orders." },
    "guestCount": {
      "type": "integer",
      "minimum": 0,
      "maximum": 255,
      "description": "The number of people in a dine-in party. 0 means not recorded."
    },
    "dineinInitTimestamp": {
      "type": "integer",
      "minimum": 0,
      "description": "When a dine-in party was seated, in Unix seconds (not ISO 8601). 0 means not recorded."
    },
    "curbside": { "type": "boolean", "description": "True when the customer asked to be served at the curb." },
    "curbsideDetails": { "type": "string", "description": "The curbside vehicle, as \"color make type\". Empty otherwise." },
    "contactFree": { "type": "boolean", "description": "True when a delivery should be left at the door." },
    "hasAlcohol": { "type": "boolean", "description": "True when the order contains alcohol, so ID must be checked on hand-off." },
    "sourcePlatform": {
      "type": "string",
      "description": "Where the order was placed. For Blizzfull orders: `web`, `app`, `kiosk`, `pos` or `phone` (a phone-ordering partner). For marketplace orders: the marketplace's name.",
      "examples": ["web", "pos", "phone"]
    },
    "pointsProvider": { "type": "string", "description": "The loyalty program the points belong to. Currently always `blizzfull`." },
    "processingVia": {
      "type": ["string", "null"],
      "enum": ["manual", "aggregation", "cash", "restaurant-gateway", "restaurant-gateway-cp", "blizzfull-pay", "", null],
      "description": "How the order's payments are processed. `manual`: recorded, not processed (unpaid, cash at the register, pay later). `cash`: cash ordered online. `aggregation` / `blizzfull-pay`: cards processed by Blizzfull. `restaurant-gateway`: the restaurant's own card processor. `restaurant-gateway-cp`: a card reader at the counter. Empty on a few older orders; null for marketplace orders."
    },
    "dailyOrderNumber": {
      "type": ["integer", "null"],
      "description": "The short number called out at the counter, restarting daily. Null when the restaurant doesn't use daily numbers."
    },
    "merchant": { "$ref": "#/$defs/Merchant" },
    "customer": { "$ref": "#/$defs/Customer" },
    "items": {
      "type": "array",
      "items": { "$ref": "#/$defs/Item" },
      "description": "The order lines, in the order they were added."
    },
    "discounts": {
      "type": "array",
      "items": { "$ref": "#/$defs/Discount" },
      "description": "Order-level coupons and discounts. Their sum need not equal `totals.discount`: a manual discount from the register has no entry here, and an applied coupon worth $0 still does."
    },
    "itemDiscounts": {
      "type": "array",
      "items": { "$ref": "#/$defs/Discount" },
      "description": "Item-level discounts, one per discounted line (also listed on the line itself under `items[].discounts`)."
    },
    "coupons": {
      "type": "array",
      "items": { "type": "object" },
      "description": "Internal state of Blizzfull's coupon engine, in dollars. Not a stable contract: use `discounts`, `itemDiscounts` and `totals` instead."
    },
    "extraCharges": {
      "type": "array",
      "items": { "$ref": "#/$defs/ExtraCharge" },
      "description": "Restaurant fees on the order (a service or bag fee), and fees that are themselves taxes. A fee attached to one payment (a card fee) is listed on that payment instead, under `transactions[].extraCharges`."
    },
    "delivery": {
      "oneOf": [{ "$ref": "#/$defs/Delivery" }, { "type": "null" }],
      "description": "Where and how a delivery order goes. Null for other orders."
    },
    "totals": { "$ref": "#/$defs/Totals" },
    "aggregator": {
      "oneOf": [{ "$ref": "#/$defs/Aggregator" }, { "type": "null" }],
      "description": "The service that relayed a marketplace order. Null for Blizzfull orders."
    },
    "transactions": {
      "type": "array",
      "items": { "$ref": "#/$defs/Transaction" },
      "description": "Every payment on the order, whatever its status: approved, authorized (held), voided and refunded ones included. Empty when nothing has been paid."
    }
  },
  "$defs": {
    "Timestamp": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|[+-]\\d{2}:\\d{2})?$",
      "description": "ISO 8601 date and time. Blizzfull orders use UTC with a `+00:00` offset; some marketplace orders omit the offset (UTC implied). `0000-00-00T00:00:00+00:00` means not set: treat it as null.",
      "examples": ["2026-10-28T19:30:00+00:00", "0000-00-00T00:00:00+00:00"]
    },
    "Identifier": {
      "type": "object",
      "description": "The same thing's ID in two systems. `internal` is Blizzfull's; `external` is the point of sale's or marketplace's.",
      "properties": {
        "internal": {
          "type": ["string", "integer", "null"],
          "description": "Blizzfull's ID. Orders, merchants, sizes and payments use numeric strings; menu items use integers."
        },
        "external": {
          "type": ["string", "null"],
          "description": "The other system's ID, or null."
        }
      }
    },
    "Merchant": {
      "type": "object",
      "description": "The restaurant location the order belongs to.",
      "required": ["id", "name", "timezone"],
      "properties": {
        "name": { "type": "string", "description": "The restaurant's name." },
        "id": { "$ref": "#/$defs/Identifier", "description": "`internal` is the Blizzfull restaurant ID, a numeric string." },
        "timezone": { "type": "string", "description": "The restaurant's IANA time zone.", "examples": ["America/Los_Angeles"] },
        "ghostLocationID": { "type": ["string", "null"], "description": "The virtual brand (ghost kitchen) a marketplace order was placed with. Null otherwise." },
        "ghostLocationName": { "type": ["string", "null"], "description": "That virtual brand's name. Null otherwise." }
      }
    },
    "Customer": {
      "type": "object",
      "description": "The person the order is for.",
      "properties": {
        "id": {
          "type": "string",
          "description": "The customer's Blizzfull account, as a numeric string. `\"5\"` is the shared guest account (no account). Empty when the order has no customer."
        },
        "name": {
          "type": "string",
          "description": "The name to call out: the name given on the order, else the account's name, email or phone, else `Customer`."
        },
        "phone": {
          "type": ["string", "boolean"],
          "description": "The order's callback number in E.164 form (`+16615550177`), or `false` when there is no usable number. Marketplace orders pass the marketplace's number through unchanged.",
          "examples": ["+16615550177", false]
        },
        "phoneExt": { "type": "string", "description": "A phone extension. Usually empty." },
        "phoneOptIn": { "type": "boolean", "description": "Reserved. Currently always false." },
        "email": {
          "type": "string",
          "description": "The account's email. Accounts created from a phone number carry a placeholder (`6615550177@#`), and guest orders show the guest account's address, so don't treat this as a deliverable address."
        },
        "emailOptIn": { "type": "boolean", "description": "Reserved. Currently always false." }
      }
    },
    "Item": {
      "type": "object",
      "description": "One order line: a menu item at a quantity, with its size and options.",
      "required": ["quantity", "id", "name", "totalPrice"],
      "properties": {
        "quantity": { "type": "integer", "minimum": 1, "description": "How many." },
        "orderItemID": {
          "type": ["integer", "null"],
          "description": "The line's number within this order (1, 2, 3…), not a global ID. Null on marketplace orders."
        },
        "checkName": { "type": "string", "description": "The guest's check the line belongs to, as `Guest N`. Empty for the shared check." },
        "checkNumber": { "type": "integer", "minimum": 0, "maximum": 255, "description": "The guest or seat number. 0 is the shared check." },
        "id": {
          "$ref": "#/$defs/Identifier",
          "description": "`internal` is the menu item ID (an integer). 0 is a custom item not on the menu; 1 is a reward with no menu item behind it. Marketplace orders send strings."
        },
        "name": {
          "type": "string",
          "description": "The line's display name, with the size name already prefixed when there is one."
        },
        "translatedName": { "type": "string", "description": "The name in a second language, on receipts that ask for one. Otherwise empty or absent." },
        "note": { "type": "string", "description": "Special instructions for this line." },
        "category": { "$ref": "#/$defs/Category" },
        "tags": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Kitchen routing tags (and `cat-<shortName>`). Filled on receipts and point-of-sale tickets; empty in API order responses."
        },
        "unitPrice": {
          "type": "integer",
          "description": "`totalPrice` divided by `quantity`, rounded to the cent, so it may not multiply back exactly. `totalPrice` is authoritative."
        },
        "totalPrice": {
          "type": "integer",
          "description": "The line total in cents: the item with its size and options, times quantity, before item discounts."
        },
        "customPrice": {
          "type": ["integer", "null"],
          "description": "A line total the cashier typed over the menu price, in cents. Null when the menu price stands."
        },
        "taxRate": { "type": "number", "description": "The line's tax rate as a percentage. 0 for tax-exempt lines." },
        "discount": { "type": "integer", "description": "The line's item-level discount in cents." },
        "size": {
          "description": "The size chosen. An empty array (`[]`) when the item has no sizes. Marketplace orders may carry a Size object with null IDs instead.",
          "oneOf": [
            { "$ref": "#/$defs/Size" },
            { "type": "array", "maxItems": 0 }
          ]
        },
        "discounts": {
          "type": "array",
          "items": { "$ref": "#/$defs/Discount" },
          "description": "The line's item-level discounts."
        },
        "modifiers": {
          "type": "array",
          "items": { "$ref": "#/$defs/Modifier" },
          "description": "The options on the line, ready to print. For the exact choices (with IDs), use `optionSelections`."
        },
        "optionSelections": {
          "description": "Exactly which options were chosen, by ID. This is the authoritative record of a line's customization, and the shape you send when you create an order. Null when nothing was chosen beyond the defaults, and on receipts.",
          "oneOf": [
            { "type": "array", "items": { "$ref": "#/$defs/OptionGroupSelection" } },
            { "type": "null" }
          ]
        },
        "pointsUsed": { "type": "integer", "minimum": 0, "description": "Loyalty points spent on this line." },
        "loyaltyItemID": { "type": "integer", "description": "The loyalty reward this line redeems. 0 when it isn't a reward." },
        "giftCard": { "type": "boolean", "description": "True when the line sells gift-card value." },
        "giftCardActivationReference": {
          "type": "string",
          "description": "A signed reference used to activate a physical gift card, never the card number. Empty otherwise."
        }
      }
    },
    "OptionGroupSelection": {
      "type": "object",
      "description": "The choices made in one option group of an item.",
      "required": ["optionGroupId", "selections"],
      "properties": {
        "optionGroupId": {
          "type": ["string", "integer"],
          "description": "The option group's `linkageID` on this item, from the menu feed (`fooditems[].options[].linkageID`)."
        },
        "selections": {
          "type": "array",
          "items": { "$ref": "#/$defs/OptionItemSelection" }
        }
      }
    },
    "OptionItemSelection": {
      "type": "object",
      "description": "One option's state. List only what differs from the menu's defaults: an option that is on by default stays on unless you send `selected: 0`.",
      "required": ["optionItemId", "selected"],
      "properties": {
        "optionItemId": {
          "type": ["string", "integer"],
          "description": "The option's `id`, from the menu feed (`options[].items[].id`)."
        },
        "selected": {
          "type": ["integer", "string"],
          "description": "0 turns the option off. 1 or more turns it on: the count for a stepper group, or the level for a variable-amount group (1 light, 2 regular, 3 extra). Usually an integer; a few older orders hold a numeric string."
        },
        "included": {
          "type": "boolean",
          "description": "True when the option is one of the group's free (included) choices. Present only when true."
        },
        "subOptionSelections": {
          "type": "array",
          "items": { "$ref": "#/$defs/SubOptionGroupSelection" },
          "description": "Choices inside the nested groups this option opens (choosing Burger opens Cooking temperature). Options nest two levels at most."
        }
      }
    },
    "SubOptionGroupSelection": {
      "type": "object",
      "description": "The choices made in a nested group.",
      "required": ["optionGroupId", "selections"],
      "properties": {
        "optionGroupId": {
          "type": ["string", "integer"],
          "description": "The nested group's `id`, from the menu feed (`subOptions[].id`). Nested groups have no `linkageID`."
        },
        "selections": {
          "type": "array",
          "items": { "$ref": "#/$defs/SubOptionItemSelection" }
        }
      }
    },
    "SubOptionItemSelection": {
      "type": "object",
      "description": "One option's state in a nested group. It cannot open further groups.",
      "required": ["optionItemId", "selected"],
      "properties": {
        "optionItemId": { "type": ["string", "integer"], "description": "The option's `id` in the nested group." },
        "selected": { "type": ["integer", "string"], "description": "0 off; 1 or more on (see `OptionItemSelection.selected`)." },
        "included": { "type": "boolean", "description": "True when the option is one of the group's free choices." }
      }
    },
    "Modifier": {
      "type": "object",
      "description": "One option on a line, as it prints.",
      "properties": {
        "quantity": {
          "type": ["integer", "string"],
          "description": "The selection value per unit of the item (see `OptionItemSelection.selected`)."
        },
        "id": {
          "$ref": "#/$defs/Identifier",
          "description": "The option's ID when known. Matched to the option by position, so it can be wrong for items with default options; rely on `optionSelections` for IDs."
        },
        "name": {
          "type": "string",
          "description": "Ready to print, prefixes included (`No Onions`, `Extra Ranch`, `2x Ranch`). Don't add the quantity again."
        },
        "translatedName": { "type": "string", "description": "The name in a second language, on receipts that ask for one." },
        "note": { "type": "string", "description": "Reserved. Currently always empty." },
        "group": { "$ref": "#/$defs/ModifierGroup", "description": "The option group the choice belongs to." },
        "food_group": {
          "$ref": "#/$defs/ModifierGroup",
          "description": "The part of a multi-part item the option belongs to, such as `1st Half` of a pizza. Its name is the item's name when the item has one part."
        },
        "unitPrice": { "type": "integer", "description": "The option's price in cents. 0 on Blizzfull orders, whose option prices are inside the line's `totalPrice`; marketplace orders fill it." },
        "totalPrice": { "type": "integer", "description": "`unitPrice` times `quantity`, in cents. 0 on Blizzfull orders." },
        "taxRate": { "type": "number", "description": "The option's tax rate as a percentage." },
        "modifiers": {
          "type": "array",
          "items": { "$ref": "#/$defs/Modifier" },
          "description": "Options chosen inside a nested group. One level deep."
        }
      }
    },
    "ModifierGroup": {
      "type": "object",
      "description": "A named group with an ID.",
      "properties": {
        "name": { "type": "string", "description": "The group's name, when known. Empty in API order responses." },
        "translatedName": { "type": "string" },
        "id": {
          "$ref": "#/$defs/Identifier",
          "description": "`internal` is the group's `linkageID` on the item (a string), or null when unknown."
        }
      }
    },
    "Category": {
      "type": "object",
      "description": "The line's menu category. Filled on receipts and point-of-sale tickets; empty in API order responses.",
      "properties": {
        "name": { "type": "string" },
        "translatedName": { "type": "string" },
        "shortName": { "type": "string", "description": "The category's short name, used to route tickets to printers." },
        "id": { "$ref": "#/$defs/Identifier" }
      }
    },
    "Size": {
      "type": "object",
      "description": "The size variant chosen.",
      "properties": {
        "name": { "type": "string", "examples": ["Medium 12\""] },
        "translatedName": { "type": "string" },
        "id": { "$ref": "#/$defs/Identifier", "description": "`internal` is the size ID, a numeric string, or null." },
        "price": { "type": "integer", "description": "Reserved. Currently always 0: the size's price is inside the line's `totalPrice`." }
      }
    },
    "Discount": {
      "type": "object",
      "description": "A coupon or discount and what it took off, in cents.",
      "properties": {
        "name": { "type": "string" },
        "amount": { "type": "integer", "description": "What it took off, in cents. Positive." },
        "id": { "$ref": "#/$defs/Identifier", "description": "`internal` is the coupon ID (a numeric string) when it is a Blizzfull coupon." },
        "description": { "type": ["string", "null"] },
        "itemID": { "type": ["integer", "null"], "description": "Reserved. Currently always null." },
        "pointsUsed": { "type": ["integer", "string"], "description": "Loyalty points spent on the discount. Usually an integer." }
      }
    },
    "ExtraCharge": {
      "type": "object",
      "description": "A restaurant fee, or a fee that is itself a tax.",
      "properties": {
        "name": { "type": "string" },
        "id": { "$ref": "#/$defs/Identifier", "description": "`internal` is the fee's name." },
        "amount": { "type": "integer", "description": "The fee in cents." },
        "isTax": { "type": "boolean", "description": "True when the fee is a tax (and counts as tax on receipts)." },
        "taxRate": { "type": "number", "description": "The percentage the fee is taxed at; 0 when it isn't taxed." },
        "isPercentage": { "type": "integer", "description": "Reserved. Currently always 0; `amount` is already in cents." },
        "taxed": { "type": "boolean", "description": "True when tax is charged on the fee." }
      }
    },
    "Totals": {
      "type": "object",
      "description": "The order's money, in cents. `total = subtotal - discount + deliveryFee + tax + tip + extraCharge`.",
      "required": ["subtotal", "tax", "total", "paid", "balanceOwed"],
      "properties": {
        "subtotal": { "type": "integer", "description": "The lines' total after item-level discounts." },
        "tip": { "type": "integer", "description": "Tips, including tips added after payment." },
        "extraCharge": { "type": "integer", "description": "All fees, including those attached to a payment." },
        "deliveryFee": { "type": "integer" },
        "tax": { "type": "integer" },
        "dspWithheldTax": { "type": "integer", "description": "The part of `tax` a delivery marketplace collected and remits itself. Already included in `tax`. 0 for Blizzfull orders." },
        "total": { "type": "integer", "description": "What the order costs." },
        "discount": { "type": ["integer", "null"], "description": "Order-level discounts only (item-level ones are already out of `subtotal`). Some marketplace orders send null for none." },
        "paid": { "type": "integer", "description": "What has been paid. 0 for cash ordered online, which is collected on hand-off." },
        "balanceOwed": { "type": "integer", "description": "What is still owed. 0 when paid in full or canceled; negative when overpaid." }
      }
    },
    "Delivery": {
      "type": "object",
      "description": "Where a delivery order goes, and who is taking it.",
      "properties": {
        "address": { "type": "string", "description": "Street address." },
        "unit": { "type": "string", "description": "Apartment, suite or unit. Empty when none." },
        "city": { "type": "string" },
        "state": { "type": "string", "description": "Two-letter state code." },
        "zip": { "type": "string" },
        "full": { "type": "string", "description": "The whole address on one line, as \"address unit city, state  zip\"." },
        "country": { "type": "string", "description": "Two-letter country code. `US` for Blizzfull orders." },
        "courier": {
          "oneOf": [{ "$ref": "#/$defs/Courier" }, { "type": "null" }],
          "description": "The delivery service taking the order, or null when the restaurant delivers it."
        },
        "geo": { "$ref": "#/$defs/Geocode" },
        "notes": { "type": "string", "description": "Delivery instructions. Usually empty here: instructions are in the order's `note`." },
        "distance": { "type": ["string", "number"], "description": "Distance from the restaurant, as a decimal string (`\"4.9\"`)." }
      }
    },
    "Courier": {
      "type": "object",
      "description": "The delivery service or driver.",
      "properties": {
        "name": { "type": "string", "description": "Often the service's name (`Doordash`, `Uber`) rather than a person's." },
        "phone": { "type": ["string", "boolean"], "description": "The courier's phone in E.164 form, or `false` when there is none." },
        "phoneExt": { "type": "string" },
        "email": { "type": "string", "description": "Reserved. Currently always empty." },
        "status": {
          "type": "string",
          "enum": ["WAITING", "ACCEPTED", "TRANSIT_TO_MERCHANT", "TRANSIT_TO_CUSTOMER", "DELIVERED", "CANCELLED", ""],
          "description": "Where the courier is. Empty when unknown."
        },
        "geo": { "oneOf": [{ "$ref": "#/$defs/Geocode" }, { "type": "null" }], "description": "Reserved. Currently always null." },
        "trackingUrl": { "type": "string", "description": "A live tracking page, when the service provides one." }
      }
    },
    "Geocode": {
      "type": "object",
      "description": "A point, in decimal degrees.",
      "properties": {
        "lat": { "type": "number" },
        "lng": { "type": "number" }
      }
    },
    "Aggregator": {
      "type": "object",
      "description": "The service that relayed a marketplace order.",
      "properties": {
        "name": { "type": "string", "examples": ["Stream"] },
        "id": { "$ref": "#/$defs/Identifier", "description": "`internal` identifies the integration; `external` is the source order's ID." }
      }
    },
    "Transaction": {
      "type": "object",
      "description": "One payment. Amounts are cents and stay positive for refunds: `action` and `status` say what happened.",
      "properties": {
        "type": {
          "type": "string",
          "enum": ["CASH", "CARD", "PAYPAL", "GIFTCARD", "MANUAL", "OTHER"],
          "description": "The tender. `CARD` is any card payment; `MANUAL` is one recorded without a processor."
        },
        "amount": { "type": "integer", "description": "The amount, in cents, tip included." },
        "tax": { "type": "integer", "description": "The tax this payment covered." },
        "tip": { "type": "integer", "description": "The tip in this payment." },
        "cashTip": { "type": "boolean", "description": "True when the tip was paid in cash." },
        "delivery": { "type": "integer", "description": "The delivery fee this payment covered." },
        "discounts": { "type": "integer", "description": "The discounts applied to this payment." },
        "processedBy": {
          "type": "string",
          "description": "The processor, lowercased (`finix`, `braintree`, `paypal`, `cash`, `manual`…).",
          "examples": ["finix", "cash"]
        },
        "externalPaymentService": {
          "type": "string",
          "enum": ["none", "applepay", "googlepay"],
          "description": "The wallet the card came through."
        },
        "canChargeAgain": { "type": "boolean", "description": "True when the card can be charged again for what the order still owes." },
        "cardBrand": {
          "type": ["string", "null"],
          "description": "The card network, or null.",
          "examples": ["visa", "mastercard", "amex", "discover"]
        },
        "last4": { "type": ["string", "null"], "description": "The card's last four digits, or null." },
        "id": { "$ref": "#/$defs/Identifier", "description": "`internal` is the payment ID, a numeric string." },
        "status": {
          "type": ["string", "null"],
          "enum": ["APPROVED", "AUTHORIZED", "VOIDED", "REFUNDED", null],
          "description": "`AUTHORIZED`: held on the card, not yet captured. `APPROVED`: taken. `VOIDED` / `REFUNDED`: reversed."
        },
        "action": { "type": "string", "enum": ["sale", "refund"], "description": "Whether the payment took money or returned it." },
        "description": { "type": ["string", "null"], "description": "A note from the source, such as `Stream transaction`." },
        "items": {
          "type": "array",
          "description": "When a payment covers particular lines (a split check), which lines.",
          "items": {
            "type": "object",
            "properties": {
              "orderItemID": { "type": "integer", "description": "The line's `orderItemID`." },
              "amount": { "type": ["integer", "null"], "description": "The part of the line paid, in cents; null means all of it." }
            }
          }
        },
        "itemSplitData": {
          "type": ["object", "null"],
          "description": "For an item or guest split, `{version: 1, allocations: [{orderItemID, amount}]}`. Null otherwise."
        },
        "pointsEarned": { "type": ["string", "integer"], "description": "Loyalty points the payment earned. A numeric string on Blizzfull orders." },
        "receiptData": {
          "type": ["object", "array", "null"],
          "description": "Lines printed on the card receipt. Keys starting with `_` are not for the customer."
        },
        "totals": {
          "oneOf": [{ "$ref": "#/$defs/Totals" }, { "type": "null" }],
          "description": "This payment's money broken down like the order's. Null on marketplace orders."
        },
        "extraCharges": {
          "type": "array",
          "description": "Fees attached to this payment, such as a card fee.",
          "items": {
            "type": "object",
            "properties": {
              "name": { "type": "string" },
              "amount": { "type": "number", "description": "Cents for a `flat` fee; the configured rate for a `percentage` fee." },
              "calculatedAmountCents": { "type": "integer", "description": "What the fee came to, in cents." },
              "type": { "type": "string", "enum": ["flat", "percentage"] },
              "taxed": { "type": "boolean" },
              "isTax": { "type": "boolean" }
            }
          }
        }
      }
    }
  }
}
