Salesforce у благодійності: кейс впровадження CRM для Патронатної служби «Янголи»

Вступ

Мене звати Любов Крохмальна, я керуюча партнерка консалтингової агенції з фандрейзингу Pledge Peak, яка допомагає неприбутковим організаціям і бізнесам системно підходити до залучення коштів та ефективно працювати з донорами.

У межах pro bono співпраці з командою Noltic ми підтримали «Благодійний фонд Патронатна служба «Янголи» у переході до єдиної CRM-системи Salesforce Nonprofit Cloud. Наша робота полягала у тому, щоб підготувати дані, структурувати процеси та адаптувати систему до реальних потреб фонду — так, щоб вона могла забезпечувати прозорість, послідовність і надійну аналітику, які є критично важливими для донорів.

У цьому матеріалі ми з колегами з Noltic та Янголів розповімо, як підготували дані та процеси до переходу в CRM, технічно налаштували інтеграцію з банками та реалізували механізм, який автоматично розпізнає донати й під’єднує їх до відповідних акаунтів донорів.

Про «Янголів»

Патронатна служба «Янголи» існує з 2014 року, її створили у складі тоді ще батальйону «Азов». З початку повномасштабної війни команда «Янголів» опікується пораненими, полеглими та звільненими з полону бійцями Третьої штурмової бригади та інших підрозділів й їхніми родинами. У 2022 році для забезпечення потреб, що значно зросли після повномасштабного вторгнення, було створено благодійну організацію «Благодійний фонд Патронатної служби „Янголи“». Фонд супроводжує захисників на всіх етапах — від лікування і реабілітації до протезування і юридичної підтримки. Також команда займається супроводом родин зниклих безвісти бійців та моніторингом інформації про полонених 3-ї штурмової бригади.

З початком повномасштабної війни обсяги роботи зросли у сотні разів. Разом із підтримкою військових організація щодня обробляє сотні донатів, які спрямовуються на різні напрями діяльності Патронатної служби, а це вимагає чіткої системи обліку, прозорості й швидкого доступу до даних.

Як виникла ідея впровадження CRM

З розширенням діяльності БО «БФ Патронатна служба «Янголи» та збільшенням запитів від Патронатної служби на фінансування зросла і кількість зборів, кампаній та постійних донорів. Інструменти, достатні на ранньому етапі, вже не дозволяли забезпечувати рівень системності та прозорості, необхідний під час активного зростання. Стало зрозуміло, що для цього потрібна централізована система обліку.

Коли у структурі організації з’явився окремий відділ фандрейзингу, виникла потреба у фіксації всієї історії контактів, включаючи як поточних донорів, так і потенційних. Для цього вже було недостатньо електронної пошти чи Google Suite.

Крім того, з появою великих донорів і регулярних внесків стало критично важливо мати інструменти не лише для швидкого формування звітів за будь-який період, а і для глибшої аналітики поведінки донорів: відстеження повторних внесків, реакцій на кампанії, залученості та довгострокових патернів підтримки. Це також стосувалося і аналізу самих кампаній — розуміння, які з них працюють краще, які формати приводять нових донорів, а які мотивують до повторних пожертв.

Тож команда вирішила перейти на CRM-систему, яка допоможе упорядкувати дані, автоматизувати звітність і створити єдину базу донорів. Після аналізу різноманітних рішень на ринку та серії інтерв’ю з українськими та міжнародними НГО щодо їхнього досвіду, разом із командою Noltic було обрано Salesforce Nonprofit Cloud.

На перший погляд, вибір такого потужного бізнес-рішення може здаватися складним для невеликої благодійної організації. Проте БО «БФ Патронатна служба «Янголи» вже давно переросла формат малої ініціативи. Це перша Патронатна служба в Україні, яка продовжує масштабуватися завдяки професійності команди та зростанню потреб у її роботі.

Salesforce запропонував не просто систему для закриття поточних запитів фонду, а платформу, яка дає можливість розвивати функціональність разом з організацією: додавати нові інструменти, автоматизувати процеси та вдосконалювати роботу фандрейзингу без необхідності переходу на інші рішення.

Чому CRM критично важлива для БО

