PIZZA FASHION · DEVELOPER DOCUMENTATION
Каталог и поръчки.
Една интеграция.
Актуално меню към вашата платформа. Поръчки от вашата платформа към Pizza Fashion. Всички полета, опции и примери на едно място.
https://api.pizzafashion.bg/v1Езикът се отнася за документацията. JSON ключовете не се превеждат; имената на ястията и някои съобщения от ресторанта остават на български.
Бърз старт
Интеграцията е сървър към сървър. Каталогът се изтегля от вас; поръчките се изпращат към нас. Няма endpoint за промяна на нашите продукти.
- Получете отделни API ключ и парола от Pizza Fashion. Ключът е Basic username, паролата е Basic password.
- Изтеглете всички страници на /catalogue и прочетете /availability.
- Създайте items + choice и извикайте /quote. Покажете крайната цена на клиента.
- След потвърждение изпратете /orders със същите items/choice, quote_token и постоянен external_order_id.
- Запазете order_number. Следете само своите поръчки чрез /orderstatus.
Използвайте HTTPS с проверка на сертификата, Accept: application/vnd.api+json и Content-Type: application/json за POST. Максимален JSON body: 128 KiB. Не следвайте автоматично redirect с данните за достъп.
Всички заявки, включително каталогът, изискват удостоверяване. Успехът е HTTP 200 с данни в meta.data. Грешките от нашия контролер са в meta.error; gateway/маршрутизацията може да върнат друг JSON формат или текст. Първо проверявайте HTTP статуса.
export PF_API_KEY='<API_KEY>'
export PF_API_PASSWORD='<API_PASSWORD>'
curl --fail-with-body --user "$PF_API_KEY:$PF_API_PASSWORD" \
--header 'Accept: application/vnd.api+json' \
'https://api.pizzafashion.bg/v1/catalogue?page=1'{
"meta": {
"data": {
"currency": "EUR",
"page": 1,
"has_more": true
}
}
}/catalogue?page=1Продукти: изтегляне и синхронизация
Единственият query параметър е page: цяло число 1–10000, по подразбиране 1. Връщат се до 50 продукта. Четете до has_more=false. Категориите и комботата може да се повтарят на всяка страница: обединявайте по id/code.
Показвайте карти само за listed=true. Запазете listed=false записи, защото choices може да сочи към тях. available=false означава, че продуктът не може да се поръча; наличностите и изтеклите комбота се проверяват отново на сървъра.
Синхронизирайте приблизително веднъж в минута в рамките на лимита. Заменяйте локалния каталог само след успешен пълен цикъл. Продукти, които вече липсват от пълния каталог, се скриват. При непълен/неуспешен цикъл пазете последното успешно копие.
Цената на размера е variants[].minor, а не разлика спрямо основната цена. Цената на добавките се взема от variants[].addons за избрания размер. Избор на вкус/разфасовка в choices означава друг product_id, със собствена рецепта и цена.
curl --fail-with-body --user "$PF_API_KEY:$PF_API_PASSWORD" \
--header 'Accept: application/vnd.api+json' \
'https://api.pizzafashion.bg/v1/catalogue?page=2'/availabilityЗони, получаване и плащане
Отговорът съдържа зони, обект за вземане и ordering_enabled за текущия партньор. Този флаг не означава, че всяка зона е отворена сега. Работните часове са Europe/Sofia; точните минимуми, късни режими, почивни дни и такси се налагат от /quote.
За доставка: fulfilment=delivery + zone_id от отговора. За вземане: fulfilment=pickup + location_id=main. Не сменяйте зоната/начина, за да заобиколите минимум или работно време.
Тази версия приема само payment=cash — в брой при доставка или вземане. Не се плаща онлайн през API и няма такса за обработка. POS при получаване не е отделен поддържан API метод и изисква отделно договаряне.
Не се приемат промокодове, FASHION, лични ваучери, външни цени или paid=true. Комбо намаленията вече са в цените. Не се предоставя достъп до клиентската база, Club профили, точки или поръчки от други канали.
curl --fail-with-body --user "$PF_API_KEY:$PF_API_PASSWORD" \
--header 'Accept: application/vnd.api+json' \
'https://api.pizzafashion.bg/v1/availability'/quoteЦена и продуктови опции
Подайте items и choice. Отговорът съдържа quote.total_minor, quote_token и expires_at. Офертата не създава поръчка, не резервира наличност и не таксува. Изтича след около 15 минути; при промяна на цена/състав/условия поискайте нова и потвърдете с клиента.
Обикновен продукт: type=product, product_id и size от каталога. removed е масив от разрешени за премахване ingredient.id; addons е масив от кодове за добавки; base е един код за основа. Инициализирайте crust от crust_included и го променяйте само при crust_selectable=true.
Комбо: копирайте combos[].default_selection с code/revision и подредените items. Сменяйте product_id само в рамките на slot.product_ids, запазете размера и броя. Не добавяйте quantity в комбо позициите. Модификациите може да увеличат крайната цена.
50/50: само ако half.enabled=true и двете пици са half_eligible с family вариант. Изпратете точно две halves с product_id, size=family и removed; общият base е на външния selection. Добавки и смяна на борд за половините не се конфигурират тук. Крайната цена идва от /quote.
Запазете оригиналните items и choice. Не използвайте quote.items[].configuration вместо request.selection: отговорът съдържа полета само за четене, които API отхвърля във входяща заявка.
{
"items": [
{
"selection": {
"type": "product",
"product_id": 123,
"size": "medium",
"removed": [],
"crust": 0,
"addons": []
},
"quantity": 1
}
],
"choice": {
"fulfilment": "pickup",
"location_id": "main",
"payment": "cash"
}
}
curl --fail-with-body --user "$PF_API_KEY:$PF_API_PASSWORD" \
--header 'Accept: application/vnd.api+json' \
--header 'Content-Type: application/json' \
--data-binary @quote-request.json \
'https://api.pizzafashion.bg/v1/quote'{
"type": "product",
"product_id": 123,
"size": "family",
"removed": [
17
],
"crust": 1,
"addons": [
"garlic_sauce"
],
"base": "tomato"
}{
"type": "combo",
"combo_code": "combo-example",
"combo_revision": "<revision-from-catalogue>",
"items": [
{
"product_id": 123,
"size": "medium",
"removed": [],
"crust": 0,
"addons": []
},
{
"product_id": 124,
"size": "standard",
"removed": [],
"crust": 0,
"addons": []
}
]
}{
"type": "half",
"halves": [
{
"product_id": 123,
"size": "family",
"removed": []
},
{
"product_id": 125,
"size": "family",
"removed": [
17
]
}
],
"base": "tomato"
}{
"meta": {
"data": {
"quote": {
"currency": "EUR",
"total_minor": 790,
"delivery_minor": 0,
"schedule_ready": true
},
"quote_token": "<signed-token>",
"expires_at": "2026-10-18T12:15:00Z"
}
}
}/ordersПоръчки: изпращане към ресторанта
Това е обратното наливане: вашата платформа създава поръчка в нашата администрация. Изпратете external_order_id, оригиналните items/choice, customer, expected_total_minor от офертата и quote_token. Не се изпращат price, source, user_id, status или данни за карта.
external_order_id е постоянният ви ключ срещу дублиране. Създайте и съхранете номера преди първата HTTP заявка. Един и същ номер с идентични данни връща същия PF номер и replayed=true. Същият номер с променени данни връща409. Редът на масивите е значим; запазете тялото на заявката.
След timeout не създавайте нов номер. Проверете /orderstatus и повторете първоначалната заявка със същия ID и данни при нужда.404 сам по себе си не доказва провал на заявка, която още се обработва. При вече записана заявка точният повторен опит може да се възобнови и с изтекъл токен; това не разрешава нова поръчка с изтекла оферта.
Име и пълен телефон са задължителни. Изпратете истинския имейл на клиента, когато е наличен; ресторантът може да го изисква. При доставка са нужни улица, номер и уточнения. Не подменяйте данните с адрес/телефон на партньора. Това не създава регистрация или маркетингово съгласие.
Източникът се определя от удостоверения партньор. OneBite поръчките автоматично се маркират като OneBite в администрацията и Telegram. HTTP 200 потвърждава записването; не е отделна гаранция за доставено Telegram/имейл/SMS известие.
{
"external_order_id": "ONEBITE-2026-10001",
"items": [
{
"selection": {
"type": "product",
"product_id": 123,
"size": "medium",
"removed": [],
"crust": 0,
"addons": []
},
"quantity": 1
}
],
"choice": {
"fulfilment": "pickup",
"location_id": "main",
"payment": "cash"
},
"customer": {
"name": "Customer name",
"phone": "0888123456",
"email": "customer@example.com",
"note": "Doorbell 3"
},
"expected_total_minor": 790,
"quote_token": "<quote_token-from-matching-quote>"
}
curl --fail-with-body --user "$PF_API_KEY:$PF_API_PASSWORD" \
--header 'Accept: application/vnd.api+json' \
--header 'Content-Type: application/json' \
--data-binary @order-request.json \
'https://api.pizzafashion.bg/v1/orders'{
"meta": {
"data": {
"external_order_id": "ONEBITE-2026-10001",
"order_number": "PF-A2000",
"status": "accepted",
"status_label": "Приета",
"currency": "EUR",
"total_minor": 790,
"payment": "cash",
"paid": false,
"created_at": "2026-10-18T12:00:00Z",
"updated_at": "2026-10-18T12:00:00Z",
"replayed": false
}
}
}const base = 'https://api.pizzafashion.bg/v1';
const auth = Buffer.from(
process.env.PF_API_KEY + ':' + process.env.PF_API_PASSWORD
).toString('base64');
async function pf(path, body) {
const response = await fetch(base + path, {
method: body === undefined ? 'GET' : 'POST',
redirect: 'error',
signal: AbortSignal.timeout(20_000),
headers: {
Authorization: 'Basic ' + auth,
Accept: 'application/vnd.api+json',
...(body === undefined ? {} : {'Content-Type':'application/json'})
},
...(body === undefined ? {} : {body:JSON.stringify(body)})
});
const raw = await response.text();
let payload;
try { payload = JSON.parse(raw); } catch { payload = null; }
if (!response.ok) {
// Do not log Authorization, raw contact data or the entire body.
const error = new Error(payload?.meta?.error?.message || 'API request failed');
error.status = response.status;
error.retryAfter = response.headers.get('retry-after');
throw error;
}
if (!payload?.meta?.data) throw new Error('Unexpected response envelope');
return payload.meta.data;
}
async function readCompleteCatalogue() {
const products = new Map(), combos = new Map();
for (let page = 1; ; page++) {
const data = await pf('/catalogue?page=' + page);
for (const product of data.products) products.set(product.id, product);
for (const combo of data.combos) combos.set(combo.code, combo);
if (!data.has_more) return {products:[...products.values()], combos:[...combos.values()]};
if (page >= 10000) throw new Error('Pagination limit');
}
}
async function priceSelection(items, choice) {
const result = await pf('/quote', {items, choice});
// Persist original items/choice; show result.quote.total_minor to customer.
return result;
}
async function sendConfirmedOrder(savedRequest) {
// Persist external_order_id and this exact payload BEFORE calling.
// Call only after the customer confirms the quoted total.
return pf('/orders', savedRequest);
}
async function checkOwnOrder(externalOrderId) {
return pf('/orderstatus', {external_order_id:externalOrderId});
}
// After an ambiguous timeout: checkOwnOrder(savedRequest.external_order_id).
// If needed retry sendConfirmedOrder(savedRequest), preserving ID and content.
// This sample defines functions only. It creates no order automatically./orderstatusСтатус и повторни опити
Изпратете само external_order_id. Връща се статус единствено за поръчка на вашия партньор, без контактните данни на клиента. Няма endpoint за чужди поръчки, промяна на статус, отказ или webhook във v1. За промяна се свържете с ресторанта.
Проверявайте активните поръчки през 30–60 секунди в общия лимит. При 429 спазете Retry-After и добавете случайно забавяне; при 503 ползвайте ограничен backoff със същия ID. При повтарящи се грешки уведомете ваш оператор.
acceptedЗаписана и приета в системата; служителите продължават обработката.preparingПриготвя се.sentИзпратена; при pickup означава готова за вземане.deliveredДоставена / приключена.cancelledОтказана.payment_reviewИзисква ръчна проверка; свържете се с ресторанта.
{
"external_order_id": "ONEBITE-2026-10001"
}
curl --fail-with-body --user "$PF_API_KEY:$PF_API_PASSWORD" \
--header 'Accept: application/vnd.api+json' \
--header 'Content-Type: application/json' \
--data-binary @status-request.json \
'https://api.pizzafashion.bg/v1/orderstatus'Пълен списък на атрибутите
Всеки ред описва едно поле. Пътят показва къде се намира; [] означава елемент от масив. Полетата само за четене не се копират в заявката за поръчка.
minor = цяло число евроцентове; 790 = 7,90 EUR. flag = boolean или 0/1. numeric = число или цифров низ от отговор; нормализирайте преди употреба. ? допуска null. При product / half / combo полето е приложимо за съответния вид. delivery / pickup са условни според получаването. email зависи от настройките на ресторанта.
Няма намерени атрибути. Опитайте друго име.
Заглавки на заявкитеHTTP headers3
Заявка към API · RequestHeaders
AuthorizationstringЗадължителноHTTP Basic: API ключът е username, отделната парола е password. Само към HTTPS адреса на API.
Примерна стойност"Basic <base64(API_KEY:API_PASSWORD)>"AcceptstringЗадължителноИзрично поискайте JSON API отговор.
Примерна стойност"application/vnd.api+json"Content-TypestringУсловно · postЗа POST тялото трябва да е UTF-8 JSON обект. Не изпращайте HTML form или form-data.
Примерна стойност"application/json"
Страници на каталогаGET /catalogue query1
Заявка към API · CatalogueQuery
pageinteger 1–10000НезадължителноЦяло число 1–10000, по подразбиране 1. Пример: /catalogue?page=2. Други query параметри не се поддържат.
Примерна стойност1
Отговор на каталогаmeta.data13
Само в отговора · Catalogue
schemaintСамо в отговораВерсия на структурата; в момента 1.
Примерна стойност1currencyEURСамо в отговораВалутата на всички цени.
Примерна стойност"EUR"timezonestringСамо в отговораЧасова зона за работното време.
Примерна стойност"Europe/Sofia"categoriesCategory[]Само в отговораКатегории; свържете чрез category_ids на продукта.
Примерна стойностВложени полета: Category ↗productsProduct[]Само в отговораДо 50 продукта на страница, включително деца за избор.
Примерна стойностВложени полета: Product ↗pageintСамо в отговораНомер на текущата страница; започва от 1.
Примерна стойност1page_sizeintСамо в отговораРазмер на страницата: 50.
Примерна стойност50totalintСамо в отговораОбщ брой продукти, не само видимите карти.
Примерна стойност144has_moreboolСамо в отговораПри true извикайте следващата страница.
Примерна стойностtruecombosCombo[]Само в отговораКомбо предложения; обединявайте страниците по code.
Примерна стойностВложени полета: Combo ↗pizza_basesBase[]Само в отговораОбщ списък основи; използвайте конкретния products[].bases за продукта.
Примерна стойностВложени полета: Base ↗halfHalfSettings objectСамо в отговораНастройки за пица 50/50.
Примерна стойностВложени полета: HalfSettings ↗generated_atRFC3339 stringСамо в отговораЧас на генериране, RFC3339.
Примерна стойност"2026-10-18T12:00:00+00:00"
Категорииcategories[]4
Само в отговора · Category
idintСамо в отговораПостоянен идентификатор на категорията.
Примерна стойност7namestringСамо в отговораПублично име на категорията.
Примерна стойност"Пици"iconstringСамо в отговораКод на иконка; визуален метаданен атрибут.
Примерна стойност"pizza"countintСамо в отговораБрой продукти в категорията според менюто.
Примерна стойност24
Атрибути на продуктproducts[]18
Само в отговора · Product
idintСамо в отговораСтабилен ID; изпратете го като selection.product_id.
Примерна стойност123namestringСамо в отговораИме за показване; API не превежда имената на ястията.
Примерна стойност"Пица Чикън"descriptionstringСамо в отговораОбикновен текст без HTML.
Примерна стойност"Пилешко месо, моцарела"category_idsinteger[]Само в отговораКатегориите, към които принадлежи продуктът.
Примерна стойност[7]imageurl?Само в отговораАбсолютен HTTPS адрес на снимката или null.
Примерна стойност"https://pizzafashion.bg/images/example.webp"thumbnailurl?Само в отговораПо-малка снимка за каталог или null.
Примерна стойност"https://pizzafashion.bg/images/example-thumb.webp"image_illustrativeboolСамо в отговораДали снимката е илюстративна.
Примерна стойностfalselistedboolСамо в отговораfalse: дете за вкус/разфасовка; пазете го, но не показвайте отделна карта.
Примерна стойностtrueminorminor?Само в отговораБазова показвана цена в евроцентове. Проверявайте конкретния размер.
Примерна стойност790currencyEURСамо в отговораВалута EUR.
Примерна стойност"EUR"availableboolСамо в отговораПри false забранете поръчването на този продукт.
Примерна стойностtrueavailable_atstr?Само в отговораПланирано връщане в наличност или null; не заменя текущото available.
Примерна стойностnullavailability_noticestringСамо в отговораТекст за наличността, ако е зададен.
Примерна стойност""variantsVariant[]Само в отговораРазмерите и съответните цени, съставки и опции.
Примерна стойностВложени полета: Variant ↗addonsAddon[]Само в отговораДопустими добавки. Цената за избрания размер е във variants[].addons.
Примерна стойностВложени полета: Addon ↗basesBase[]Само в отговораДопустими основи за тази пица; празно за неприложими продукти.
Примерна стойностВложени полета: Base ↗choicesChoiceGroup[]Само в отговораИзбори за вкус/разфасовка, водещи към друг product_id.
Примерна стойностВложени полета: ChoiceGroup ↗half_eligibleboolСамо в отговораМоже да участва в 50/50 при включена функция и размер family.
Примерна стойностtrue
Размериproducts[].variants[]10
Само в отговора · Variant
keystandard | medium | familyСамо в отговораКлюч за selection.size; използвайте само върнат размер.
Примерна стойност"medium"labelstringСамо в отговораЧовешко име на размера.
Примерна стойност"Средна"minorminor?Само в отговораПълна цена на този размер, не доплащане спрямо друг размер.
Примерна стойност790weight_gint?Само в отговораГрамаж или null, когато не е зададен.
Примерна стойност550ingredientsIngredient[]Само в отговораСъставки; премахвайте само тези с removable=1.
Примерна стойностВложени полета: Ingredient ↗allergensinteger[1–14][]Само в отговораЧислови кодове 1–14; премахване на съставка не гарантира липса на алерген.
Примерна стойност[1,7]crust_selectableboolСамо в отговораРазрешен ли е изборът на борд.
Примерна стойностtruecrust_includedboolСамо в отговораБорд по рецепта; използвайте като начална стойност на crust.
Примерна стойностfalsecrust_extra_minorminor?Само в отговораДоплащане при добавяне на борд; null не означава безплатно.
Примерна стойност250addonsAddon[]Само в отговораДобавки с изчислена цена за този размер.
Примерна стойностВложени полета: Addon ↗
Съставкиvariants[].ingredients[]3
Само в отговора · Ingredient
idintСамо в отговораID за selection.removed[], ако премахването е разрешено.
Примерна стойност17namestringСамо в отговораИме на съставката.
Примерна стойност"Лук"removableboolean | 0 | 1Само в отговора1/true: може да се премахне; 0/false: не може.
Примерна стойност1
Сосове и добавкиproducts[].addons[] / variants[].addons[]11
Само в отговора · Addon
codestringСамо в отговораИзпратете този код в selection.addons[], без повторения.
Примерна стойност"garlic_sauce"namestringСамо в отговораИме на добавката за избрания размер.
Примерна стойност"Чеснов сос"groupsauce | toppingСамо в отговораГрупа: сос или добавка за пица.
Примерна стойност"sauce"enabledboolean | 0 | 1Само в отговораФлаг за включена дефиниция; каталогът връща разрешените добавки.
Примерна стойност1minorinteger · EUR centsСамо в отговораЦена в евроцентове; във variant е за конкретния размер.
Примерна стойност100allergensinteger[1–14][]Само в отговораАлергените на добавката.
Примерна стойност[7]reviewedboolean | 0 | 1Само в отговораПотвърдени ли са данните за алергени.
Примерна стойност1family_minorinteger · EUR centsСамо в отговораДопълнителна метаинформация за семейния размер, ако е налична.
Примерна стойност200weight_gintСамо в отговораГрамаж на добавката, ако е известен.
Примерна стойност50family_weight_gintСамо в отговораГрамаж за семейния размер, ако е наличен.
Примерна стойност100family_namestringСамо в отговораЕтикет за семейния размер, ако е наличен.
Примерна стойност"Добавка — 100 г"
Основи за пицаproducts[].bases[] / pizza_bases[]7
Само в отговора · Base
codestringСамо в отговораКод за selection.base; не е платена добавка.
Примерна стойност"tomato"namestringСамо в отговораИме за показване.
Примерна стойност"Доматено пюре"enabledboolean | 0 | 1Само в отговораФлаг на дефиницията; липсва в някои нормализирани отговори за цена.
Примерна стойност1defaultboolean | 0 | 1Само в отговораОсновата по подразбиране; избира се при пропуснат base.
Примерна стойност1minorinteger · EUR centsСамо в отговораОсновите са включени; стойността е 0.
Примерна стойност0allergensinteger[1–14][]Само в отговораАлергенни кодове за основата.
Примерна стойност[]reviewedboolean | 0 | 1Само в отговораПотвърдени ли са алергенните данни.
Примерна стойност1
Вкус и разфасовкаproducts[].choices[]3
Само в отговора · ChoiceGroup
labelstringСамо в отговораЗаглавие на групата за избор.
Примерна стойност"Избери вкус"show_priceboolСамо в отговораДали интерфейсът да показва цената до избора.
Примерна стойностtrueoptionsChoiceOption[]Само в отговораВарианти, всеки с отделен product_id.
Примерна стойностВложени полета: ChoiceOption ↗
Опция за вкус/разфасовкаchoices[].options[]4
Само в отговора · ChoiceOption
product_idintСамо в отговораСлед избора заредете този продукт и неговите размери/добавки.
Примерна стойност124labelstringСамо в отговораТекст на избора.
Примерна стойност"Без захар"minorinteger · EUR centsСамо в отговораСамостоятелна цена на целевия продукт.
Примерна стойност200currentboolСамо в отговораТази опция ли е текущият продукт.
Примерна стойностfalse
Комбо предложенияcombos[]10
Само в отговора · Combo
codestringСамо в отговораПостоянен код за selection.combo_code.
Примерна стойност"combo-example"revisionstringСамо в отговораКопирайте точно в combo_revision; не генерирайте своя стойност.
Примерна стойност"<revision-from-catalogue>"namestringСамо в отговораПублично име.
Примерна стойност"Комбо предложение"descriptionstringСамо в отговораКратко описание.
Примерна стойност"Пица и напитка"imageurl?Само в отговораHTTPS снимка или null.
Примерна стойностnullminorinteger · EUR centsСамо в отговораЦена на конфигурацията по подразбиране; опции може да добавят доплащане.
Примерна стойност1490availableboolСамо в отговораТекуща достъпност; сървърът проверява отново при поръчка.
Примерна стойностtrueschedulestringСамо в отговораЧовешко описание, не машинно разрешение за поръчка.
Примерна стойност"Всеки ден · през работното време"slotsComboSlot[]Само в отговораПодредени позиции; запазете броя и реда.
Примерна стойностВложени полета: ComboSlot ↗default_selectionSelection objectСамо в отговораГотов selection за заявка; променяйте само разрешените опции.
Примерна стойностВложени полета: Selection ↗
Позиции в комбоcombos[].slots[]2
Само в отговора · ComboSlot
product_idsinteger[]Само в отговораДопустими продукти за тази позиция; не използвайте други ID.
Примерна стойност[123,124]sizestandard | medium | familyСамо в отговораЗадължителен размер за позицията; не може да се сменя.
Примерна стойност"medium"
Настройки 50/50half4
Само в отговора · HalfSettings
enabledboolСамо в отговораАко false, не предлагайте билдера 50/50.
Примерна стойностtruesizefamilyСамо в отговора50/50 е само семейна пица.
Примерна стойност"family"price_modehigher | average | fixed | unsetСамо в отговораМетод за цена; винаги вземайте окончателната сума от /quote.
Примерна стойност"higher"fixed_minorminor?Само в отговораФиксирана цена при mode=fixed; null не означава 0.
Примерна стойностnull
Получаване и работно времеmeta.data7
Само в отговора · Availability
currencyEURСамо в отговораВалута на сумите.
Примерна стойност"EUR"timezonestringСамо в отговораМестна часова зона за графиците.
Примерна стойност"Europe/Sofia"payment_methodsstring[]Само в отговораЗа тази версия се връща само cash.
Примерна стойност["cash"]ordering_enabledboolСамо в отговораОбщ и партньорски прием; не гарантира, че дадена зона е отворена.
Примерна стойностtruezonesZone[]Само в отговораЗони за доставка. Числата може да са JSON числа или цифрови низове.
Примерна стойностВложени полета: Zone ↗pickupPickup objectСамо в отговораИнформация за вземане от ресторанта.
Примерна стойностВложени полета: Pickup ↗noticestringСамо в отговораНапомняне да се ползва /quote за окончателните правила.
Примерна стойност"Use POST /quote for authoritative current eligibility, fees and minimums."
Зони за доставкаzones[]9
Само в отговора · Zone
idinteger | numeric stringСамо в отговораID за choice.zone_id; изпращайте като цяло число.
Примерна стойност1namestringСамо в отговораИме на обслужваното място.
Примерна стойност"Велинград"enabledinteger | numeric stringСамо в отговора1: включена зона; 0: изключена.
Примерна стойност1days_maskinteger | numeric stringСамо в отговораБитова маска: понеделник=1, вторник=2, … неделя=64; 127=всеки ден.
Примерна стойност127acceptance_opensstringСамо в отговораОбичаен начален час, HH:MM, Europe/Sofia.
Примерна стойност"09:00"acceptance_cutoffstringСамо в отговораОбичаен краен час; късни правила/почивни дни се проверяват чрез /quote.
Примерна стойност"22:00"delivery_fee_minornumeric?Само в отговораОбичайна такса или null; точната такса идва от /quote.
Примерна стойност0minimum_order_minornumeric?Само в отговораОбичаен минимум или null, ако не е конфигуриран.
Примерна стойност0free_delivery_over_minornumeric?Само в отговораПраг за безплатна доставка или null, ако няма такъв.
Примерна стойностnull
Вземане от мястоpickup6
Само в отговора · Pickup
location_idmainСамо в отговораИзползвайте main в choice.location_id.
Примерна стойност"main"namestringСамо в отговораИме на обекта.
Примерна стойност"Pizza Fashion"addressstringСамо в отговораАдрес за получаване.
Примерна стойност"Велинград, адрес на обекта"opensstringСамо в отговораОбичаен начален час.
Примерна стойност"09:00"cutoffstringСамо в отговораОбичаен краен час.
Примерна стойност"22:00"days(integer | numeric string)[]Само в отговораISO дни: 1=понеделник, 7=неделя; стойностите може да са низове.
Примерна стойност[1,2,3,4,5,6,7]
Наливане на поръчка към Pizza FashionPOST /orders6
Заявка към API · OrderRequest
external_order_idstring 1–80ЗадължителноВаш постоянен уникален номер, 1–80 ASCII букви/цифри и _ . : -; започва с буква/цифра. Пазете при повторен опит.
Примерна стойност"ONEBITE-2026-10001"itemsLine[]Задължително1–40 позиции; същите като при подписаната оферта.
Примерна стойностВложени полета: Line ↗choiceReceiptChoice objectЗадължителноНачин на получаване и плащане; същият като в /quote.
Примерна стойностВложени полета: ReceiptChoice ↗customerCustomer objectЗадължителноДанни за изпълнение на тази поръчка; не създават Club профил.
Примерна стойностВложени полета: Customer ↗expected_total_minorinteger ≥ 1ЗадължителноТочно quote.total_minor като JSON integer; не е ръчно задаване на цена.
Примерна стойност790quote_tokenstringЗадължителноНепроменен токен от /quote; първото изпращане трябва да е до 15 минути.
Примерна стойност"<quote_token-from-matching-quote>"
Заявка за точна ценаPOST /quote2
Заявка към API · QuoteRequest
itemsLine[]Задължително1–40 позиции с избори; цени не се изпращат.
Примерна стойностВложени полета: Line ↗choiceReceiptChoice objectЗадължителноНачин на получаване и cash плащане.
Примерна стойностВложени полета: ReceiptChoice ↗
Позиция в поръчкатаitems[]2
Заявка към API · Line
selectionSelection objectЗадължителноИзбор на продукт, 50/50 или комбо.
Примерна стойностВложени полета: Selection ↗quantityinteger 1–20НезадължителноКоличество 1–20; по подразбиране 1.
Примерна стойност1
Конфигуриране на продуктitems[].selection11
Заявка към API · Selection
typeproduct | half | comboНезадължителноВид избор; по подразбиране product. За 50/50 и комбо го задайте изрично.
Примерна стойност"product"product_idinteger ≥ 1Условно · productID от каталога; за нормален продукт или за вложена половина/комбо позиция.
Примерна стойност123sizestandard | medium | familyУсловно · productРазмер от variants[].key. В комбо запазете размера на позицията; за 50/50 е family.
Примерна стойност"medium"removedinteger[]НезадължителноДо 100 уникални ID от ingredients с removable=1; по подразбиране [].
Примерна стойност[17]crustboolean | 0 | 1НезадължителноИзбор на борд: 0/1 или false/true. Инициализирайте от crust_included; сменяйте само ако selectable.
Примерна стойност0addonsstring[]НезадължителноДо 40 различни кода за този продукт/размер; не на общото ниво на 50/50.
Примерна стойност["garlic_sauce"]basestringНезадължителноЕдин код от product.bases; при пропуск се взема default. За 50/50 е на общото ниво.
Примерна стойност"tomato"halvesSelection[]Условно · halfТочно две половини с product_id, size=family и removed. Бордът на половините следва рецептата; добавки не се конфигурират тук.
Примерна стойностВложени полета: Selection ↗combo_codestringУсловно · comboТочният code от combos[].
Примерна стойност"combo-example"combo_revisionstringУсловно · comboИзпратете върнатата revision, за да засечете променен състав/цена.
Примерна стойност"<revision-from-catalogue>"itemsSelection[]Условно · comboПодредени позиции от default_selection.items; точно една за всеки slot. Без quantity в тях.
Примерна стойностВложени полета: Selection ↗
Доставка, вземане и плащанеchoice4
Заявка към API · ReceiptChoice
fulfilmentdelivery | pickupЗадължителноИзпращайте изрично delivery или pickup.
Примерна стойност"delivery"zone_idinteger ≥ 1Условно · deliveryID от /availability.zones за delivery.
Примерна стойност1location_idmainУсловно · pickupЗа pickup използвайте main; не сменяйте зона с друг начин за по-ниска цена.
Примерна стойност"main"paymentcashЗадължителноСамо плащане в брой при доставка/вземане; няма онлайн плащане или такса за обработка.
Примерна стойност"cash"
Контакти за изпълнениеcustomer5
Заявка към API · Customer
namestr100ЗадължителноИстинско име, до 100 знака, обикновен текст.
Примерна стойност"Име на клиента"phonestring ≤ 80ЗадължителноПълен валиден телефон, препоръчително E.164. Български мобилен: 10 цифри с начална 0 или +359 и 9 цифри; непълни номера се отхвърлят.
Примерна стойност"0888123456"emailemail string ≤ 190Условно · emailВалиден имейл; задължителен, ако ресторантът го изисква. Изпращайте реалния адрес при наличност.
Примерна стойност"customer@example.com"addressstr240Условно · deliveryПри delivery: улица, номер и нужните уточнения, до 240 знака. При pickup не се използва.
Примерна стойност"Улица Примерна 10, вход А"notestr500НезадължителноБележка до 500 знака; може да бъде изключена от ресторанта. Без HTML или нови редове.
Примерна стойност"Звънец 3"
Заявка за собствен статусPOST /orderstatus1
Заявка към API · StatusRequest
external_order_idstring 1–80ЗадължителноСъщият номер, с който този партньор е изпратил поръчката.
Примерна стойност"ONEBITE-2026-10001"
Отговор след поръчка / статусmeta.data11
Само в отговора · OrderStatus
external_order_idstring 1–80Само в отговораВашият номер на поръчката.
Примерна стойност"ONEBITE-2026-10001"order_numberstringСамо в отговораНомерът, генериран от Pizza Fashion; не го изпращайте като собствен ID.
Примерна стойност"PF-A2000"statusaccepted | preparing | sent | delivered | cancelled | payment_reviewСамо в отговораМашинен статус за интеграцията; значенията са описани отделно.
Примерна стойност"accepted"status_labelstringСамо в отговораЕтикет от ресторанта; може да е на български независимо от езика на документацията.
Примерна стойност"Приета"currencyEURСамо в отговораВалута на поръчката.
Примерна стойност"EUR"total_minorinteger · EUR centsСамо в отговораЗаписана крайна сума, включително доставка.
Примерна стойност790paymentcashСамо в отговораНачинът на плащане е cash.
Примерна стойност"cash"paidboolСамо в отговораФлаг за отчетено плащане. При нова поръчка в брой false е нормално.
Примерна стойностfalsecreated_atRFC3339 stringСамо в отговораUTC време на създаване.
Примерна стойност"2026-10-18T12:00:00Z"updated_atRFC3339 stringСамо в отговораUTC време на последна промяна.
Примерна стойност"2026-10-18T12:05:00Z"replayedboolСамо в отговораСамо от /orders: true означава повторен отговор за същата поръчка, не нова поръчка.
Примерна стойностfalse
Отговор на офертатаmeta.data3
Само в отговора · QuoteResponse
quoteQuote objectСамо в отговораАвторитетна ценова разбивка; не изпращайте целия обект като поръчка.
Примерна стойностВложени полета: Quote ↗quote_tokenstringСамо в отговораЗапазете и изпратете с оригиналните items/choice в /orders.
Примерна стойност"<signed-token>"expires_atRFC3339 stringСамо в отговораКраен срок за първо изпращане на офертата, около 15 минути.
Примерна стойност"2026-10-18T12:15:00+00:00"
Крайни суми и правилаquote25
Само в отговора · Quote
schemaintСамо в отговораВерсия на ценовата структура.
Примерна стойност1test_onlyboolСамо в отговораПри true не може да се подаде реална партньорска поръчка.
Примерна стойностfalsecurrencyEURСамо в отговораВсички суми са в евроцентове.
Примерна стойност"EUR"choiceQuoteChoice objectСамо в отговораНормализиран избор за показване; за /orders запазете оригиналната заявка choice.
Примерна стойностВложени полета: QuoteChoice ↗locationQuoteLocation objectСамо в отговораЗона за доставка или обект за вземане.
Примерна стойностВложени полета: QuoteLocation ↗itemsQuotedLine[]Само в отговораКонфигурирани позиции и ценови разбивки.
Примерна стойностВложени полета: QuotedLine ↗countintСамо в отговораСбор на количествата, не брой редове.
Примерна стойност2subtotal_minorinteger · EUR centsСамо в отговораСума на продуктите преди общи отстъпки и доставка.
Примерна стойност1580delivery_minorinteger · EUR centsСамо в отговораАвторитетна такса за избраното получаване.
Примерна стойност0total_minorinteger · EUR centsСамо в отговораКрайна сума за показване и expected_total_minor.
Примерна стойност1580minimum_minorminor?Само в отговораПриложим минимум за поръчка.
Примерна стойност0minimum_exclusiveboolСамо в отговораtrue: сумата трябва да е строго над минимума.
Примерна стойностfalseminimum_includes_deliveryboolСамо в отговораДали минимумът включва доставката.
Примерна стойностfalseperiodregular | late | pickupСамо в отговораВид приложен времеви режим.
Примерна стойност"pickup"schedule_readyboolСамо в отговораРазрешено ли е изпращане според текущите правила.
Примерна стойностtruewarningsstring[]Само в отговораПредупреждения за показване.
Примерна стойност[]discount_minorinteger · EUR centsСамо в отговораОбща промо отстъпка; API не приема промокод и обичайно е 0.
Примерна стойност0discount_codestringСамо в отговораПромокод; за този API е празен.
Примерна стойност""online_discount_minorinteger · EUR centsСамо в отговораОтстъпка за онлайн плащане; при cash е 0.
Примерна стойност0online_discount_basis_pointsintСамо в отговораБазисни точки на онлайн отстъпка; при cash е 0.
Примерна стойност0delivery_net_minorinteger · EUR centsСамо в отговораДоставка без включения ДДС.
Примерна стойност0delivery_tax_minorinteger · EUR centsСамо в отговораВключен ДДС върху доставката.
Примерна стойност0net_minorinteger · EUR centsСамо в отговораОбща нетна сума; не се добавя повторно към total.
Примерна стойност1317tax_minorinteger · EUR centsСамо в отговораОбщ включен ДДС; не е допълнителна такса.
Примерна стойност263vat_percentintСамо в отговораПриложим процент ДДС от настройките, не твърдо зададена политика.
Примерна стойност20
Нормализиран избор в отговораquote.choice4
Само в отговора · QuoteChoice
fulfilmentdelivery | pickupСамо в отговораПотвърден начин на получаване.
Примерна стойност"pickup"zone_idintСамо в отговораЗона при delivery; 0 при pickup.
Примерна стойност0location_idstringСамо в отговораmain при pickup; празен низ при delivery.
Примерна стойност"main"paymentcashСамо в отговораПотвърден cash начин на плащане.
Примерна стойност"cash"
Място в офертатаquote.location5
Само в отговора · QuoteLocation
idinteger | "main"Само в отговораID на зона (число) или main за pickup.
Примерна стойност"main"namestringСамо в отговораИме на обекта/зоната.
Примерна стойност"Pizza Fashion"addressstringСамо в отговораАдрес на обекта при pickup; празно за зона.
Примерна стойност"Велинград, адрес на обекта"opensstringСамо в отговораОбичаен начален час.
Примерна стойност"09:00"cutoffstringСамо в отговораОбичаен краен час.
Примерна стойност"22:00"
Изчислена позицияquote.items[]10
Само в отговора · QuotedLine
keystringСамо в отговораВътрешен ключ на ценовия ред; не е product_id и не се изпраща обратно.
Примерна стойност"<server-line-key>"namestringСамо в отговораГотово име с конфигурацията.
Примерна стойност"Пица Чикън — Средна"quantityintСамо в отговораКоличество.
Примерна стойност1unit_minorinteger · EUR centsСамо в отговораЦена за един конфигуриран брой.
Примерна стойност790subtotal_minorinteger · EUR centsСамо в отговораunit_minor × quantity преди общи отстъпки.
Примерна стойност790configurationConfiguration objectСамо в отговораПълна изчислена конфигурация; само за четене.
Примерна стойностВложени полета: Configuration ↗discount_minorinteger · EUR centsСамо в отговораРазпределена отстъпка за реда.
Примерна стойност0gross_minorinteger · EUR centsСамо в отговораРед след отстъпката, с включен ДДС.
Примерна стойност790net_minorinteger · EUR centsСамо в отговораРед без включения ДДС.
Примерна стойност658tax_minorinteger · EUR centsСамо в отговораВключен ДДС за реда.
Примерна стойност132
Изчислен продукт / комбоquote.items[].configuration15
Само в отговора · Configuration
schemaintСамо в отговораВерсия на конфигурацията.
Примерна стойност1typeproduct | half | comboСамо в отговораВид на конфигурираната позиция.
Примерна стойност"product"namestringСамо в отговораИме за показване.
Примерна стойност"Пица Чикън — Средна"unit_minorinteger · EUR centsСамо в отговораКрайна единична цена с опциите.
Примерна стойност790currencyEURСамо в отговораВалута EUR.
Примерна стойност"EUR"weight_gint?Само в отговораОбщ грамаж, ако е известен.
Примерна стойност550partsConfiguredPart[]Само в отговораЕдин продукт, две половини или позиции в комбо.
Примерна стойностВложени полета: ConfiguredPart ↗allergensinteger[1–14][]Само в отговораОбединени алергенни кодове.
Примерна стойност[1,7]baseBase objectСамо в отговораНормализирана избрана основа, когато е приложима.
Примерна стойностВложени полета: Base ↗combo_codestringСамо в отговораКод на комбото.
Примерна стойност"combo-example"combo_revisionstringСамо в отговораПриложена ревизия на комбото.
Примерна стойност"<revision-from-catalogue>"regular_minorinteger · EUR centsСамо в отговораЦена на същите продукти поотделно.
Примерна стойност1800combo_savings_minorinteger · EUR centsСамо в отговораСпестяване от комбо цената.
Примерна стойност270extras_minorinteger · EUR centsСамо в отговораДоплащания за избраните опции.
Примерна стойност0selectionSelection objectСамо в отговораНормализиран selection за комбото; оригиналната заявка остава нужна за токена.
Примерна стойностВложени полета: Selection ↗
Детайл на изчислен продуктconfiguration.parts[]20
Само в отговора · ConfiguredPart
product_idintСамо в отговораID на продукта.
Примерна стойност123namestringСамо в отговораИме на продукта/позицията.
Примерна стойност"Пица Чикън"sizestandard | medium | familyСамо в отговораИзбран размер.
Примерна стойност"medium"recipe_revisionintСамо в отговораРевизия на рецептата; само за четене.
Примерна стойност3weight_gint?Само в отговораГрамаж или null.
Примерна стойност550portionstringСамо в отговораЕтикет за порцията, ако е зададен.
Примерна стойност""ingredientsIngredient[]Само в отговораСъстав по рецептата.
Примерна стойностВложени полета: Ingredient ↗omittedOmittedIngredient[]Само в отговораПремахнати съставки.
Примерна стойностВложени полета: OmittedIngredient ↗allergensinteger[1–14][]Само в отговораАлергенни кодове; не се премахват автоматично с компонент.
Примерна стойност[1,7]allergens_reviewedboolСамо в отговораПотвърдени ли са алергенните данни.
Примерна стойностtruecomposition_completeboolСамо в отговораПълен ли е записаният състав.
Примерна стойностtruecrustboolean | 0 | 1Само в отговораДействително избран борд.
Примерна стойност0crust_includedboolСамо в отговораВключен ли е борд по рецепта.
Примерна стойностfalsecrust_extra_minorinteger · EUR centsСамо в отговораДействително начислено доплащане за борд.
Примерна стойност0base_minorinteger · EUR centsСамо в отговораБазова цена на продукта/размера.
Примерна стойност790unit_minorinteger · EUR centsСамо в отговораЕдинична цена на тази част. При 50/50 не я сумирайте самостоятелно.
Примерна стойност790half_eligibleboolСамо в отговораДопустимост за 50/50.
Примерна стойностtrueaddonsAddon[]Само в отговораИзбрани добавки за продукт/комбо част; липсва при половини.
Примерна стойностВложени полета: Addon ↗addons_extra_minorinteger · EUR centsСамо в отговораСбор доплащания за добавки.
Примерна стойност0size_extra_minorinteger · EUR centsСамо в отговораИнформационно доплащане за размер; вече е в цената.
Примерна стойност0
Премахната съставкаconfiguration.parts[].omitted[]2
Само в отговора · OmittedIngredient
idintСамо в отговораID на премахнатата съставка.
Примерна стойност17namestringСамо в отговораИме на премахнатата съставка.
Примерна стойност"Лук"
Грешка от API контролераmeta.error2
Само в отговора · ApiError
statusintСамо в отговораHTTP статус на грешката.
Примерна стойност422messagestringСамо в отговораОбяснение; някои бизнес грешки са на български. Следете кода, не сравнявайте текстове.
Примерна стойност"Invalid request"
Кодове на алергениallergens[]14
- Глутен
- Ракообразни
- Яйца
- Риба
- Фъстъци
- Соя
- Мляко
- Ядки
- Целина
- Горчица
- Сусам
- Серен диоксид и сулфити
- Лупина
- Мекотели
Кодове за отговор и грешки
Обработвайте HTTP статуса преди JSON. Не приемайте, че всички инфраструктурни грешки имат meta.error. Не повтаряйте безкрайно грешки от данните или удостоверяването.
200Успех; включва и точен повторен отговор на /orders.400Неподдържани query параметри / gateway заявка.401Липсващ, грешен, спрян или сменен ключ/парола.403HTTPS е задължителен; HTTP API заявки не се пренасочват с ключа.404Няма ваша поръчка с този ID или маршрутът не съществува.409Променена/изтекла оферта, конфликтен external_order_id или заета заявка. Проверете статуса.413 / 415Тяло над 128 KiB / изисква се Content-Type: application/json.422Невалидни полета, опции, телефон, минимум, затворен период или липсваща наличност. Коригирайте данните.429Достигнат лимит. Спазете Retry-After.503Изключен прием/API/партньор или временна недостъпност. Ограничени повторни опити със същия ID.
{
"meta": {
"error": {
"status": 409,
"message": "Total changed. Request a fresh quote."
}
}
}Достъп, лимити и съвместимост
Данните за достъп са само за вашия сървър. Пазете ги в secret store или променливи на средата. Не ги поставяйте в URL, frontend JavaScript, мобилно приложение, логове или публичен API тестер. Изключете логването на Authorization и лични данни.
По подразбиране лимитът е 120 заявки/минута; ресторантът управлява индивидуалния и общия лимит. Прилага се по-ниският, както и независим IP лимит 120/минута. Не стартирайте паралелни агресивни пълни синхронизации.
Нов партньор започва спрян, без издаден ключ и без прием на поръчки. Pizza Fashion генерира ключ и парола отделно за всеки партньор. Спирането блокира следващи заявки, а смяната на ключ отменя старите данни и запазва номерата/защитата от дублиране.
API версията остава v1. Оригиналният адрес https://pizzafashion.bg/api/index.php/v1/pizzafashion/partner продължава да работи. Игнорирайте непознати добавени полета в отговорите; във входящите заявки не изпращайте неописани полета.
Преди реален старт договорете контролиран тест с Pizza Fashion. Примерите тук не съдържат работещ ключ и не изпращат автоматично поръчки.