היסטוריית קאשבק שקופה: מדריך התקנה מקיף לחשבון האישי בביטריקס
המשתמש רואה את יתרת הקאשבק שלו אבל אין לו מושג מאיפה היא הגיעה. זוכו 2–3 דולרים—עבור איזו הזמנה? נמחקו 100—מתי ועל איזו רכישה? ללא היסטוריית עסקאות שקופה, כל תוכנית נאמנות מעוררת חוסר אמון. ופשוט "הצגת טבלה מהמסד נתונים" לא מספיקה: צריך פיצ'ינציה נכונה, סינון לפי סוג עסקה, וטיפול נכון באזור זמן.
אנחנו פותרים את הבעיה הזו באופן מקיף: אנחנו מתכננים את טבלת העסקאות, יוצרים קומפוננטה עם ניווט עמודים, מגדירים את הקישור להזמנות, ואם צריך—מיישמים מנגנון פקיעת קאשבק. הניסיון שלנו: 12+ שנים בפיתוח 1C-Bitrix, 80+ פרויקטי מסחר אלקטרוני מוצלחים. אנחנו מבטיחים שהיסטוריית העסקאות תעבוד מהר גם עם 100,000+ עסקאות למשתמש. זמן טעינת עמוד טיפוסי: מתחת ל-150ms.
הבנת הצורך והפתרון
ללא שקיפות, משתמשים מטילים ספק בהגינות התוכנית, מה שמפחית מעורבות. מחקרים מראים ש-70% מהקונים משתתפים באופן פעיל יותר בתוכניות נאמנות שמספקות דוח נקודות מפורט. לכן אנחנו שמים דגש מיוחד על ארכיטקטורת הנתונים ונוחות השימוש בממשק. הגישה שלנו מפחיתה פניות לתמיכה בנושא קאשבק ב-40%.
איך אנחנו מיישמים את טבלת העסקאות
היסטוריית העסקאות מאוחסנת בטבלת local_cashback_transactions. אנחנו משתמשים במבנה אופטימלי עם אינדקס על (USER_ID, CREATED_AT DESC)—זה מאיץ שאילתות פי 10 בהשוואה לסריקה מלאה של הטבלה.
קוד יצירת טבלת SQL
CREATE TABLE local_cashback_transactions ( ID BIGINT AUTO_INCREMENT PRIMARY KEY, USER_ID INT NOT NULL, TYPE ENUM('accrual','debit','reserve','release','expire','manual') NOT NULL, AMOUNT DECIMAL(10,2) NOT NULL, ORDER_ID INT, PAYMENT_ID INT, DESCRIPTION VARCHAR(500), CREATED_AT DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, EXPIRES_AT DATETIME, INDEX idx_user_date (USER_ID, CREATED_AT DESC) ); האינדקס הוא חובה: בלעדיו, שליפת 6 החודשים האחרונים של היסטוריה עבור משתמש פעיל עם אלפי עסקאות הייתה דורשת סריקה מלאה.
סוגי עסקאות וסינון
| סוג | שם | סימן | תיאור |
|---|---|---|---|
| accrual | זיכוי | + | קאשבק עבור הזמנה |
| debit | חיוב | − | קאשבק ששימש לתשלום |
| reserve | עיכוב | − | עיכוב זמני בעת ביצוע הזמנה |
| release | שחרור עיכוב | + | ביטול עיכוב כשההזמנה מבוטלת |
| expire | פקיעה | − | פקיעת קאשבק |
| manual | התאמה ידנית | +/- | התאמה על ידי נציג |
הקומפוננטה מקבלת את פרמטר ה-GET CREATE TABLE local_cashback_transactions ( ID BIGINT AUTO_INCREMENT PRIMARY KEY, USER_ID INT NOT NULL, TYPE ENUM('accrual','debit','reserve','release','expire','manual') NOT NULL, AMOUNT DECIMAL(10,2) NOT NULL, ORDER_ID INT, PAYMENT_ID INT, DESCRIPTION VARCHAR(500), CREATED_AT DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, EXPIRES_AT DATETIME, INDEX idx_user_date (USER_ID, CREATED_AT DESC) ); . ב-type, אנחנו בודקים שהערך נמצא ברשימה המותרת ומחילים את המסנן על השאילתה. זה מאפשר למשתמשים לראות רק פעולות רלוונטיות: לדוגמה, רק זיכויים או רק חיובים.
בניית קומפוננטת היסטוריית העסקאות
אנחנו יוצרים את הקומפוננטה class.php. מבנה:
class.php — логика выборки templates/.default/template.php — шаблон lang/ru/ — языковые файлы /local/components/local/cashback.history/ מרחיב את class.php — логика выборки templates/.default/template.php — шаблон lang/ru/ — языковые файлы ומשתמש ב-D7 ORM כדי לעבוד עם הטבלה. למידע נוסף על גישת הקומפוננטות, ראו תיעוד רשמי של 1C-Bitrix.
קוד מחלקת הקומפוננטה
class CashbackHistoryComponent extends CBitrixComponent { public function executeComponent(): void { if (!$this->getUser()->isAuthorized()) { ShowError('Доступ запрещён'); return; } $userId = (int)$this->getUser()->GetID(); $pageNum = max(1, (int)($_GET['page'] ?? 1)); $pageSize = (int)($this->arParams['PAGE_SIZE'] ?? 20); $typeFilter = $_GET['type'] ?? ''; $filter = ['USER_ID' => $userId]; if (in_array($typeFilter, ['accrual', 'debit', 'expire'])) { $filter['TYPE'] = $typeFilter; } $totalCount = CashbackTransactionTable::getCount($filter); $transactions = CashbackTransactionTable::getList([ 'filter' => $filter, 'order' => ['CREATED_AT' => 'DESC'], 'limit' => $pageSize, 'offset' => ($pageNum - 1) * $pageSize, 'select' => ['ID', 'TYPE', 'AMOUNT', 'ORDER_ID', 'DESCRIPTION', 'CREATED_AT', 'EXPIRES_AT'], ])->fetchAll(); // Подгружаем номера заказов одним запросом $orderIds = array_filter(array_column($transactions, 'ORDER_ID')); $orderNumbers = []; if ($orderIds) { $res = \Bitrix\Sale\Internals\OrderTable::getList([ 'filter' => ['ID' => $orderIds], 'select' => ['ID', 'ACCOUNT_NUMBER'], ]); while ($row = $res->fetch()) { $orderNumbers[$row['ID']] = $row['ACCOUNT_NUMBER']; } } $this->arResult = [ 'BALANCE' => CashbackBalanceTable::getBalance($userId), 'TRANSACTIONS' => $transactions, 'ORDER_NUMBERS' => $orderNumbers, 'TOTAL_COUNT' => $totalCount, 'PAGE_NUM' => $pageNum, 'PAGE_SIZE' => $pageSize, 'TYPE_FILTER' => $typeFilter, ]; $this->includeComponentTemplate(); } } ממשק משתמש ונוחות שימוש
תצוגה ופיצ'ינציה
נקודה חשובה עם פיצ'ינציה: עבור קומפוננטת D7, אנחנו לא משתמשים ב-class.php; אנחנו מחשבים את מספר העמודים בעצמנו:
$totalPages = (int)ceil($arResult['TOTAL_COUNT'] / $arResult['PAGE_SIZE']); קישורי עמודים נוצרים תוך שמירה על המסנן הנוכחי. אנחנו גם מציגים תוויות סוג וסימנים:
$typeLabels = [ 'accrual' => 'Начисление', 'debit' => 'Списание', 'reserve' => 'Резерв', 'release' => 'Возврат резерва', 'expire' => 'Сгорание', 'manual' => 'Ручная корректировка', ]; $amountSign = [ 'accrual' => '+', 'debit' => '−', 'reserve' => '−', 'release' => '+', 'expire' => '−', 'manual' => '', ]; המרת אזור זמן
תאריכים מאוחסנים ב-UTC. כדי להציג אותם באזור הזמן של המשתמש, אנחנו משתמשים ב:
$userTz = new \DateTimeZone(\CTimeZone::GetOffset() ? 'UTC' : date_default_timezone_get()); $dt = new \DateTime($transaction['CREATED_AT'], new \DateTimeZone('UTC')); $dt->setTimezone($userTz); echo $dt->format('d.m.Y H:i'); או דרך CBitrixComponent—זה מתחשב אוטומטית בהגדרות האתר.
קישור להזמנות
עסקאות מסוג class CashbackHistoryComponent extends CBitrixComponent { public function executeComponent(): void { if (!$this->getUser()->isAuthorized()) { ShowError('Доступ запрещён'); return; } $userId = (int)$this->getUser()->GetID(); $pageNum = max(1, (int)($_GET['page'] ?? 1)); $pageSize = (int)($this->arParams['PAGE_SIZE'] ?? 20); $typeFilter = $_GET['type'] ?? ''; $filter = ['USER_ID' => $userId]; if (in_array($typeFilter, ['accrual', 'debit', 'expire'])) { $filter['TYPE'] = $typeFilter; } $totalCount = CashbackTransactionTable::getCount($filter); $transactions = CashbackTransactionTable::getList([ 'filter' => $filter, 'order' => ['CREATED_AT' => 'DESC'], 'limit' => $pageSize, 'offset' => ($pageNum - 1) * $pageSize, 'select' => ['ID', 'TYPE', 'AMOUNT', 'ORDER_ID', 'DESCRIPTION', 'CREATED_AT', 'EXPIRES_AT'], ])->fetchAll(); // Подгружаем номера заказов одним запросом $orderIds = array_filter(array_column($transactions, 'ORDER_ID')); $orderNumbers = []; if ($orderIds) { $res = \Bitrix\Sale\Internals\OrderTable::getList([ 'filter' => ['ID' => $orderIds], 'select' => ['ID', 'ACCOUNT_NUMBER'], ]); while ($row = $res->fetch()) { $orderNumbers[$row['ID']] = $row['ACCOUNT_NUMBER']; } } $this->arResult = [ 'BALANCE' => CashbackBalanceTable::getBalance($userId), 'TRANSACTIONS' => $transactions, 'ORDER_NUMBERS' => $orderNumbers, 'TOTAL_COUNT' => $totalCount, 'PAGE_NUM' => $pageNum, 'PAGE_SIZE' => $pageSize, 'TYPE_FILTER' => $typeFilter, ]; $this->includeComponentTemplate(); } } ו-CDBResult::NavStart מכילות $totalPages = (int)ceil($arResult['TOTAL_COUNT'] / $arResult['PAGE_SIZE']); . הקישור להזמנה נבנה באמצעות $typeLabels = [ 'accrual' => 'Начисление', 'debit' => 'Списание', 'reserve' => 'Резерв', 'release' => 'Возврат резерва', 'expire' => 'Сгорание', 'manual' => 'Ручная корректировка', ]; $amountSign = [ 'accrual' => '+', 'debit' => '−', 'reserve' => '−', 'release' => '+', 'expire' => '−', 'manual' => '', ]; , לא $userTz = new \DateTimeZone(\CTimeZone::GetOffset() ? 'UTC' : date_default_timezone_get()); $dt = new \DateTime($transaction['CREATED_AT'], new \DateTimeZone('UTC')); $dt->setTimezone($userTz); echo $dt->format('d.m.Y H:i'); —זה המספר הציבורי:
/personal/order/detail/{ACCOUNT_NUMBER}/ אם ההזמנה נמחקה, אנחנו מציגים רק את המספר עם הערה "(ההזמנה נמחקה)" ולא מציגים קישור.
תכונות נוספות ושיקולים
מנגנון פקיעת קאשבק
אם הלוגיקה העסקית דורשת שקאשבק יפקע (לדוגמה, אחרי 12 חודשים), השדה \Bitrix\Main\Type\DateTime::createFromTimestamp() מוצג עבור עסקאות accrual. משימת cron רצה פעם ביום ויוצרת עסקאות מסוג debit עבור קאשבק שפקע:
$expired = CashbackTransactionTable::getList([ 'filter' => [ 'TYPE' => 'accrual', '<EXPIRES_AT' => new \Bitrix\Main\Type\DateTime(), 'EXPIRED' => false, ], ]); זה מבטיח שהיתרה תמיד מעודכנת.
מה כלול בעבודה?
- תכנון ויצירת טבלת העסקאות עם אינדקסים
- פיתוח הקומפוננטה עם ניווט עמודים וסינון לפי סוג
- הגדרת המרת אזור זמן
- אינטגרציה עם הזמנות: הצגת קישורים ומספרים
- יישום מנגנון פקיעת קאשבק (אופציונלי)
- בדיקות עומס (עד 10,000 עסקאות למשתמש, מאומתות עם שאילתות מתחת ל-10ms)
- תיעוד מלא (כולל ארכיטקטורה והוראות התקנה)
- גישה למאגר עם בקרת גרסאות
- פגישת הדרכה אחת לצוות שלך (שעה אחת באמצעות שיחת וידאו)
- תמיכה לאחר העלייה לאוויר: שבועיים של תיקוני באגים כלולים
המלצות UX להיסטוריית עסקאות
לנוחות המשתמש, אנחנו ממליצים על קידוד צבעים: זיכויים בירוק (+), חיובים באדום (−), ממתינים באפור. במכשירים ניידים, רשימה קומפקטית עם תאריך, סכום וסוג פעולה היא אופטימלית, עם פרטים מוסתרים כברירת מחדל—הפרטים נפתחים בלחיצה. זה מפחית עומס קוגניטיבי ומגביר אמון בתוכנית הנאמנות. פיצ'ינציה—20 רשומות לעמוד, תוך שמירת המסנן בכתובת ה-URL לשיתוף.
לוחות זמנים ואחריות
לוח זמנים משוער: בין שבוע ל-3 שבועות, תלוי במורכבות (קיום מנגנון פקיעה, נפח נתונים). אנחנו מבטיחים ביצועים גם בעומס גבוה—99% מהשאילתות לטבלה מתבצעות ב-< 10 ms. לצוות שלנו יש 12+ שנות ניסיון בביטריקס ושיעור שביעות רצון של 98% מהלקוחות. צרו קשר לקבלת הערכה מדויקת לפרויקט שלכם. מחיר התחלתי טיפוסי: $1,500 ליישום בסיסי.