Для великих громадських та неприбуткових організацій CRM є базовою необхідністю та основою довіри. Донори очікують прозорості та чіткості у процесах. Без системного підходу до даних складно масштабувати навіть найкращі ініціативи.

Що дає CRM неприбутковій організації:

  1. Структуровані дані. Кожен донор має окремий профіль із контактною інформацією, історією транзакцій і взаємодій.
  2. Аудит. Керівництво може в реальному часі бачити, які кампанії приносять найбільше результатів.
  3. Прозорість. Автоматичні звіти показують, куди саме надходять кошти, як вони витрачаються, і які програми отримують найбільшу підтримку.
  4. Збереження історії. Нові співробітники чи волонтери підключаються до вже впорядкованої бази.
  5. Менше ручної роботи. Автоматичні процеси економлять години на повторюваних завданнях, наприклад, формування звітів або відправка листів подяки.
  6. Системна комунікація з донорами. Можливо відстежити повну історію взаємодій із кожним донором, а також автоматично надсилати подяки за кожен донат, звітність та персональні оновлення.

Для організації з тисячами донорів і постійними кампаніями відсутність CRM означає втрату частини потенційної підтримки через хаос у даних.

Технічна реалізація Noltic: від Excel до CRM через API

1. Початковий стан: Excel-таблиці

Поки ми чекали на API-ключі, потрібно було зрозуміти, з якою саме інформацією доведеться працювати. Передусім ми визначали ключові поля, які можна використати для автоматичного створення донорів та заповнення їх профілів: Total Donations Amount; Regularity Type; Segmentation By Amount; Donation Frequency; Transaction Number; Transaction Date; Original Amount; Currency Iso Code; Name; Transaction Full Name; EDRPOU(VAT); Processor Reference; Counterparty Account; Counterparty Code; Payment Identifier; PaymentMethod; Status; Bank Name; Bank Branch Line; Banking Account Number.

Спершу ми отримали таблицю в Excel з усіма виписками по транзакціях — на перший погляд, з неї було важко виокремити корисні дані для парсингу у структуровані поля.

Ми почали з обробки даних у самій Excel-таблиці. З’ясувалося, що поділ інформації напряму залежав від джерела переказу. Найбільш зручним ідентифікатором стали ЄДРПОУ ключі банків, завдяки яким можна було розділяти транзакції за джерелами надходжень і виявляти повторювані шаблони у структурі полів. У результаті ми отримали чисті таблиці з чітко виділеними полями для кожного банку.

2. Перехід від таблиць до API-запитів

Після структурування даних у Excel ми змогли перейти до роботи безпосередньо через API. Технічна документація для розробників доступна за посиланням: Google Docs.

Звідти ж ми отримали приклад відповіді з транзакціями за певний проміжок часу:

{
  "status": "SUCCESS", // ознака успішності відповіді
  "type": "transactions", // тип відповіді
  "exist_next_page": true, // ознака наявності наступної пачки
  "next_page_id": "620699370_online", // ідентифікатор наступної пачки (підставляється у followId наступного запиту)
  "transactions": [ // масив об’єктів із транзакціями
    {
      "AUT_MY_CRF": "31451288", // ЄДРПОУ одержувача
      "AUT_MY_MFO": "305299", // МФО одержувача
      "AUT_MY_ACC": "26184050001514", // рахунок одержувача
      "AUT_MY_NAM": "Програмiсти та Ko МСБ-ТЕСТ ТОВ", // назва одержувача
      "AUT_MY_MFO_NAME": "АТ КБ \"ПРИВАТБАНК\"", // банк одержувача
      "AUT_MY_MFO_CITY": "Київ", // назва міста банку
      "AUT_CNTR_CRF": "14360570", // ЄДРПОУ контрагента
      "AUT_CNTR_MFO": "305299", // МФО контрагента
      "AUT_CNTR_ACC": "70214924104032", // рахунок контрагента
      "AUT_CNTR_NAM": "ПРОЦ ВИТР ЗА СТРОК КОШТ СУБ(UAH)", // назва контрагента
      "AUT_CNTR_MFO_NAME": "АТ КБ \"ПРИВАТБАНК\"", // назва банку контрагента
      "AUT_CNTR_MFO_CITY": "Київ", // назва міста банку
      "CCY": "UAH", // валюта
      "FL_REAL": "r", // ознака реальності проведення (r,i)
      "PR_PR": "r", // стан p - проводиться, t - сторнована, r - проведена, n - забракована
      "DOC_TYP": "m", // тип пл. документа
      "NUM_DOC": "K0108B1WKX", // номер документа
      "DAT_KL": "07.01.2020", // клієнтська дата
      "DAT_OD": "07.01.2020", // дата валютування
      "OSND": "Нарахування вiдсоткiв згiдно депозитного договору N...", // підстава  платежу
      "SUM": "0.01", // сума
      "SUM_E": "0.01", // сума в національній валюті (грн)
      "REF": "DNCHK0108B1WKX", // референс проведення
      "REFN": "1", // № з/п всередині проведення
      "TIM_P": "02:58", // час проведення
      "DATE_TIME_DAT_OD_TIM_P": "07.01.2020 02:58:00",
      "ID": "557091731", // ID транзакції
      "TRANTYPE": "C", // тип транзакції дебет/кредит (D, C)
      "DLR": "J63DNDSM0XHY5", // референс платежу сервісу, через який створювали платіж (payment_pack_ref - у разі створення платежу через АPI «Автоклієнт»)
      "TECHNICAL_TRANSACTION_ID": "557091731_online"
            }, {...}
]}

