הטמעה בפועל — WordPress, Wix ו‑HTML
הקוד מוכן, הדגל דלוק, הסכימה נשלפה. נשארה השאלה המעשית: איפה מדביקים את זה.
הכלל שמקצר את כל העמוד: נקודות הקצה מקבלות POST של JSON עם שתי כותרות. כל סביבה שמסוגלת לעשות את זה — מהדפדפן או מהשרת — תעבוד. מה שמשתנה בין הפלטפורמות הוא רק איפה מותר להריץ קוד.
מסלול א’ · טופס HTML רגיל
Section titled “מסלול א’ · טופס HTML רגיל”הפשוט ביותר, וגם המומלץ כשאתם שולטים בעמוד: <form> רגיל, מאזין submit, fetch.
<form id="lead-form" novalidate> <input name="fullName" placeholder="שם מלא" /> <input name="phone" type="tel" placeholder="טלפון" required /> <input name="email" type="email" placeholder="אימייל" />
<!-- מלכודת דבש: בוט ימלא, אדם לא יראה --> <input name="company_website" tabindex="-1" autocomplete="off" style="position:absolute;left:-9999px" aria-hidden="true" />
<button type="submit">שליחה</button> <p class="form-msg" role="status" aria-live="polite"></p></form>
<script>const APP_ID = 'הדביקו-כאן-את-ה-Application-Id'; // מזהה ציבורי — מותר בדפדפן
document.getElementById('lead-form').addEventListener('submit', async (e) => { e.preventDefault(); const form = e.currentTarget; const msg = form.querySelector('.form-msg'); const btn = form.querySelector('button'); const f = Object.fromEntries(new FormData(form));
if (f.company_website) { msg.textContent = 'תודה! נחזור אליכם בהקדם.'; return; }
const data = { Name: f.fullName, PhoneNumber: f.phone, Email: f.email }; Object.keys(data).forEach((k) => { if (!data[k]) delete data[k]; });
if (!data.PhoneNumber && !data.Email) { msg.textContent = 'נא למלא טלפון או אימייל'; return; }
btn.disabled = true; try { const res = await fetch(`https://api.mbapps.co.il/functions/${APP_ID}/getlead`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Parse-Application-Id': APP_ID }, body: JSON.stringify(data), }); // onSuccess — שלוש גרסאות בסעיף "מה קורה אחרי ההצלחה" למטה if (res.ok) { onSuccess(await res.json()); return; }
// כל שגיאה עסקית חוזרת כ-400 — מסתעפים על הגוף, לא על הסטטוס const err = (await res.json().catch(() => ({}))).error || ''; msg.textContent = /Disabled/.test(err) ? 'קבלת פניות מהאתר אינה מופעלת כרגע' : /missing/.test(err) ? 'נא למלא טלפון או אימייל תקינים' : 'אירעה שגיאה, נסו שוב'; } catch { msg.textContent = 'אין חיבור לרשת, נסו שוב'; } finally { btn.disabled = false; }});</script>הקוד הזה הורץ כפי שהוא בדפדפן headless (24.08.2026): מול getlead התקבל 200 ו‑onSuccess עם {"result":{"success":true,"leadId":"…"}}, והרשומה אומתה ב‑REST מול Accounts. מלכודת הדבש עצרה את השליחה לפני כל בקשה. (בגרסה קודמת של העמוד הקוד פנה לשם הישן “web2lead” וקיבל 400 {"error":"User function not found"} — זה היה שם שגוי בתיעוד, לא באג.)
מסלול ב’ · WordPress ואלמנטור
Section titled “מסלול ב’ · WordPress ואלמנטור”הדרך הפשוטה: ווידג’ט HTML מותאם
Section titled “הדרך הפשוטה: ווידג’ט HTML מותאם”באלמנטור — ווידג’ט HTML; ב‑Gutenberg — בלוק Custom HTML. מדביקים את הקוד מהמסלול הראשון כמו שהוא. זו הדרך שהכי קל לתחזק ולבדוק, כי אתם שולטים בכל מה שקורה.
שימוש בטופס של התוסף — העברה בצד השרת
Section titled “שימוש בטופס של התוסף — העברה בצד השרת”כשהלקוח כבר משתמש ב‑Elementor Pro Forms, Contact Form 7, WPForms או Gravity Forms ולא רוצה לוותר על מנגנון הטופס — התבנית הנכונה היא hook בצד השרת שמעביר את הנתונים הלאה אחרי שליחה מוצלחת:
<?php// functions.php של תבנית-בת, או תוסף קטן משלכם.// שם ה-hook תלוי בתוסף — זו הדוגמה של Contact Form 7.add_action('wpcf7_mail_sent', function ($contact_form) { $submission = WPCF7_Submission::get_instance(); if (!$submission) return; $posted = $submission->get_posted_data();
$app_id = 'הדביקו-כאן'; $data = array_filter([ 'Name' => $posted['your-name'] ?? null, 'PhoneNumber' => $posted['your-phone'] ?? null, 'Email' => $posted['your-email'] ?? null, ], static fn ($v) => $v !== null && $v !== '');
wp_remote_post("https://api.mbapps.co.il/functions/{$app_id}/getlead", [ 'timeout' => 10, 'headers' => [ 'Content-Type' => 'application/json', 'X-Parse-Application-Id' => $app_id, ], 'body' => wp_json_encode($data), ]);});היתרון: הקוד לא נראה בדפדפן, אפשר להוסיף לוגיקה, וה‑CAPTCHA של התוסף כבר עבר לפני שה‑hook רץ. החיסרון: כשל שקט — אם הקריאה נכשלת, הגולש כבר קיבל “תודה”. תמיד רשמו את התוצאה ללוג ובדקו אותו בימים הראשונים.
מסלול ג’ · Wix
Section titled “מסלול ג’ · Wix”ב‑Wix יש שתי דרכים, ואחת מהן מלכודת:
| הדרך | מתי | הערה |
|---|---|---|
| Velo — קוד עמוד או backend | הדרך הנכונה | קוד שרץ בהקשר של האתר, בלי iframe |
| Embed ← HTML iframe | להימנע | הקוד רץ ב‑iframe מבודד: אין גישה לאלמנטים של העמוד, קשה לעקוב, וההפניה אחרי הצלחה מתנהגת אחרת |
עם Velo, התבנית המומלצת היא לשלוח מפונקציית backend — כך הקוד לא נחשף, ואפשר להוסיף אימות לפני ההעברה:
// backend/crm.jswimport { fetch } from 'wix-fetch';
const APP_ID = 'הדביקו-כאן';
export async function submitLead(form) { const data = { Name: form.fullName, PhoneNumber: form.phone, Email: form.email }; Object.keys(data).forEach((k) => { if (!data[k]) delete data[k]; }); if (!data.PhoneNumber && !data.Email) return { ok: false, error: 'נדרש טלפון או אימייל' };
const res = await fetch(`https://api.mbapps.co.il/functions/${APP_ID}/getlead`, { method: 'post', headers: { 'Content-Type': 'application/json', 'X-Parse-Application-Id': APP_ID }, body: JSON.stringify(data), });
if (res.status === 200) return { ok: true, ...(await res.json()) }; return { ok: false, status: res.status };}// קוד העמודimport { submitLead } from 'backend/crm';
$w.onReady(() => { $w('#submitButton').onClick(async () => { $w('#submitButton').disable(); const r = await submitLead({ fullName: $w('#inputName').value, phone: $w('#inputPhone').value, email: $w('#inputEmail').value, }); $w('#statusText').text = r.ok ? 'תודה! נחזור אליכם בהקדם.' : 'אירעה שגיאה, נסו שוב'; $w('#submitButton').enable(); });});מתי עדיף שרת ביניים
Section titled “מתי עדיף שרת ביניים”שליחה ישירה מהדפדפן היא לגיטימית לחלוטין — ה‑Application Id אינו סוד. אבל בארבעה מצבים שרת ביניים הוא התשובה הנכונה:
| המצב | למה |
|---|---|
| יש CAPTCHA | ה‑secret של ספק ה‑CAPTCHA לא יכול לשבת בדפדפן. אימות שאפשר לדלג עליו אינו אימות |
| לוגיקה נוספת | חישוב, העשרה ממקור נוסף, ניתוב לפי תוכן, שליחה גם ליעד שני |
| לא לחשוף את הקוד | מפות ה‑Pointer, שמות השדות ומבנה הסכימה גלויים בקוד צד לקוח. זו לא דליפת סוד, אבל זה מידע שלא כל לקוח רוצה לפרסם |
| צריך לוג ו‑retry | כשל רשת בדפדפן פשוט נעלם. בשרת אפשר לרשום, לנסות שוב, ולהתריע |
התבנית: הטופס שולח לנקודת קצה שלכם, והשרת מעביר ל‑MyBusiness. דוגמאות מלאות ב‑PHP, Python, Node.js ו‑C# — דוגמאות קוד.
מה קורה אחרי ההצלחה
Section titled “מה קורה אחרי ההצלחה”תשובת 200 היא רק חצי מהחוויה. שלושה דברים לסגור:
1 · הפניה לעמוד תודה
Section titled “1 · הפניה לעמוד תודה”function onSuccess(body) { window.location.href = '/thank-you/';}היתרון: עמוד תודה הוא יעד המרה נקי ל‑Analytics ול‑Google Ads, ואי אפשר לשלוח פעמיים ברענון. החיסרון: הגולש מאבד את ההקשר של הדף.
2 · אישור בתוך העמוד
Section titled “2 · אישור בתוך העמוד”function onSuccess(body) { form.hidden = true; document.getElementById('thanks').hidden = false; // אזור עם role="status"}עדיף בדפי נחיתה ארוכים ובטפסים בתוך מודאל. הקפידו על role="status" ו‑aria-live="polite" כדי שגם קורא מסך יידע שהשליחה הצליחה.
3 · אירוע מדידה
Section titled “3 · אירוע מדידה”function onSuccess(body) { window.dataLayer = window.dataLayer || []; // getlead עוטפת את ההצלחה ב-result; web2table מחזירה שטוח (accountId / Id) window.dataLayer.push({ event: 'form_submit', form_name: 'lead-landing', lead_id: body.result?.leadId }); window.location.href = '/thank-you/';}תשובת ההצלחה מחזירה מזהה שאפשר להעביר הלאה למדידה:
| נקודת הקצה | הגוף (נמדד בפועל) |
|---|---|
web2table |
{ "success": true, "accountId": "<objectId>", "Id": "<objectId של שורת היעד>" } |
web2case |
{ "success": true, "accountId": "<objectId>", "caseId": "<objectId של הפנייה>" } |
getlead |
{ "result": { "success": true, "leadId": "<objectId>" } } — עטוף ב‑result, בשונה משתי האחרות. המזהה ב‑body.result.leadId |
CORS — פתוח כברירת מחדל
Section titled “CORS — פתוח כברירת מחדל”הבקשות האלה הן כמעט תמיד cross‑origin: הדף יושב בדומיין של הלקוח, נקודת הקצה ב‑api.mbapps.co.il. זה עובד — אומת: preflight מחזיר 200 עם Access-Control-Allow-Origin שמהדהד את ה‑Origin.
וגם: תשובות השגיאה נושאות את הכותרת (400 של דגל כבוי, 400 של פונקציה חסרה, ו‑404 של נתיב שגוי). לכן שגיאת CORS אמיתית כמעט לא תיווצר מהן: אם הדפדפן מדווח על CORS, חפשו http:// בעמוד https://, תוסף חוסם, או iframe מוגבל. הבדיקה הראשונה: הריצו את אותה בקשה ב‑curl — אבחון לפי תסמין.
רשימת בדיקה לפני עלייה לאוויר
Section titled “רשימת בדיקה לפני עלייה לאוויר”- הדגל המתאים דלוק ב‑
Config— שורה אחת בלבד - הטופס נבדק בעמוד חי, לא רק בעורך
-
preventDefaultקיים, וכפתור השליחה ננעל בזמן הבקשה — בלעדיו לחיצה כפולה מייצרת שתי רשומות (אומת: כל קריאה מוסיפה שורה) - הטיפול בשגיאות מסתעף על גוף התשובה, לא על 403/422 — הכול חוזר כ‑400
- יש מלכודת דבש, או CAPTCHA שמאומת בשרת ביניים
- אירוע ההמרה נשלח רק אחרי
200 - נבדק מהנייד, לא רק מהדסקטופ
- הרשומה שנוצרה נבדקה בתוך המערכת — כל השדות שנשלחו אכן שם. זו הבדיקה החשובה ביותר:
200אינו מעיד על כלום
- getlead · web2table — החוזה המלא
- דוגמאות קוד — PHP · Python · Node.js · C# · JavaScript
- מודל האבטחה — CAPTCHA, סודות, ומה לא לפתוח
- אבחון תקלות