Treoir

Fittle a chomhtháthú i dtairseach – céim ar chéim.

D’fhorbróirí tairseach, slabhraí agus córas dá gcuid féin: an cumraitheoir a leabú, iarratais a fháil trí webhook, obair leis an API agus an réamhamharc 3D a thaispeáint don cheardaí. Le samplaí in Node.js, PHP agus curl. Tógann bunchomhtháthú thart ar uair an chloig.

1. Conas a oibríonn sé

Ní óstálann tú rud ar bith agus ní shuiteálann tú rud ar bith. Tá ceithre chéim sa sreabhadh iomlán:

  1. Ritheann an cumraitheoir ar do shuíomh in iframe (<script> amháin). Dearann an custaiméir cistin, vardrús, balla seomra suí, troscán nó seomra folctha i 3D.
  2. Seolann sé iarratas (ainm, ríomhphost, teileafón, riachtanais, grianghraif). Stórálann Fittle é faoi d’eochair.
  3. Faigheann tú é ar thrí bhealach: trí ríomhphost (le nasc 3D), trí webhook (POST sínithe chuig do fhreastalaí – láithreach) agus tríd an API (am ar bith níos déanaí, grianghraif san áireamh).
  4. Tugann tú do do cheardaithe é – tá nasc réamhamhairc 3D ag gach iarratas a osclaíonn gan chuntas.

A bhfuil uait: cuntas siúinéara ar app.getfittle.com le billeáil in aghaidh an iarratais (ní íocann tairseacha agus slabhraí pacáiste ach gach iarratas a fhaightear) – tar éis an athraithe, feictear an cárta Comhtháthú le webhook agus eochair API i do chuntas. Scríobh chugainn agus athróimid thú.

Gan billeáil in aghaidh an iarratais níl aon chárta Comhtháthú ann agus tugann glaonna API 403 integration_off ar ais. Oibríonn leabú an chumraitheora féin (céim 1) ar ghnáthphacáiste freisin.

Céim 1 – An cumraitheoir a leabú (5 nóiméad)

An bealach is simplí: script amháin ar an leathanach ina mbeidh an cumraitheoir. Tá an eochair FITT-… i do chuntas; tá sí ceangailte le do chuid fearann (socraigh iad sa chuntas), mar sin ní féidir mí-úsáid a bhaint aisti ó shuíomh eile.

<div id="configurator-ga"></div>
<script src="https://app.getfittle.com/embed.js"
        data-key="FITT-XXXX-XXXX-XXXX"
        data-product="kitchen"
        data-target="#configurator"></script>

data-product: kitchen · wardrobe · living · furniture · bathroom. Is í teanga an chumraitheora teanga réamhshocraithe do chuntais; is féidir leis an gcustaiméir í a athrú sa cheanntásc.

Tairseach le húsáideoirí logáilte isteach: in ionad data-target glaoigh ar HNL.mount() – réamhlíonann tú ainm, ríomhphost agus teileafón san fhoirm iarratais agus cuirtear ar an eolas thú nuair a seoladh iarratas:

<script src="https://app.getfittle.com/embed.js" data-key="FITT-XXXX-XXXX-XXXX"></script>
<script>
  HNL.mount('#configurator', {
    product: 'wardrobe',                 // kitchen | wardrobe | living | furniture | bathroom
    fill: true,                          // fill the parent's height (default 820 px)
    prefill: {                           // logged-in user of your portal (editable in the form)
      name: 'Jane Doe', email: 'jane@example.com', phone: '+421 900 000 000'
    }
  });
  HNL.on('ready', function (e) { console.log('configurator running:', e.product); });
  HNL.on('quote', function (e) {
    // request sent – e.id is the request id (DM…), e.design the design JSON
    location.href = '/thank-you?request=' + encodeURIComponent(e.id);
  });
</script>

Imeachtaí HNL.on: ready {product}, quote {id, product, design}, design (freagra ar HNL.getDesign(cb)), height {height}. Is féidir HNL.prefill({…}) a ghlaoch níos déanaí freisin.

Leid. Tagann an t-imeacht quote i mbrabhsálaí an chustaiméara – úsáideach do leathanach buíochais nó atreorú. Le haghaidh próiseála ar an bhfreastalaí úsáid an webhook (céim 2), atá sínithe.

Céim 2 – Webhook (20 nóiméad)

I do chuntas → Comhtháthú socraigh an URL webhook (https) agus rún (aon teaghrán fada, m.sh. 32 carachtar randamach). Le gach iarratas seolaimid:

POST https://portal.example.com/furniconf/webhook
Content-Type: application/json
X-Furniconf-Event: quote.created
X-Furniconf-Delivery: WMTZ7Q2K9A1B
X-Furniconf-Timestamp: 1789300000
X-Furniconf-Signature: sha256=3f1a…9c

{
  "id": "WMTZ7Q2K9A1B",
  "event": "quote.created",
  "createdAt": "2026-09-16T09:12:33.000Z",
  "shopKey": "FITT-XXXX-XXXX-XXXX",
  "data": {
    "design": {
      "id": "DMU3VCTB63BB7",
      "product": "kitchen",
      "status": "new",
      "createdAt": "2026-09-16T09:12:33.000Z",
      "customer": { "name": "Jane Doe", "email": "jane@example.com", "phone": "+421 900 000 000",
                    "note": "Handles in black, please.", "photoCount": 2 },
      "design": { "type": "kitchen", "layout": "…", "dims": { … }, "runs": [ … ], "room": { … }, "state": { … } }
    }
  }
}

Rialacha seachadta:

  • Freagair 2xx laistigh de 8 soicind. Próiseáil tar éis freagra a thabhairt (scuaine, oibrí) – murach sin tá baol ama istigh ann.
  • Ar earráid nó am istigh déanaimid iarracht arís tar éis 10 s, 1 nóim agus 5 nóim, ansin éirímid as – is féidir leat an t-iarratas a fháil tríd an API i gcónaí. Ní leanaimid atreoruithe (3xx).
  • An X-Furniconf-Delivery céanna = an seachadadh céanna. Stóráil é agus déan neamhaird de dhúblaigh (idempotence).
  • Níl grianghraif an chustaiméara sa webhook (photoCount amháin) – íoslódáil iad tríd an API (céim 3).

Seiceáil sínithe

Is HMAC-SHA256 é an síniú le do rún thar an teaghrán timestamp + "." + amhchorp. Cuir i gcomparáid in am tairiseach:

// Node.js / Express – the signature is computed over the RAW body, so read it before any JSON parser
const express = require('express');
const crypto = require('crypto');
const app = express();
const SECRET = process.env.FURNICONF_WEBHOOK_SECRET;

app.post('/furniconf/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const ts  = req.header('X-Furniconf-Timestamp') || '';
  const got = req.header('X-Furniconf-Signature') || '';
  const want = 'sha256=' + crypto.createHmac('sha256', SECRET).update(ts + '.' + req.body).digest('hex');
  if (got.length !== want.length || !crypto.timingSafeEqual(Buffer.from(got), Buffer.from(want))) {
    return res.status(401).end();                       // not from Fittle
  }
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return res.status(401).end();   // replay protection (5 min)

  const evt = JSON.parse(req.body);
  res.status(200).end();                                // answer first (within 8 s) …
  if (evt.event === 'quote.created') {
    const d = evt.data.design;
    // … then process: idempotency by delivery id, save, assign to a craftsman
    saveRequest({ deliveryId: evt.id, requestId: d.id, product: d.product, customer: d.customer, design: d.design });
  }
});
app.listen(3000);

An rud céanna in PHP:

<?php  // PHP – same check with hash_hmac + hash_equals
$secret = getenv('FURNICONF_WEBHOOK_SECRET');
$raw    = file_get_contents('php://input');
$ts     = $_SERVER['HTTP_X_FURNICONF_TIMESTAMP'] ?? '';
$got    = $_SERVER['HTTP_X_FURNICONF_SIGNATURE'] ?? '';
$want   = 'sha256=' . hash_hmac('sha256', $ts . '.' . $raw, $secret);
if (!hash_equals($want, $got) || abs(time() - (int)$ts) > 300) { http_response_code(401); exit; }

http_response_code(200);
$evt = json_decode($raw, true);
if ($evt['event'] === 'quote.created') {
  $d = $evt['data']['design'];
  // $evt['id'] = delivery id (idempotency), $d['id'] = request id, $d['customer'], $d['design']
}

Tástáil: seolann an cnaipe Seol webhook tástála i do chuntas imeacht webhook.test leis na ceanntásca céanna; feictear an toradh (stádas HTTP, iarrachtaí) i do chuntas agus inár logáil.

An botún is coitianta: ní mheaitseálann an síniú toisc gur pharsáil an creatlach an corp agus gur athshraithigh sí é (spásanna difriúla, ord na n-eochracha). Sínítear an t-amhchorp – in Express express.raw() roimh express.json(), in PHP php://input, in Django request.body, in Laravel $request->getContent().