У документації наведено приклад відповіді з транзакціями за певний період. Завдяки попередній роботі з Excel ми вже розуміли, які саме поля з API-відповіді потрібні для подальшої обробки. Це дало змогу перейти до наступного етапу — автоматичного створення донорів.

3. Автоматичне створення донорів

Ключова інформація для формування профілю донора зберігається у таких полях:

  • AUT_MY_CRF — ЄДРПОУ отримувача
  • AUT_CNTR_NAM — ім’я відправника або назва банку
  • OSND — призначення платежу

Ми класифікували транзакції на три типи:

  1. Від бізнес-клієнтів ПриватБанку (ФОП або компанії).
  2. Від приватних клієнтів ПриватБанку.
  3. Від донорів з інших банків.

Для бізнес-донатів ми використовували довжину ЄДРПОУ та назву організації. Для транзакцій від приватних осіб — нормалізоване ім’я та додаткові правила парсингу для кожного банку.

4. Транзакції від бізнес клієнтів ПриватБанку

Даний підтип ділиться на 2 підкатегорії Бізнес донати або донати від підприємців.

При аналізі донатів від підприємців основою аналізу є довжина ЄДРПОУ та прізвище імʼя по-батькові. У випадку коли донат здійснюється з рахунку ФОП чи особистого бізнес рахунку особи, довжина ЄДРПОУ складає 10 символів, і індентифікується, як особистий ЄДРПОУ. Крім того, у полі AUT_CNTR_NAM вказано повне імʼя донора, яке дозволяє аналізувати, що донор здійснював донат не з бізнес рахунку, а з особистого. У такому випадку транзакція буде зарахована до того ж донора.

Донат від бізнесу індентифікується тільки за полем ЄДРПОУ. Довжина ЄДРПОУ для бізнесу на території України складається з 8 символів. Якщо знаходиться повна подібність, значить донат був здійснений тим самим бізнесом. З поля AUT_CNTR_NAM просто перезаписуємо повну назву організації.

5. Транзакції від приватних клієнтів приват банка чи донатів з інших банків

З транзакціями від приватних донорів ситуація трішки складніша. У першому випадку ми у більшості випадків маніпулювали з ЄДРПОУ та їх довжиною, у даному випадку цей варіант не спрацює, адже єдина інформація яку ми знаємо це ЄДРПОУ банка з якого була здійснена транзакція. На даний момент нам вдалося індентифікувати 4 банки, інформацію з яких можна розпарсити, та створити донорів: Приват, Сенс, Кредіагріколь та Райфайзен.

У структурі призначення платежу для кожного з них, є більш детальна інформація про кожного з них, але у різному виді:

Приват Банк
Благодiйна допомога вiйськовим, Петренко Оксана Анатолiївна
Сенс Банк
благодiйна допомога Платник Мельник Тетяна Анатолiївна IПН 2008006007 Рахунок платника UA563003460000026203812101781
КредіАгріколь
БЛАГОДIЙНИЙ ВНЕСОК, ВИСОЦЬКИЙ ВАДИМ БОГДАНОВИЧ
Райфайзен
Янголам Платник: IПН3080312350 СКИРПАЛЬ ОЛЕНА ВОЛОДИМИРIВНА

Для обробки цих даних було реалізовано інтерфейс BankProcessor:

public interface BankProcessor {
    Map<String, String> buildAccountSearchValues(GiftTransaction txn);
}  

Та імплементація для кожного з банків:

ПриватБанк

public class PrivatBank implements BankProcessor {
    public Map<String, String> getAccountSearchValueByIndex(GiftTransaction giftTransaction) {
        if (!giftTransaction.ProcessorReference.contains('опер') && !giftTransaction.ProcessorReference.contains('Продаж UAH клiєнтiв')) {
            String fullName = giftTransaction.FullName__c;
            List<String> separatedFullName = fullName.split(',');
            List<String> fullNameList = separatedFullName.size() > 1 ? separatedFullName.get(1).trim().split(' ') : new List<String>();
            return separatedFullName.size() > 1 ? new Map<String, String>{
                'Full Name' => String.join(new List<String>{
                    (fullNameList.size() > 0 && String.isNotBlank(fullNameList.get(0))) ? fullNameList.get(0).toLowerCase() : 'Last Name',
                    (fullNameList.size() > 1 && String.isNotBlank(fullNameList.get(1))) ? fullNameList.get(1).toLowerCase() : '',
                    (fullNameList.size() > 2 && String.isNotBlank(fullNameList.get(2))) ? fullNameList.get(2).toLowerCase() : ''},
                    ' ').trim()
            } : new Map<String, String>();
        }
        return new Map<String, String>();
    }
}

СенсБанк

public class SensBank implements BankProcessor {
    public Map<String, String> getAccountSearchValueByIndex(GiftTransaction giftTransaction) {
        Integer fullNameIndex = giftTransaction.FullName__c.indexOf('Платник ');
        Integer ITNIndex = giftTransaction.FullName__c.indexOf('IПН ');
        Integer IBANIndex = giftTransaction.FullName__c.indexOf(' Рахунок');
        return new Map<String, String>{
            'EDRPOU' => giftTransaction.FullName__c.substring(ITNIndex + 4, IBANIndex).trim(),
            'Full Name' => giftTransaction.FullName__c.substring(fullNameIndex + 8, ITNIndex).trim().toLowerCase()
        };
    }
}

КредіАгріколь

public with sharing class CrediAgricoleBank implements BankProcessor {
    public Map<String, String> getAccountSearchValueByIndex(GiftTransaction giftTransaction) {
        return new Map<String, String>{
            'Full Name' => giftTransaction.FullName__c.split(',').get(1).trim().toLowerCase()
        };
    }
}

Райфайзен

public with sharing class RaiffeisenBank implements BankProcessor {
    public Map<String, String> getAccountSearchValueByIndex(GiftTransaction giftTransaction) {
        Integer ITNIndex = giftTransaction.FullName__c.indexOf('ІПН');
        return new Map<String, String>{
            'EDRPOU' => giftTransaction.FullName__c.substring(ITNIndex + 3, ITNIndex + 13).trim(),
            'Full Name' => giftTransaction.FullName__c.substring(ITNIndex + 14).trim().toLowerCase()
        };
    }
}

Після того, як ми отримали і звели інформацію з транзакцій до 2 ключових параметрів: ЄДРПОУ та Full Name, можна приступати до створення запису в CRM системі.

Транзакції, які не підпадають під даний аналіз, було додано під загальним донором.
Даний підхід аналізу дозволяє обробляти 99% від усіх транзакцій, які надходять на приват рахунок.

6. Як ми «підшиваємо» банківські транзакції до акаунтів у Salesforce

Проблема. На платформу щодня приходять пожертви з різних банків і в різних форматах: десь є коректний ЄДРПОУ, десь — лише ПІБ у вільній формі, інколи в призначенні платежу з’являється «ФОП». Потрібно автоматично знайти або створити правильний Account (Person Account / Account) і зв’язати його з транзакцією, не виходячи за ліміти Salesforce.

Ідея рішення. Ми обробляємо транзакції батчем і працюємо в два кроки:

  1. Попередня підготовка: з усього пакета витягуємо унікальні ключі (ЄДРПОУ, імена) й одним запитом дістаємо Account. Далі будуємо два «індекси в пам’яті»:
    — мапа для компаній/ФОП (пошук по ЄДРПОУ),
    — мапа для Person Account (пошук по ЄДРПОУ та нормалізованому повному імені).
    Це дає миттєві відповідності без додаткових запитів.
  2. Класифікація кожної транзакції:
    — якщо банк відомий, застосовуємо відповідну стратегію парсингу (виділяє корисні ключі),
    — якщо бачимо «ФОП» чи довжину ЄДРПОУ як у бізнесу — шукаємо в мапі ЄДРПОУ,
    — інакше вважаємо це фізособою й шукаємо за ПІБ/ЄДРПОУ в мапі персон.
    Якщо акаунт не знайдено — готуємо до створення (але не вставляємо одразу).

Один insert, одне оновлення. Після проходу по всіх транзакціях ми разом створюємо всі нові акаунти одним DML і другим кроком масово проставляємо посилання на них у транзакціях. Так ми зберігаємо продуктивність і дотримуємося лімітів (SOQL/DML — поза циклами).

Що це дає на практиці. Обробка тисяч транзакцій за один прогін, стабільне зіставлення навіть із «шумними» даними, просте додавання нових банків (через окремі стратегії парсингу) і ідемпотентність — вже опрацьовані записи не чіпаємо.

Типові граблі і як їх обійти. Непослідовні формати («ФОП» у різних написаннях, пробіли, регістри) — вирішуємо нормалізацією даних і чіткими правилами класифікації. Дублікати — знімаються переходом на upsert за зовнішнім ідентифікатором і дедуплікацією перед вставкою. Для великих обсягів — чанки та Queueable/Batch.

Висновок. Секрет у трьох речах: одна попередня вибірка кандидатів, індекси в пам’яті для швидкого матчингу та уніфікований крок «знайди або створи». Результат — масштабована, стійка до «шуму» та легко розширювана інтеграція банківських транзакцій із акаунтами в Salesforce.

Результати для «Янголів»

До впровадження CRM-системи обробка даних фонду займала години, а звітність вимагала десятків ручних дій. Зараз команда працює в єдиній системі, де всі процеси автоматизовані:

  • Час на обробку донатів скоротився в рази. Кожна транзакція фіксується — система одразу визначає, кому належить внесок та додає його до відповідної кампанії та донора. Команда при цьому бачить повну історію всіх пожертв.
  • Зберігається вся інформація про донорів. Кожен донор має власний профіль, у якому відображається історія його підтримки — суми, дати, участь в певних кампаніях, навіть нотатки про особисті уподобання чи важливі дати. Особливо важливо, що в системі фіксується вся комунікація з донорами всіма членами команди за різні періоди, що забезпечує послідовну та ефективну взаємодію без втрати історії попередніх взаємодій.
  • З’явилася прозорість і контроль у звітності. Уся інформація про кампанії, транзакції та донорів тепер зібрана в одному місці. Система формує автоматичні звіти в реальному часі, як внутрішні, так і для партнерів/донорів.
  • Автоматично формуються подяки донорам. CRM надсилає персоналізовані подяки одразу після підтвердження внеску — особисто, з ім’ям донора. А щомісячні звіти, які раніше займали дні ручної роботи, зараз створюються та розсилаються за кілька хвилин. Більше того, є інструменти для створення майбутніх автоматизованих онлайн кампаній.
  • Нові члени команди можуть одразу включатися в роботу. Вони мають доступ до всієї історії кампаній, контактів, аналітики. Це дозволяє розпочати роботу з першого дня, без довгого занурення в заплутані таблиці та переписки.