Céim 3 – API (15 nóiméad)

I do chuntas → Comhtháthú → Gin eochair API. Ní thaispeántar an eochair fak_… ach uair amháin – stóráil í i rúin an fhreastalaí, riamh sa tosaigh. Iompraíonn gach glao Authorization: Bearer fak_…, is JSON iad na coirp, teorainn 600 glao in aghaidh 10 nóiméad.

Iarratais nua (na cinn is nuaí ar dtús; grianghraif mar líon amháin):

curl -s "https://app.getfittle.com/api/portal/designs?status=new&limit=50" \
  -H "Authorization: Bearer fak_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

{ "designs": [
    { "id": "DMU3VCTB63BB7", "product": "kitchen", "status": "new", "createdAt": "2026-09-16T09:12:33.000Z",
      "customer": { "name": "Jane Doe", "email": "jane@example.com", "phone": "+421 900 000 000", "note": "…", "photoCount": 2 },
      "design": { … } }
] }

Iarratas amháin lena liosta grianghraf, agus grianghraf a íoslódáil:

curl -s "https://app.getfittle.com/api/portal/designs/DMU3VCTB63BB7?photos=1" \
  -H "Authorization: Bearer fak_…"

{ "design": { "id": "DMU3VCTB63BB7", …,
    "customer": { …, "photoCount": 2,
      "photos": [ { "n": 1, "name": "kitchen-now.jpg", "type": "image/jpeg", "size": 812345,
                    "url": "/api/portal/designs/DMU3VCTB63BB7/photos/1" }, … ] } } }

# photo (binary) – the API key is required here as well
curl -s "https://app.getfittle.com/api/portal/designs/DMU3VCTB63BB7/photos/1" \
  -H "Authorization: Bearer fak_…" -o kitchen-now.jpg

Athrú stádais – ionas go bhfeicfidh tusa agus muidne cá bhfuil an t-iarratas:

curl -s -X POST "https://app.getfittle.com/api/portal/designs/DMU3VCTB63BB7/status" \
  -H "Authorization: Bearer fak_…" -H "Content-Type: application/json" \
  -d '{ "status": "contacted" }'

{ "ok": true, "design": { "id": "DMU3VCTB63BB7", "status": "contacted", … } }

Nasc réamhamhairc 3D don cheardaí (gan chuntas, sínithe, bailí ar feadh an lín laethanta a thugtar):

curl -s -X POST "https://app.getfittle.com/api/portal/designs/DMU3VCTB63BB7/view-link" \
  -H "Authorization: Bearer fak_…" -H "Content-Type: application/json" \
  -d '{ "days": 30 }'

{ "ok": true,
  "url": "https://app.getfittle.com/c/kitchen?k=FITT-XXXX-XXXX-XXXX&load=DMU3VCTB63BB7&vt=eyJ0…&view=1" }

Gan webhook: vótaíocht thréimhsiúil (m.sh. gach 5 nóiméad):

# polling instead of a webhook: everything since the last check
curl -s "https://app.getfittle.com/api/portal/designs?since=2026-09-16T00:00:00Z" -H "Authorization: Bearer fak_…"

Stádais iarratais: newseencontactedquotedwon / lost. Cosáin eile: GET /api/portal/me (do phróifíl agus socruithe), POST /api/portal/webhook/test.

Tá freagraí earráide san fhoirm { "error": "…", "reason": "…", "reqId": "…" } – luaigh an reqId agus fadhb á tuairisciú agat.

Céim 4 – Réamhamharc 3D don cheardaí agus sa tairseach

Tá nasc ó view-link ag gach iarratas: osclaíonn an ceardaí é i mbrabhsálaí (ar fhón freisin) agus feiceann sé go díreach cad a dhear an custaiméir – rothlú, toisí, doirse a oscailt, siúlóid, gan logáil isteach. Seol trí ríomhphost nó SMS é, nó taispeáin é i sonraí an iarratais i do thairseach:

<!-- the request inside your portal: a 3D preview in an iframe (URL from view-link) -->
<iframe src="https://app.getfittle.com/c/kitchen?k=FITT-…&load=DMU3VCTB63BB7&vt=eyJ0…&view=1"
        style="width:100%;height:720px;border:0;border-radius:12px" allow="xr-spatial-tracking"></iframe>