«CRM зібрала всю історію фонду в одному місці. Тепер рутинна робота, як облік пожертв і підготовка звітів, займає значно менше часу, тож ми можемо більше взаємодіяти з донорами та шукати нові шляхи їх залучення. Ми бачимо всі донати та аналітику по кампаніям у реальному часі, що допомагає нам швидко реагувати на зміни й будувати прозорі, довірливі відносини з донорами. Для нашої команди це крок до нового рівня ефективності та роботи». — зазначає заступник керівника Патронатної служби «Янголи» з питань БФ та фандрейзингу Володимир Довгополий.

Висновок

Перехід «Янголів» до Salesforce показав просту річ: коли дані впорядковані, з’являється швидкість, контроль і передбачуваність. Технічне рішення було не про «ще одну систему», а про чіткий процес обробки транзакцій та комунікації з донорами.

Що спрацювало найкраще

  • Підготовка та аналіз всіх наявних даних. Попередній аналіз таблиць з усіма транзакціями дав розуміння структур, банківських маркерів і різниць у форматах. Завдяки цьому перехід до API пройшов без хаотичних переробок.
  • Правила класифікації, враховуючи специфіку та потреба організації. Розділення на бізнес, ФОП і приватних донорів з урахуванням довжини ЄДРПОУ та маркерів у призначенні платежу дало точні зіставлення.
  • Окремі процесори для банків. Стратегії парсингу для ПриватБанку, Сенс, Креді Агріколь і Райфайзен спростили підтримку. Додати новий банк тепер означає додати ще один клас.
  • Масові операції. Одна вибірка кандидатів, індекси в пам’яті, один insert акаунтів і одне оновлення зв’язків. Це тримає ліміти Salesforce під контролем і добре масштабується.
  • Політика «знайди або створи». Якщо облікового запису немає, система готує його до створення. Якщо дані нечіткі, транзакція не губиться, а тимчасово «паркується» на загальному донорі.

Практичні поради для розробників

  1. Починайте з інвентаризації даних. Зберіть приклади виписок з різних банків. Випишіть маркери типу «Платник», «ІПН», «Рахунок». Перевірте довжини і формат ідентифікаторів.
  2. Визначте мінімальний набір полів. Для створення донора достатньо надійних ключів на кшталт ЄДРПОУ і нормалізованого ПІБ. Все інше можна добудувати пізніше.
  3. Впровадьте нормалізацію. Зайві пробіли, регістри, варіації «ФОП» знімаються простими функціями очистки рядків і єдиними правилами.
  4. Тримайте SOQL і DML поза циклами. Готуйте списки, працюйте батчами, використовуйте Queueable або Batch, якщо обсяг зростає.
  5. Думайте про дублікати наперед. Використовуйте зовнішні ідентифікатори, upsert і перевірку перед вставкою.
  6. Плануйте безпеку й ролі. Обмежте доступ до фінансових даних. Ролі й профілі мають відповідати реальним обов’язкам команди.

Практичні поради для НУО

  1. Починайте з впорядкування даних. Зберіть усі таблиці, бази контактів і звіти, які вже має ваша команда.
  2. Залучайте команду на ранніх етапах. Визначте, хто відповідальний за збір та переніс даних, аналітику та звітність, створення кампаній та комунікації. Для того, щоб кожен учасник мав доступ в CRM лише в межах своєї ролі.
  3. Визначте, що дійсно потрібно зберігати. Не намагайтеся перенести в систему абсолютно все. Визначте ключові поля — контакти, типи донорів, історію пожертв, дату народження тощо.
  4. Сегментуйте донорів. Наприклад, за сумою внесків та регулярністю внесків, за організаційною формою тощо. Це стане в нагоді для генерації автоматичних звітів та якісного аудиту.
  5. Сплануйте логіку процесів, перш ніж писати технічне завдання. Опишіть, як у вас проходить шлях донорів: від першого внеску до подяки. Це дасть розуміння, які автоматизації справді потрібні.
  6. Приділіть увагу «чистоті» даних. Перевірте дублікати, формат контактних номерів, email-адреси. Це все впливає на якість аналітики та роботи.
  7. Аналізуйте та коригуйте. Після кількох місяців роботи поверніться до процесів і визначте, що працює добре, а що можна спростити. CRM має розвиватися разом із вашою організацією.
👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Підписатись на коментарі