Tá an nasc sínithe agus teoranta in am (days, réamhshocrú 30). Nuair a théann sé in éag gin ceann nua – fanann an t-iarratas stóráilte.

Céim 5 – Cad atá i JSON an deartha

Tá dhá shraith ag design: cur síos inléite do dhaoine agus state don mheaisín:

{
  "type": "kitchen",                     // kitchen | wardrobe | living | furniture | bathroom
  "layout": "Rohová (L)",                // readable values – in the shop's default language
  "dims":  { "baseHeight": 72, "wallHeight": 72, "totalHeight": 218, … },
  "runs":  [ { "id": "A", "length": 365, "columns": [ { "width": 80, "base": "Drez", "wall": "Otvorená polica", … } ] } ],
  "decors": { "base": "Dekor 3017", "baseCode": "D3017", … },
  "appliances": { "fridge": 1, "oven": 1, "hob": 1, "sink": 1, … },
  "room":  { "width": 460, "depth": 360, "height": 270, "openings": [ … ], "cart": { … } },
  "state": { … }                         // raw configurator state (codes) – for loading back into 3D
}
  • luachanna inléite (cruth, toisí, modúil agus a n-ábhar, maisiúcháin le cóid, fearais, seomra le hoscailtí) i gcónaí i dteanga réamhshocraithe do chuntais – cibé teanga a d’úsáid an custaiméir.
  • Is é state amhstaid an chumraitheora (cóid, ní téacsanna). Ligeann sé an dearadh a luchtú ar ais i 3D am ar bith; ná hathraigh é.
  • room.cart (mód praghsanna amháin): ciseán le cóid táirge, cainníochtaí agus suimeanna má chuir an custaiméir do chuid rudaí 3D nó tíleanna sa seomra.
  • Tá an fhormáid seasmhach – ní dhéantar ach réimsí nua a chur leis, ní athainmnítear na cinn atá ann riamh.

Billeáil agus teorainneacha

  • Íocann tú in aghaidh gach iarratais a fhaightear an praghas comhaontaithe gan CBL; tagann an sonrasc míosúil trí ríomhphost (PDF), tá ráiteas na n-iarratas i do chuntas.
  • API: 600 glao / 10 nóiméad in aghaidh na heochrach; webhook: 8 s le freagra a thabhairt, 4 iarracht.
  • Tá teorainn mhéide ar iarratas an chustaiméara (dearadh suas le 350 kB, nóta 4,000 carachtar, grianghraif suas le 2 MB) – diúltaíonn an brabhsálaí do cheann níos mó roimh sheoladh.

Seicliosta roimh dhul beo

  • Tá fearainn do shuímh sa chuntas (glas eochrach) agus luchtaíonn an cumraitheoir ar an leathanach beo.
  • Webhook: síniú fíoraithe thar an amhchorp, 2xx laistigh de 8 s, dúblaigh de réir X-Furniconf-Delivery curtha ar neamhní, tástáil rite.
  • Tá an eochair API i rúin an fhreastalaí; má sceitheann sí gin ceann nua sa chuntas (stopann an seancheann láithreach).
  • Seolann tú stádais iarratais ar ais (status) – tá siad le feiceáil sa chuntas freisin.
  • Faigheann an ceardaí an view-link, ní JSON.
  • Tá billeáil in aghaidh an iarratais socraithe (murach sin tá an cárta Comhtháthú in easnamh).

Cóid earráide (reason)

CódBrí agus réiteach
api_key (401)Tá an eochair fak_… neamhbhailí nó gineadh ceann nua. Seiceáil an ceanntásc Authorization.
integration_off (403)Níl billeáil in aghaidh an iarratais ag an gcuntas – webhook/API neamhghníomhach. Scríobh chugainn.
suspended (403)Tá an cuntas ar fionraí.
rate_limit (429)An iomarca glaonna (600 / 10 nóim). Moilligh, úsáid since.
license, quota, bad_email… (/api/quote)Dhiúltaigh an cumraitheoir don iarratas: ceadúnas/fearann neamhbhailí (license), teorainn mhíosúil sáraithe (quota), ríomhphost/teileafón/fad neamhbhailí (bad_email, bad_phone, too_long), dearadh os cionn 350 kB (too_big).

Tacaíocht

Comhrá go díreach i do chuntas (cárta Tacaíochta) nó ríomhphost; le haghaidh fadhb theicniúil ceangail an reqId ón bhfreagra agus an X-Furniconf-Delivery ón webhook. Tagairt iomlán: PORTAL.md.