Shopify Functions w praktyce: jak przełożyć wymagania biznesowe na skuteczną logikę techniczną w checkout
Shopify Functions to stosunkowo nowy mechanizm platformy Shopify, który pozwala programistom na modyfikację logiki backendowej sklepu. Dzięki nim można dostosować domyślne zachowania Shopify do specyficznych potrzeb biznesowych sklepu - zwłaszcza w obszarze procesu składania zamówienia (checkout). W poniższym artykule wyjaśniam, czym są Shopify Functions, jakie dają możliwości, kiedy warto (lub nie warto) z nich korzystać oraz jak podejść do zaprojektowania rozwiązania opartego o Shopify Functions, tak aby skutecznie przełożyć wymagania biznesowe na działającą logikę techniczną.
December 16, 2025
|
Wojciech Muszala
Czym są Shopify Functions?
Shopify Functions to małe, wydajne programy uruchamiane po stronie serwera Shopify, bezpośrednio w infrastrukturze platformy. Umożliwiają one „wstrzyknięcie” własnego kodu w określone punkty procesu zakupowego, modyfikując domyślne działanie sklepu. Innymi słowy, są to rozszerzenia pozwalające na dostosowanie logiki biznesowej Shopify do unikalnych wymagań, których nie da się zrealizować za pomocą standardowych ustawień.
Funkcje te są następcami starszych Shopify Scripts (pisanych w Ruby i dostępnych tylko dla Shopify Plus), które Shopify stopniowo wycofuje - wsparcie dla Shopify Scripts zakończy się w czerwcu 2026 roku. W przeciwieństwie do nich, Shopify Functions są szybsze, bardziej stabilne i łatwiejsze w dystrybucji, ponieważ są uruchamiane w bezpiecznym środowisku WebAssembly na serwerach Shopify, a sprzedawca korzysta z nich poprzez aplikacje (nie musi ręcznie edytować kodu jak w Script Editorze).
Technicznie rzecz biorąc, Shopify Function to fragment kodu (pisany zazwyczaj w językach wysokopoziomowych jak JavaScript/TypeScript lub Rust, kompilowanych następnie do WebAssembly) działający w odpowiedzi na zdarzenie w trakcie checkoutu. Każda funkcja definiuje zapytanie GraphQL (tzw. input query) określające, jakie dane ze sklepu Shopify otrzyma na wejściu - np. zawartość koszyka, dane produktów, informacje o kliencie itp. - dzięki czemu do funkcji trafia dokładnie ten podzbiór danych, który jest potrzebny. Na podstawie tych danych nasz kod wykonuje zaprogramowaną logikę (np. oblicza wysokość rabatu, decyduje o ukryciu danej metody płatności) i zwraca wynik w postaci instrukcji (operacji) do wykonania przez Shopify, zdefiniowanych również schematem GraphQL (tzw. mutation output). Shopify odczytuje wynik i odpowiednio modyfikuje proces checkout - np. stosuje rabat do koszyka albo ukrywa określoną opcję dostawy.
Rysunek: Schemat działania Shopify Functions w procesie checkout - Shopify przekazuje funkcji wymagane dane (Input) poprzez zdefiniowane zapytanie GraphQL, następnie uruchamia kod funkcji (skompilowany do WebAssembly) w swojej infrastrukturze, a ten zwraca zestaw operacji (Output) do wykonania. Całość odbywa się w ułamku sekundy, bez udziału zewnętrznych serwerów, dzięki czemu funkcje nie wpływają negatywnie na czas ładowania się strony dla klienta.
Kilka cech charakterystycznych Shopify Functions, które warto podkreślić:
Działanie backendowe: Funkcje działają pod maską - w warstwie serwerowej Shopify, a nie w przeglądarce użytkownika. Klient odwiedzający sklep nie widzi bezpośrednio, że jakaś „funkcja” została uruchomiona - widzi jedynie efekt jej działania, np. naliczony automatycznie rabat czy ukrytą metodę płatności.
Integracja z platformą: Każda funkcja jest dostarczana w formie aplikacji lub jako część aplikacji. Po zainstalowaniu aplikacji, kod funkcji zostaje osadzony w odpowiednim miejscu logiki sklepu. Shopify sam dba o wywoływanie funkcji we właściwym momencie procesu zakupowego (programista nie musi tworzyć własnych webhooków czy endpointów, aby uruchomić kod - robi to za niego platforma).
Bezpieczeństwo i izolacja: Kod funkcji jest uruchamiany w izolowanym środowisku WebAssembly. Ma to dwie konsekwencje: po pierwsze wydajność - Shopify deklaruje, że kod funkcji wykonuje się w czasie poniżej 5 milisekund, dzięki czemu nawet podczas dużych akcji promocyjnych (typu Black Friday) dodatkowa logika nie spowolni działania sklepu. Po drugie ograniczenia w dostępie - funkcje mają dostęp tylko do tych danych, które zostaną zdefiniowane w zapytaniu GraphQL (oraz ewentualnie do niektórych zasobów konfiguracyjnych sklepu jak metafieldy). Domyślnie funkcje nie komunikują się z zewnętrznymi usługami ani API podczas swojego działania, co gwarantuje szybkość (choć pojawia się już mechanizm tzw. fetch targets pozwalający pobierać dane z zewnętrznego źródła - ograniczony jednak tylko do custom apps na Shopify Plus).
Gdzie znajdują zastosowanie Shopify Functions?
Shopify Functions zostały zaprojektowane głównie z myślą o personalizacji kluczowych etapów procesu zakupu. Obecnie pozwalają na zaawansowane modyfikacje w kilku obszarach checkoutu:
Ta funkcja umożliwia dynamiczne zmiany w dostępnych formach dostawy widocznych dla klienta podczas składania zamówienia. Możemy np. zmieniać nazwy metod dostawy, ukrywać niektóre opcje lub zmieniać ich kolejność na liście.
Przykład zastosowania: sklep oferuje domyślnie opcję „Dostawa lokalna”, ale chciałby dla klientów z konkretnego miasta nazwać ją inaczej - np. „Kurier rowerowy (lokalny)”. Dzięki Shopify Function typu Delivery Customization można wykryć, że kod pocztowy dostawy należy do danego miasta i zmodyfikować nazwę metody dostawy lub całkowicie ukryć/pokazać dodatkową opcję dostawy dla wybranych regionów.
2. Automatyczne rabaty i promocje (Discount Functions)
Jest to bardzo rozbudowany obszar - Shopify Functions pozwalają tworzyć nowe rodzaje reguł promocyjnych wykraczające poza możliwości standardowych kodów rabatowych czy automatycznych zniżek Shopify. Mamy do dyspozycji kilka rodzajów funkcji rabatowych, m.in.:
Order Discount (rabat na całe zamówienie) - np. automatyczne 10% zniżki na całe zamówienie, jeżeli klient doda do koszyka minimum 2 dowolne produkty wykonane z materiałów ekologicznych (np. bambus, stal nierdzewna z recyklingu, bawełna organiczna).
Product Discount (rabat na konkretny produkt/pozycję) - np. promocja „najtańszy produkt w koszyku -20%” albo BOGO (buy one get one free).
Shipping Discount (rabat na dostawę) - np. darmowa wysyłka przy zakupach powyżej 250 zł, ale tylko dla określonej grupy produktów.
Przykład zastosowania: sklep z odzieżą chce zaoferować darmową dostawę dla zamówień, w których wszystkie produkty pochodzą z określonej kategorii (np. „Akcesoria”) i jednocześnie wartość koszyka przekracza 250 zł. Standardowe reguły Shopify nie pozwalają przypisać darmowej dostawy do tak złożonego warunku (kombinacja kategorii produktów i wartości zamówienia), ale można to zaimplementować funkcją typu Shipping Discount. Innym przykładem może być wspomniana wcześniej promocja „-20% na najtańszy produkt w koszyku” - tego typu zniżka wymaga przeanalizowania wszystkich pozycji w koszyku i wybrania tej o najniższej cenie, co idealnie nadaje się do realizacji poprzez Product Discount Function.
3. Personalizacja metod płatności (Payment Customization)
Funkcje tego typu służą do kontroli dostępnych metod płatności w checkout. Pozwalają np. ukryć wybrane metody płatności w określonych sytuacjach lub zmieniać kolejność ich wyświetlania.
Przykład zastosowania: sklep chce promować lokalną bramkę płatniczą (np. Przelewy24) dla klientów z Polski, wyświetlając ją jako pierwszą na liście metod płatności. Payment Customization Function może dynamicznie ustawiać kolejność metod na podstawie kraju klienta. Innym use-case może być ukrycie opcji płatności za pobraniem (COD), jeśli klient wybrał dostawę do paczkomatu lub punktu odbioru osobistego - scenariusz niemożliwy do ustawienia w samym panelu Shopify, ale osiągalny za pomocą funkcji. (Warto jednak dodać, że pewnych metod nie da się przestawić powyżej metod natywnie preferowanych przez Shopify - np. Shop Pay zawsze będzie promowany na górze listy, więc funkcja może co najwyżej zarządzać innymi metodami poniżej niego).
Ten rodzaj funkcji pozwala na programową modyfikację pozycji w koszyku zanim klient sfinalizuje zamówienie. Najczęstszym przypadkiem użycia są tzw. bundles, czyli pakiety produktów. Dzięki Cart Transform API można np. po dodaniu do koszyka określonej kombinacji produktów automatycznie przekształcić je w jeden „wirtualny” produkt-zestaw. Można zmieniać ceny pozycji w koszyku, ich tytuły czy łączyć/rozdzielać pozycje.
Przykład zastosowania: sklep sportowy chce sprzedawać zestaw „Strój sportowy” składający się z koszulki, spodenek i skarpetek w stałej cenie 299 zł. Klient może dodać te rzeczy osobno do koszyka, a funkcja Cart Transform wykryje odpowiedni zestaw i przekształci trzy pozycje w jedną pozycję pakietową (np. zmieniając ich nazwę na "Strój sportowy - zestaw 3w1" i ustawiając cenę 299 zł za całość). Dzięki temu w podsumowaniu zamówienia klient widzi jeden produkt (zestaw) zamiast oddzielnych pozycji, co upraszcza doświadczenie zakupowe.
5. Walidacja koszyka i zamówienia (Cart and Checkout Validation)
Walidacje pozwalają na blokowanie finalizacji zamówienia, jeśli nie spełnia ono określonych warunków biznesowych. Funkcja walidująca może rzucić błąd (uniemożliwiając przejście do płatności) wraz z komunikatem dla klienta, jeśli np. w koszyku brakuje jakiegoś wymaganego elementu lub występuje zabroniona kombinacja.
Przykład zastosowania: sklep sprzedający alkohol może wymagać, by kupujący potwierdził pełnoletność. Jeśli klient nie zaznaczy odpowiedniego checkboxa (np. metafield przy profilu klienta lub custom field w checkout zintegrowany z aplikacją), funkcja walidacyjna może wstrzymać finalizację zamówienia i wyświetlić komunikat typu „Musisz mieć ukończone 18 lat, aby zakupić ten produkt”. Innym przykładem walidacji może być ograniczenie maksymalnej liczby sztuk danego produktu na zamówienie - jeżeli klient próbuje kupić więcej niż dozwolony limit (np. 5 szt.), funkcja może uniemożliwić checkout i poprosić o zmniejszenie liczby przedmiotów.
Jak widać, Shopify Functions pokrywają kluczowe aspekty oferty podczas checkoutu: ceny i rabaty, dostawę, płatność oraz reguły poprawności zamówienia. W każdym z tych obszarów możemy zrealizować unikalną logikę biznesową, która normalnie nie byłaby dostępna w ustawieniach sklepu.
Główne korzyści Shopify Functions
Dlaczego w ogóle warto zainteresować się Shopify Functions? Oto najważniejsze zalety tego rozwiązania z perspektywy wydajności, zarządzania i elastyczności:
Błyskawiczne działanie: Funkcje uruchamiają się w środowisku Shopify, co oznacza brak opóźnień związanych z komunikacją zewnętrzną. Shopify deklaruje, że kod funkcji wykonuje się w czasie <5 ms, a zatem nawet przy dużym ruchu (flash sale, Black Friday) dodanie niestandardowej logiki nie wpływa odczuwalnie na czas obsługi koszyka. To ogromny postęp względem dawnych rozwiązań (np. Shopify Scripts), które działały wolniej i potrafiły spowalniać proces checkout przy bardziej złożonych obliczeniach.
Skalowalność i niezawodność: Ponieważ wszystko działa po stronie serwerów Shopify (w ramach tzw. commerce logic backend), funkcje automatycznie skalują się wraz z obciążeniem. Nie musimy martwić się o wydajność własnego serwera czy instancji - Shopify dba, by funkcje miały zapewnione zasoby. Dodatkowo kod funkcji jest wykonywany w odizolowanym środowisku, z narzuconymi limitami czasu i pamięci, co zapobiega sytuacjom zawieszenia czy przeciążenia (przy zbyt wolnej funkcji Shopify po prostu ją przerwie, aby nie blokować procesu zakupu).
Brak konieczności utrzymania własnej infrastruktury: W przeciwieństwie do tradycyjnych aplikacji (gdzie często musimy stworzyć i utrzymać serwer, bazę danych, API itp.), Shopify Functions nie wymagają od dewelopera stawiania żadnego zaplecza serwerowego. Cała logika jest wdrażana w ramach aplikacji Shopify (hostowanej przez Shopify). Upraszcza to architekturę rozwiązania i eliminuje wiele potencjalnych punktów awarii (brak połączenia, błędy sieci itp.).
Łatwość obsługi dla sprzedawcy: Mimo że Shopify Functions piszą programiści, to ich efekty są często dostępne do zarządzania bezpośrednio w panelu administracyjnym sklepu przez nietechnicznych użytkowników. Na przykład, jeśli aplikacja wprowadza nowy rodzaj rabatu, sprzedawca może tworzyć i konfigurować promocje z wykorzystaniem tej funkcji w znajomym interfejsie Shopify (sekcja Rabaty) - nie musi edytować kodu ani znać się na programowaniu. Podobnie, funkcje dostawy czy płatności mogą oferować w panelu administracyjnym proste ustawienia lub włączniki, dzięki którym merchant decyduje, kiedy dana logika jest aktywna. To duża przewaga - developer przygotowuje narzędzie, a biznes może samodzielnie z niego korzystać i je dostrajać.
Personalizacja i przewaga konkurencyjna: Możliwość zaimplementowania dowolnej logiki biznesowej (w granicach przewidzianych przez Shopify Functions API) otwiera drogę do wyróżnienia się na tle konkurencji. Funkcje pozwalają zaadresować bardzo specyficzne potrzeby - coś, czego nie mają inne sklepy korzystające wyłącznie z natywnych funkcji. Czy to skomplikowany program lojalnościowy z niestandardowymi zniżkami, czy zaawansowane reguły kompletowania zamówień - funkcje dają narzędzia, by to zrealizować i tym samym zaoferować klientom unikatowe doświadczenie zakupowe.
Ograniczenia i ważne uwagi
Oczywiście, Shopify Functions to nie „silver bullet” - mają pewne ograniczenia, o których warto pamiętać podczas planowania rozwiązania:
Ograniczony zakres działania: funkcje działają tylko w określonych punktach procesu zakupu (wspomniane wcześniej obszary). Nie są uniwersalnym mechanizmem do zmiany wszystkiego w sklepie. Jeśli coś dzieje się poza checkoutem (np. na stronie produktu, w koszyku na froncie sklepu, w panelu admina, w procesach fulfillmentu po złożeniu zamówienia), to Shopify Functions nie będą mogły tam ingerować. Ich „świat” to proces kompletowania zamówienia - od momentu dodania produktów do koszyka do momentu finalizacji płatności.
Brak wpływu na interfejs użytkownika: funkcje operują na logice i danych, nie na wyglądzie. Nie można za ich pomocą zmienić układu elementów na stronie checkout czy dodać nowych pól/formularzy (do tego służą inne mechanizmy, jak Checkout UI Extensions, omówione dalej). Shopify Functions decydują co się stanie (np. „ukryj metodę X”, „nalicz rabat Y”), ale jak to jest prezentowane użytkownikowi pozostaje w gestii platformy Shopify i ewentualnych rozszerzeń front-endowych.
Zasada jednej funkcji na dany obszar (w kontekście rabatów): W przypadku funkcji rabatowych trzeba pamiętać, że Shopify nie pozwala jednocześnie zastosować wielu automatycznych promocji naraz z różnych źródeł. Jeżeli zainstalujemy dwie różne aplikacje z funkcjami rabatowymi (albo nawet w jednej aplikacji stworzymy dwa oddzielne rozszerzenia rabatowe dla różnych typów zniżek), to finalnie tylko jeden rabat zostanie automatycznie zastosowany. Shopify wybierze najkorzystniejszy lub domyślnie jedną funkcję - innymi słowy, promocje z różnych funkcji nie „stackują się” standardowo. Istnieje co prawda mechanizm kombinacji rabatów (Discount Combinations) pozwalający łączyć określone oferty, ale wymaga on świadomej konfiguracji po stronie sklepu i spełnienia reguł łączenia. Dlatego dobrą praktyką projektową jest obsłużenie wszystkich potrzebnych reguł promocji w ramach jednej funkcji/rozszerzenia, która zwróci ewentualnie wiele aplikacji rabatowych jednocześnie. Unikniemy w ten sposób konfliktów, gdzie dwie różne funkcje „rywalizują” o to, która naliczy swój rabat. (Analogiczna zasada dotyczy innych obszarów - np. jeśli dwie funkcje próbują zmodyfikować listę metod płatności, efekt może być nieprzewidywalny, więc lepiej mieć jedną funkcję zarządzającą całością logiki płatności).
Dostęp do danych i brak persystencji: funkcje działają bezstanowo - każdorazowo, gdy Shopify je wywołuje, otrzymują pewien snapshot danych (definiowany w zapytaniu GraphQL). Nie mają dostępu do żadnej bazy danych poza tym, co im przekażemy. Nie „pamiętają” nic z poprzedniego wywołania (chyba że zapiszemy coś np. w metafieldach poprzez osobną mutację, ale to już kombinowanie). Nie mogą też same modyfikować trwale danych sklepu poza tym, co przewiduje ich output (np. nie zmienią stałej ceny produktu w katalogu - mogą jedynie wpłynąć na cenę w koszyku). To oznacza, że nie nadają się do logiki wymagającej przechowywania stanu, historii czy do integracji wymagającej wielu kroków (tu lepiej sprawdzi się standardowa aplikacja z własną bazą).
Krótki czas wykonania i brak zewnętrznych połączeń: jak wspomniano, funkcje muszą działać szybko. Domyślnie nie mogą robić wywołań sieciowych (np. do API ERP czy CRM) w trakcie swojego biegu - dzięki temu nie czekamy na odpowiedź i checkout jest płynny. Jednak z tego powodu nie zrealizujemy w function np. sprawdzenia zdolności kredytowej klienta na zewnętrznym serwisie w czasie rzeczywistym - takie rzeczy trzeba obsłużyć inaczej (poza flow checkout). Shopify wprowadza co prawda eksperymentalną możliwość ograniczonego pobrania danych z zewnętrznego API w funkcjach (tzw. fetch target), ale działa to tylko w customowych aplikacjach na Plusie i wymaga dodatkowych zgód - przeciętnie w budowie funkcji zakładamy brak połączeń zewnętrznych.
Podsumowując: Shopify Functions dają potężne możliwości, ale w ściśle określonym zakresie. Trzeba je traktować jako wyspecjalizowane narzędzia do modyfikacji logiki checkoutu, a nie ogólno-pojęte rozwiązanie „każdego problemu” w sklepie.
Wymagania dotyczące planu Shopify (Kto może używać Functions?)
Wraz z wprowadzeniem Shopify Functions pojawiły się pytania o dostępność tej technologii na poszczególnych planach Shopify. Sytuacja wygląda następująco:
Każdy plan Shopify (w kontekście korzystania z gotowych aplikacji): Jeśli korzystasz z publicznych aplikacji dostępnych w Shopify App Store, które mają wbudowane Shopify Functions, to możesz ich używać na dowolnym planie - od Basic, przez Shopify, Advanced, po Plus. Innymi słowy, funkcje dostarczone przez partnerów Shopify w formie aplikacji są dostępne dla wszystkich sklepów, niezależnie od planu. Jest to świetna wiadomość dla mniejszych sklepów - mimo że dawniej zaawansowane modyfikacje checkoutu były domeną tylko Shopify Plus (np. Shopify Scripts), teraz nawet sklep na podstawowym planie może skorzystać z podobnych możliwości poprzez zainstalowanie odpowiedniej aplikacji.
Własne (custom) funkcje - tylko Shopify Plus: Jeśli potrzebujesz stworzyć własną, dedykowaną aplikację z funkcją (czyli tzw. custom app, pisana na potrzeby tylko twojego sklepu lub klienta, niepublikowana w App Store), to niestety musisz mieć plan Shopify Plus. Shopify restrykcyjnie ogranicza możliwość uruchamiania własnego kodu w checkout - tylko sklepy Plus mogą instalować aplikacje custom zawierające funkcje. Z perspektywy biznesu oznacza to, że elastyczność i indywidualne rozwiązania wymagają najwyższego planu. Sklepy na niższych planach są skazane na rozwiązania dostępne publicznie - co zwykle pokrywa większość standardowych potrzeb, ale bardzo specyficzne wymagania mogą wymagać przejścia na Plus (lub znalezienia obejścia czysto front-endowego).
Specjalne funkcje tylko dla Plus: Ponadto, niektóre specyficzne Shopify Function APIs są dostępne wyłącznie dla sklepów Plus (i to często jako custom app). Przykładem są np. funkcje generujące dodatkowe opcje dostawy typu Pickup Point (odbiór w punkcie) czy reguły zaawansowanego routingu zamówień do konkretnych lokalizacji magazynowych. Shopify udostępnia je w trybie early access tylko dla Plusów, bo zwykle dotyczą one większych merchantów z rozbudowaną logistyką. Jeśli więc Twój sklep potrzebuje np. własnej integracji z paczkomatami prezentowanej bezpośrednio w checkout (czyli generowanie listy punktów odbioru w oparciu o zewnętrzny API przewoźnika) - to również będzie wymagało Shopify Plus.
W praktyce, większość standardowych funkcji (rabaty, dostawy, płatności, walidacje) jest dostępna dla wszystkich poprzez publiczne aplikacje. Shopify Plus odblokowuje natomiast pełnię możliwości - tworzenie własnych funkcji od zera oraz używanie tych najbardziej zaawansowanych (często niestandardowych lub jeszcze w fazie beta) rozszerzeń checkoutu.
Shopify Functions a aplikacje - logika i zarządzanie
Każda Shopify Function istnieje w kontekście aplikacji (appki). Warto zrozumieć, jak to wygląda od strony architektury i zarządzania:
Funkcja jako rozszerzenie (extension) aplikacji: W ramach jednej aplikacji Shopify może być zdefiniowanych wiele funkcji (np. jedna od rabatów, druga od płatności, itd.), przy czym każda z nich to osobne extension. Taka aplikacja ma plik konfiguracyjny (shopify.extension.toml) definiujący rozszerzenia, a także osobne foldery z kodem dla każdej funkcji. Dla programisty jest to przejrzyste - tworząc apkę generujemy scaffolding dla danego typu funkcji i piszemy kod niezależnie dla każdego rozszerzenia.
Brak interfejsu graficznego w checkout (UI): Warto podkreślić, że Shopify Functions nie dodają nowych elementów interfejsu same w sobie. To czysto backendowa logika. Jeśli nasza aplikacja jest typu “rabaty”, to jej efekt pojawi się np. w postaci innego przeliczenia ceny w koszyku lub dodatkowej etykiety rabatu, ale nie pojawi się żaden nowy przycisk czy pole w interfejsie checkoutu tylko dlatego, że mamy funkcję. Interfejs checkoutu można modyfikować oddzielnie za pomocą tzw. Checkout UI Extensions (o czym za chwilę). Natomiast aplikacja z funkcjami może posiadać własny panel administracyjny (tzw. UI aplikacji w Shopify Admin), napisany np. w frameworku Remix lub Polaris - i tam programista może udostępnić np. ustawienia dla sprzedawcy czy przyciski do ręcznego wywołania pewnych akcji. Przykładowo, aplikacja rabatowa może mieć w swoim panelu listę reguł promocji, które sprzedawca może włączać/wyłączać. Jednak to już część standardowego frontendu aplikacji osadzonego w Shopify Admin - nie mylić tego z interfejsem sklepu, który widzi klient.
Zarządzanie i wdrażanie zmian: Po zainstalowaniu aplikacji z funkcją, sprzedawca zazwyczaj konfiguruje jej działanie poprzez:
Panel admina aplikacji: tutaj twórcy aplikacji mogą wystawić różne opcje konfiguracyjne. Np. w aplikacji walidującej może być pole do wpisania komunikatu wyświetlanego klientowi przy naruszeniu reguły, przełączniki aktywujące/dezaktywujące daną regułę itp.
Integrację z natywnym panelem Shopify: niektóre funkcje integrują się bezpośrednio. Przykładem są rabaty - po zainstalowaniu aplikacji rabatowej sprzedawca może tworzyć oferty w panelu Rabaty w adminie Shopify, gdzie pojawia się nowy typ rabatu (dostarczony przez aplikację). Tworząc taki rabat, de facto konfiguruje on instancję działania funkcji (przekazuje parametry do funkcji poprzez GraphQL). W efekcie właściciel sklepu czuje się tak, jakby korzystał z natywnej funkcji Shopify, mimo że „pod spodem” działa nasz custom code.
Aktualizacja działania funkcji: Jeżeli po wdrożeniu zajdzie potrzeba zmiany logiki, developer aktualizuje kod funkcji i redeployuje aplikację (np. za pomocą Shopify CLI). Shopify automatycznie zacznie korzystać z nowej wersji kodu. Konfiguracje ustawione przez sprzedawcę pozostają zazwyczaj w mocy (chyba że zmienia się schemat GraphQL wejścia/wyjścia - wtedy potrzebne są migracje).
Współistnienie wielu funkcji: Poruszony już wcześniej temat, ale warty powtórzenia - jeśli planujesz aplikację, która ma wiele funkcji (np. kilka różnych promocji), pamiętaj, że w ramach jednego „targetu” Shopify będzie uruchamiać tylko jedno rozszerzenie. W praktyce oznacza to, że na jeden obszar (np. rabaty) na sklep może działać tylko jedna funkcja jednocześnie. Jeśli zainstalujesz dwie różne aplikacje rabatowe, Shopify i tak przy wyliczaniu rabatu w koszyku skorzysta tylko z jednej (najczęściej tej, która daje największy rabat albo według wewnętrznej kolejności). Podobnie w przypadku walidacji koszyka — Shopify uruchamia tylko jedną funkcję walidującą, dlatego wszystkie warunki powinny być sprawdzane w jednej funkcji, a nie w kilku osobnych. To ważne przy projektowaniu: zamiast tworzyć wiele drobnych appek, rozważ zgrupowanie logiki w jedną, jeśli mają działać równolegle. (Na szczęście problem ten nie dotyczy np. sytuacji, gdy masz funkcję rabatową i funkcję dostawy - one są w różnych obszarach i Shopify uruchomi obie w odpowiednich momentach).
Cykl życia aplikacji wykorzystującej Shopify Functions
Z punktu widzenia pełnego procesu wdrożenia, aplikacja z Shopify Functions przechodzi przez następujące etapy:
Tworzenie i wdrożenie (development & deployment): Programista lub zespół (np. agencja Shopify) tworzy aplikację zawierającą jedną lub wiele funkcji. Pisze kod, testuje go na sklepie deweloperskim i następnie wdraża aplikację. Wdrożenie może oznaczać opublikowanie jej w Shopify App Store (jeśli to aplikacja publiczna) lub zainstalowanie na konkretnym sklepie (jeśli to aplikacja prywatna/custom tworzona dla klienta). W naszym przypadku (firma attomy), często będzie to bezpośrednie wdrożenie na sklep klienta w formie aplikacji custom.
Instalacja i konfiguracja (merchant onboarding): Właściciel sklepu (merchant) instaluje aplikację na swoim sklepie Shopify i dokonuje niezbędnej konfiguracji. Może to być akceptacja żądanych uprawnień, a następnie przejście przez ustawienia aplikacji. Jeśli aplikacja oferuje np. funkcje rabatowe, to na tym etapie sprzedawca tworzy reguły rabatowe (np. definiuje: "10% rabatu na kolekcję X przy zakupie powyżej 200 zł") używając interfejsu udostępnionego przez appkę. Konfiguracja ta zazwyczaj skutkuje wywołaniem mutacji GraphQL do Shopify, która rejestruje naszą funkcję z odpowiednimi parametrami (np. zapamiętuje progowe 200 zł i kolekcję X jako warunki działania rabatu).
Interakcja klienta i wykonanie funkcji (runtime): Gdy wszystko jest gotowe, do gry wkracza klient sklepu. Podczas przeglądania oferty, dodawania produktów do koszyka i finalizacji zakupu Shopify automatycznie uruchamia zainstalowane funkcje w odpowiednich momentach. Jeśli np. klient przechodzi do checkoutu i wpisuje adres, system w tym momencie wywoła funkcję Delivery Customization (aby ewentualnie zmodyfikować opcje dostawy na podstawie adresu). Następnie przed wyświetleniem podsumowania cen uruchomione zostaną funkcje rabatowe (aby obliczyć promocje). Wreszcie, przed pokazaniem metod płatności - funkcje płatności, itd. Klient nie odczuwa w żaden sposób działania tych funkcji poza tym, że zachowanie sklepu jest inne, spersonalizowane. Np. zobaczy od razu naliczony rabat na produkcie albo nie zobaczy metody „Za pobraniem” jeśli nie powinna być dostępna. Wszystko to dzieje się płynnie w trakcie ładowania kolejnych kroków checkoutu (żadnych osobnych przeładowań strony czy oczekiwania - funkcje wykonują się w ułamku sekundy w tle).
Warto tutaj zaznaczyć, że Shopify Functions nie są wywoływane przez żadnego zewnętrznego triggera typu URL czy webhook - to platforma Shopify sama decyduje kiedy i którą funkcję uruchomić w zależności od kontekstu. Naszym zadaniem jako developerów jest tylko poprawnie zarejestrować funkcję (poprzez instalację aplikacji i ewentualne utworzenie np. reguły rabatowej przez merchanta). Resztę robi silnik Shopify.
Podsumowując ten cykl: deweloper dostarcza rozwiązanie, sprzedawca je aktywuje i ustawia, klient końcowy korzysta z e-sklepu i doświadcza efektów działania funkcji, nawet nie wiedząc o istnieniu całego mechanizmu.
Kiedy wystarczą funkcje natywne, a kiedy potrzebne są Shopify Functions?
Przed sięgnięciem po Shopify Functions (czy zleceniem ich napisania), warto zadać pytanie: czy na pewno nie da się tego zrobić prościej? Wiele wymagań biznesowych można zaspokoić za pomocą istniejących funkcji platformy lub gotowych aplikacji, bez konieczności tworzenia niestandardowego kodu. Z drugiej strony, niektóre pomysły z definicji wykraczają poza to, co oferuje standard, i wtedy funkcje będą wybawieniem. Oto, jak rozpoznać jedną i drugą sytuację:
Wymagania obsługiwalne natywnie to takie, które:
Są typowe i przewidziane przez Shopify - np. prosty rabat procentowy na całe zamówienie, darmowa dostawa od pewnej kwoty, podstawowe opcje wysyłki krajowej/zagranicznej, ograniczenie sprzedaży cyfrowych produktów itd. Shopify posiada w panelu administracyjnym szereg wbudowanych ustawień (kody rabatowe, automatyczne zniżki, stawki wysyłki warunkowe, typy produktów wymagające akceptacji regulaminu itd.), które często pokrywają podstawowe scenariusze. Jeśli Twój case biznesowy da się „wyklikać” w adminie Shopify, to zdecydowanie nie ma sensu pisać funkcji - szkoda czasu i pieniędzy.
Mogą zostać zrealizowane istniejącą aplikacją z App Store - zanim zaczniesz tworzyć coś od zera, sprawdź Shopify App Store. Jest duża szansa, że ktoś już stworzył aplikację, która rozwiązuje dany problem. Np. chcesz dodać wyskakujące okienko z upsellem w checkout? Zamiast pisać własne rozszerzenie (co i tak byłoby trudne, bo funkcje nie dotykają UI), możesz skorzystać z aplikacji Checkout Promotions dostępnej publicznie. Albo potrzebujesz prostej walidacji typu „limit 1 sztuka produktu X na zamówienie”? - istnieją aplikacje, które to robią. Oczywiście, gotowe appki mają swoje ograniczenia i często działają „ogólnie” (mogą nie uwzględniać specyfiki Twojego biznesu), ale jeśli pasują w 80-90%, to warto rozważyć ich użycie zamiast inwestować w custom development.
Wymagania uzasadniające użycie Shopify Functions z kolei to te, które spełniają jedno lub więcej z poniższych kryteriów:
Brak natywnej opcji w panelu: Najprostszy test - czy da się to ustawić w Shopify bez kodowania? Jeśli panel administracyjny Shopify nie oferuje danej funkcjonalności, to sygnał, że możemy potrzebować niestandardowej logiki. Np. “ukryj metodę płatności X, gdy wybrano dostawę Y” - nie ma takiego checkboxa w ustawieniach, więc pozostaje custom code. Podobnie, “daj rabat 5% klientom, którzy dokonali już 3 zakupów” - Shopify nie ma natywnej opcji segmentacji rabatu po liczbie poprzednich zamówień klienta. Brak natywnego supportu to pierwszy powód, by pomyśleć o Functions.
Złożone reguły logiczne / wieloetapowe warunki: Jeżeli wymaganie obejmuje unikalny algorytm czy obliczenia, których nie sposób skonfigurować z gotowych klocków, to prawdopodobnie przypadek dla Shopify Functions. Przykładowo: dynamiczne naliczanie rabatu w zależności od struktury koszyka (np. „jeśli koszyk zawiera co najmniej jeden produkt A i dwa produkty B lub jeśli suma kategorii C > 500 zł, to wtedy…”) - takie kombinacje warunków to ewidentnie robota dla kodu. Innym symptomem jest zależność czasowa lub stanowa, np. promocja zmienia się w czasie (za pierwszym zakupem coś, za drugim coś innego) - standardowe narzędzia są statyczne, a Functions mogą zaimplementować własny licznik czy sekwencję (o ile mamy gdzie trzymać dane o stanie, np. w metafieldach klienta).
Wymagania oparte o dane niestandardowe lub zewnętrzne: Jeśli logika ma korzystać z danych, które nie są standardową częścią procesu checkout - np. metafields produktu/klienta, informacje z zewnętrznego systemu lojalnościowego, preferencje użytkownika zapisane gdzieś indziej - to bez kodu się nie obejdzie. Shopify Functions mogą pobierać metafieldy (są dostępne w GraphQL input) i na ich podstawie podejmować decyzje. Np. sprzedawca chce dawać rabat 15% na produkty, które mają metafield „Sezon: Zima 2023” - zwykły kod rabatowy tego nie sprawdzi, a funkcja już tak. Jeśli zaś chodzi o dane całkowicie zewnętrzne (np. wynik zapytania do API pogody - żeby dać rabat jak pada deszcz ;) to, jak wspomniano, jest to trudniejsze bo Functions nie mogą wołać API w locie, ale można ewentualnie zsynchronizować te dane do metafieldów wcześniej i potem użyć w funkcji.
Reasumując, użyj Shopify Functions, gdy potrzebujesz customowej logiki w krytycznym momencie zakupu, a nie masz innej drogi by ją tam umieścić. Jeśli natomiast da się to zrobić konfiguracyjnie lub prostą aplikacją - rozważ najpierw te opcje.
Mapowanie typowych wymagań na odpowiednie Shopify Function APIs
Dla uporządkowania, poniżej tabelka pokazująca, jakiego rodzaju funkcji Shopify należy użyć do danego typu wymagań biznesowych:
Wymagania dotyczące ceny, rabatów i promocji - mapujemy na Shopify Functions z kategorii Discount (Order / Product / Shipping). To wszystkie przypadki, gdzie kluczowe jest zmodyfikowanie ceny, naliczenie upustu, dodanie gratisu itp. Jeśli myślisz “promocja” - myśl “Discount Function”.
Wymagania dotyczące zawartości koszyka i ograniczeń zakupu - mapujemy na Functions z kategorii Cart Transform lub Cart/Checkout Validation. Czyli gdy trzeba programowo zmienić to, co jest w koszyku (bundling, dynamiczne produkty) lub gdy trzeba sprawdzić poprawność zamówienia przed finalizacją (limity, zakazy itp.).
Wymagania logistyczne (wysyłka, dostawa, odbiór) - mapujemy na Functions z kategorii Delivery Customization (a w specyficznych przypadkach na Delivery Option Generators, jeśli tworzymy całkiem nowe opcje dostawy). Tutaj chodzi o wpływanie na ofertę dostawy dla klienta - ukrywanie, dodawanie, zmienianie nazw metod, ewentualnie routing zamówień (np. Order Routing Function, jeśli sklep Plus chce kierować zamówienia do różnych magazynów wedle reguł).
Wymagania dotyczące płatności - mapujemy na Functions z kategorii Payment Customization. Czyli wszystko, co dotyczy bramek płatności: filtrowanie ich listy, sortowanie, warunkowe udostępnianie lub blokowanie metod płatności.
W kontekście modyfikowania checkoutu warto wspomnieć o rozwiązaniu alternatywnym wobec pisania kodu - mianowicie o aplikacjach typu Checkout UI Extensions, często udostępnianych w formie przyjaznych narzędzi „no-code”. Najbardziej znanym takim narzędziem jest aplikacja Checkout Blocks (oficjalna aplikacja Shopify), która pozwala sprzedawcom dodawać własne bloki i elementy do interfejsu checkoutu oraz ustawiać proste reguły działania, bez potrzeby zatrudniania programisty.
Checkout Blocks działa na zasadzie edytora blokowego (drag-and-drop) w panelu Shopify Admin - podobnie jak edycja treści strony w Page Builderach. Pozwala dodawać np. dodatkowe pola tekstowe, komunikaty (np. banner „Dlaczego warto nam zaufać - 100k zadowolonych klientów”), checkboxy z akceptacją warunków, sekcje FAQ w trakcie checkoutu itp. Dodatkowo, aplikacja oferuje pewne proste opcje logiki: np. warunkowe ukrywanie metody płatności lub dostawy na podstawie wartości koszyka czy wyboru klienta. Wszystko to jednak odbywa się w ramach ograniczeń narzuconych przez Shopify - czyli można ukryć coś, co Shopify pozwala ukryć przez UI Extension (np. ukryj opcję „Płatność przy odbiorze” dla zamówień powyżej X zł itp.).
Ważna uwaga:Pełne możliwości modyfikacji checkoutu poprzez Checkout Blocks (czy generalnie UI Extensions) są dostępne tylko dla sklepów na planie Shopify Plus. Dla sklepów na niższych planach Shopify udostępnia jedynie ograniczone pole manewru - w praktyce mogą oni korzystać z takich aplikacji, ale tylko do modyfikacji strony podziękowania (Thank You Page) oraz ewentualnie strony statusu zamówienia. Natomiast nie mogą edytować głównych kroków checkoutu (informacje, dostawa, płatność). Dlatego np. Checkout Blocks zainstalowany na sklepie na planie Basic pozwoli co najwyżej dodać sekcję na stronie potwierdzenia zamówienia, ale nie pozwoli wstawić dodatkowego pola adresowego na stronie wysyłki ani ukryć tam przycisku. Tę funkcjonalność Shopify rezerwuje dla Plusów (co jest jednym z argumentów sprzedażowych dla tego planu).
Zaletą rozwiązań no-code typu Checkout Blocks jest szybkość i prostota - ecommerce manager czy marketer może samodzielnie w kilka minut dokonać drobnej zmiany w checkout, bez cyklu developerskiego. Wadą - ograniczony zakres i elastyczność. Możemy wykonać tylko to, co przewidzieli autorzy aplikacji (np. ustawić 2-3 proste warunki, dodać predefiniowane bloki). Bardzo skomplikowanych rzeczy (jak logika liczenia rabatu czy integracja z systemem lojalnościowym) w ten sposób nie zrobimy.
Podsumowanie: Checkout Blocks i podobne narzędzia są świetne do szybkich, prostych zmian UI/UX w checkout (szczególnie jeśli masz Shopify Plus, by w pełni je wykorzystać). Natomiast głębokie modyfikacje logiki biznesowej - przede wszystkim związane z cenami, promocjami, walidacją - to domena Shopify Functions.
Porównanie sposobów wdrażania niestandardowej logiki w Shopify (Functions vs Blocks vs klasyczna aplikacja)
Na rynku Shopify mamy obecnie trzy główne podejścia do wdrażania niestandardowej logiki czy funkcji w sklepie: Shopify Functions, aplikacje typu Checkout Blocks/UI Extensions, oraz tradycyjne aplikacje (hostowane poza Shopify, komunikujące się przez API/Webhooki). Poniżej porównanie tych rozwiązań pod kilkoma kluczowymi względami:
Porównanie: Shopify Functions vs Checkout Blocks vs Standardowa aplikacja Shopify
Aspekt
Shopify Functions (rozszerzenia funkcji)
Checkout Blocks (UI Extensions)
Standardowa aplikacja Shopify
Czym to jest?
Kod backendowy uruchamiany na serwerach Shopify (Function Extension w aplikacji). Pisany przez programistów.
Gotowa aplikacja z interfejsem graficznym (GUI) do edycji checkoutu. Zazwyczaj no-code (dla użytkownika końcowego).
Samodzielna aplikacja (backend + opcjonalny frontend), działająca poza infrastrukturą Shopify (np. na serwerze w chmurze), komunikująca się z Shopify przez API.
Sposób użycia
Tworzenie kodu w języku obsługiwanym przez Functions (Rust, JavaScript/TypeScript → WebAssembly), definiowanie input/output GraphQL. Wymaga pracy deweloperskiej i wdrożenia aplikacji.
„Wyklikiwanie” zmian w panelu administracyjnym Shopify poprzez edytor bloków. Użytkownik dodaje bloki i ustawia warunki bez pisania kodu.
Instalacja aplikacji przez sprzedawcę, a następnie konfiguracja w panelu aplikacji (o ile oferuje ustawienia). Aplikacja działa niezależnie, często z własnym panelem admin lub dashboardem.
Główne zastosowanie
Bardzo złożona, unikalna logika biznesowa, szczególnie dotycząca cen, promocji, procesu koszyka/checkout:
skomplikowane algorytmy rabatowe
niestandardowe reguły walidacji
personalizacja oferty w checkout
Szybkie zmiany wizualne i drobne modyfikacje zachowania checkoutu:
dodanie pola/komunikatu
ukrycie elementu w prostym warunku (np. wartość koszyka > X)
poprawa UX i elementy marketingowe w checkout
Dodawanie funkcjonalności wykraczających poza checkout:
opinie klientów
integracje e-mail marketingu
program lojalnościowy, raportowanie
customowe integracje z ERP
procesy wymagające dłuższego działania lub zapisu danych
Lokalizacja kodu
Kod wykonywany wewnątrz platformy Shopify (na backendzie Shopify, w ramach procesu checkout). Nie ma osobnego serwera — kod jest częścią systemu Shopify poprzez rozszerzenie.
Kod (UI bloki) renderowany w przeglądarce klienta podczas checkoutu — warstwa frontend (konfigurowana przez panel Shopify). Logika warunków wykonywana jest po stronie Shopify/JS w przeglądarce.
Kod wykonywany poza Shopify — aplikacja ma własny backend (np. serwer Node, AWS Lambda) i korzysta z Admin API, Storefront API, webhooków itd., aby wpływać na sklep.
Wymagany plan
Do instalacji aplikacji publicznej z Functions — dowolny plan (Basic i wyżej). Do stworzenia własnej funkcji (custom app) — wymagany Shopify Plus. Niektóre typy funkcji działają tylko na Plus (np. zaawansowane opcje odbioru osobistego).
Shopify Plus dla modyfikacji głównych kroków checkout (informacje, dostawa, płatność). Na niższych planach — tylko strona statusu zamówienia/podziękowania (bardzo ograniczone).
Zależy od aplikacji — większość publicznych działa na wszystkich planach (zwykle Admin API jest dostępne podobnie na różnych planach).
Elastyczność
Bardzo wysoka w swoim zakresie — można zaprogramować prawie dowolną logikę w granicach API Functions (ograniczenia: dostępne dane i krótki czas wykonania).
Ograniczona do katalogu bloków i warunków przewidzianych przez twórcę. Poza schemat nie wyjdziesz bez kodowania (a wtedy to już własna UI Extension i zwykle Plus).
Wysoka — możesz zbudować dowolny proces/integrację/logikę. Ograniczenia: dostępne API Shopify oraz koszt i złożoność utrzymania; wpływ na checkout zwykle pośredni.
Dla kogo?
Dla programistów i wyspecjalizowanych agencji tworzących aplikacje Shopify. Końcowo zwykle średni/duży sklep (często Plus przy rozwiązaniach custom).
Dla nietechnicznych użytkowników sklepu: sprzedawców, marketerów, managerów e-commerce — szybkie zmiany w checkout pod UX bez dev.
Dla sprzedawców i zespołów potrzebujących funkcji, których Shopify nie ma — najczęściej gotowe app z App Store lub custom dev dla firm z budżetem na dedykowane rozwiązania.
Jak widać, każdy z tych wariantów ma swoje miejsce. Często najlepsze efekty osiąga się łącząc je: np. korzystając z Shopify Functions do logiki cenowej, z Checkout UI Extensions do drobnych zmian w interfejsie, a z klasycznych aplikacji do integracji z systemami zewnętrznymi.
Proces projektowania rozwiązania opartego o Shopify Functions
Załóżmy, że zidentyfikowaliśmy wymaganie biznesowe, którego nie da się zrealizować natywnie i decydujemy się sięgnąć po Shopify Functions. Jak podejść do przełożenia tego wymagania na konkretną implementację? Oto przykładowy proces projektowania funkcji dla scenariusza: „Klienci VIP mają darmową wysyłkę kurierem, jeśli w koszyku nie ma produktów z kategorii Wyprzedaż, a zamówienie przekracza 200 zł”.
Określamy, co dokładnie ma się wydarzyć: kiedy akcja ma nastąpić (przy wyborze dostawy), dla kogo (klienci z tagiem VIP), co zrobić (ustawić darmową wysyłkę kurierem), i pod jakimi warunkami (brak produktów z kategorii Wyprzedaż, wartość zamówienia >200 zł). Spisujemy punkt w procesie, akcję i warunki w formie czytelnego scenariusza.
Krok 2: Wybór odpowiedniego rodzaju funkcji
Decydujemy, na którym Shopify Functions API będziemy działać (w tym przypadku obszar dostawy, czyli funkcja modyfikująca opcje dostawy). Określamy, jakie operacje chcemy wykonać (np. zmiana ceny metody wysyłki, ukrycie opcji, ewentualne nadpisanie parametrów istniejącej metody).
Krok 3: Określenie potrzebnych danych
Spisujemy wszystkie dane, które będą potrzebne do logiki funkcji: tagi klienta (VIP), produkty w koszyku i ich kategorie, wartość całego zamówienia, ewentualnie adres wysyłki czy inne parametry. To pozwala przygotować zapytanie GraphQL i input do funkcji.
Krok 4: Weryfikacja możliwości funkcji
Sprawdzamy, czy wybrane API dostarcza wszystkie potrzebne dane i pozwala wykonać operacje, które chcemy. Upewniamy się, że możemy odczytać tagi klienta, sprawdzić linie koszyka i ich kategorie, oraz że możemy zmodyfikować parametry wybranej metody dostawy. Jeśli jakieś ograniczenia istnieją, planujemy obejścia (np. przygotowanie dodatkowej metody „Kurier VIP” w ustawieniach sklepu, którą funkcja będzie aktywować).
Krok 5: Przygotowanie logiki i implementacja
Tworzymy pseudokod logiki funkcji, określamy input i oczekiwany output. Logika może wyglądać np.: „jeśli klient ma tag VIP, totalAmount >200 zł i żadna linia w koszyku nie należy do kategorii Wyprzedaż, to ustaw koszt wybranej metody kuriera na 0 zł”. Następnie implementujemy funkcję, testujemy różne scenariusze i weryfikujemy poprawność działania przed wdrożeniem.
Taki usystematyzowany proces pomaga uniknąć sytuacji, gdzie “napiszemy funkcję, a potem okaże się, że czegoś jej brakowało” lub że można to było zrobić prościej. Wymaga to pewnej wiedzy o możliwościach Shopify Functions, stąd warto korzystać z dokumentacji i przykładów, jakie Shopify udostępnia.
Kiedy nie stosować Shopify Functions?
Na koniec, warto też wiedzieć, kiedy nie należy sięgać po Shopify Functions, bo są po prostu niewłaściwym narzędziem do zadania. Oto typowe przypadki, gdy lepiej poszukać innego rozwiązania:
Zmiany czysto wizualne w sklepie (frontend/UI): Jeśli celem jest np. zmiana wyglądu strony produktu, dodanie nowych sekcji, zmiana kolejności pól formularza w checkout - Shopify Functions tu nie pomogą. One nic nie renderują w przeglądarce. Do modyfikacji frontendu sklepu służą tradycyjne metody (edycja motywu - Liquid/HTML/CSS/JS) albo nowe rozszerzenia UI (Checkout UI Extensions dla checkoutu, Theme App Extensions dla stron sklepu). Przykład: chcesz dodać zegar odliczający czas do końca promocji na stronie koszyka - zrób to JavaScriptem lub Checkout UI Extension, funkcja się tu nie odnajdzie.
Długotrwałe procesy, integracje wymagające czekania: Jak wcześniej wspomniano, Shopify Functions wykonują się błyskawicznie i nie mogą czekać na zewnętrzne odpowiedzi. Jeśli chcesz np. wysłać zapytanie do API kuriera, żeby obliczyć dynamicznie koszt wysyłki na podstawie kodu pocztowego - funkcja tego nie zrobi (chyba że masz Shopify Plus i użyjesz fetch, ale to nadal dość ograniczone i eksperymentalne). Zamiast tego, takie rzeczy robi się często przed wejściem do checkoutu (np. kalkulator na stronie koszyka komunikujący się z twoim serwerem) albo po złożeniu zamówienia (aplikacja, która edytuje zamówienie poprzez Admin API). Podobnie, generowanie PDF faktury po zakupie - to zadanie dla zwykłej aplikacji (np. odpalanej webhookiem Order Payment), nie dla Functions.
Operacje poza procesem zakupu: Shopify Functions wpinają się w logikę podczas tworzenia zamówienia. Nie mają nic do powiedzenia np. przy zarządzaniu stanem magazynowym, synchronizacji produktów, migracji danych klientów, itp. Nie użyjesz funkcji do automatycznego archiwizowania zamówień 30 dni po realizacji - do tego służy Shopify Flow lub własne skrypty wykorzystujące API. Zawsze pytaj: czy to dotyczy checkoutu (koszyka, płatności, dostawy, rabatu, walidacji zamówienia)? - jeśli nie, funkcje prawdopodobnie odpadają.
Bardzo proste, standardowe wymagania: Paradoksalnie, czasem nie warto używać Functions nawet jeśli się da, bo narzut pracy jest nieproporcjonalny. Np. chcemy wprowadzić rabat -10% na całe zamówienie dla wszystkich klientów przez weekend. Można by napisać funkcję OrderDiscount i ją odpalić… ale po co, skoro Shopify ma natywne kody rabatowe i automatyczne zniżki, które to zrobią bez ani jednej linijki kodu? Podobnie, walidacja „pole kodu pocztowego nie może być puste” - Shopify sam to waliduje. Krótko mówiąc: nie wyważaj otwartych drzwi. Functions są super, gdy drzwi są zamknięte i trzeba je zrobić własnoręcznie. Gdy są uchylone - lepiej skorzystać.
Przykład: Ukrywanie metody płatności na podstawie wagi zamówienia
Na zakończenie przejdźmy przez konkretny przykład techniczny, który ilustruje, jak wygląda Shopify Function w praktyce. Załóżmy następujące wymaganie biznesowe:
Sklep sprzedaje ciężkie towary (np. materiały budowlane) i oferuje opcję płatności za pobraniem (COD - Cash on Delivery). Jednak przy łącznej wadze zamówienia powyżej 300 kg sklep nie chce pozwalać na płatność przy odbiorze (by uniknąć sytuacji, że kurier musi wozić bardzo ciężki towar bez przedpłaty). Wówczas dostępne mają być tylko przedpłacone metody płatności.
Jak to zrealizować? Idealnym miejscem jest funkcja Payment Customization, która pozwoli warunkowo ukryć metodę “Płatność przy odbiorze”. Dla zachowania większej elastyczności dodamy do sklepu metapole określające dopuszczalną wagę przesyłki, które następnie zostaną pobrane przez funkcję i wykorzystane do decydowania, kiedy metoda COD powinna być dostępna. Poniżej omówimy kod takiej funkcji.
Krok 1: Przygotowanie aplikacji i rozszerzenia
Zakładamy, że mamy już stworzoną aplikację (np. za pomocą Shopify CLI). Generujemy nowe rozszerzenie typu payment customization poleceniem CLI:
Kilka wyjaśnień: pobieramy cart.lines - dla każdej linii interesuje nas quantity oraz weight produktu (przy czym merchandise ... on ProductVariant oznacza, że bierzemy wariant produktu i z niego wagę; zakładamy, że waga jest ustawiona w Shopify dla produktu). Nie potrzebujemy innych danych koszyka jak ceny czy adres, bo warunek dotyczy tylko wagi. Dodatkowo pobieramy metapole określające dopuszczalną wagę przesyłki shop.metafield.value., które uprzednio zdefiniowaliśmy i uzupełniliśmy w panelu administratora
Pobieramy też paymentMethods - listę metod płatności (każda ma id i name). Shopify automatycznie uwzględni tu np. że przy danej konfiguracji zamówienia dostępne są określone metody (np. powyżej pewnej kwoty może nie być dostępnych niektórych metod, ale to swoją drogą).
Krok 3: Implementacja logiki w kodzie funkcji (JavaScript)
Edytujemy plik kodu (np. extensions/payment-customization/src/index.js). Załóżmy, że piszemy w JS. Poniżej pseudokod (a właściwie realny kod JS) realizujący założoną logikę:
// Stała pomocnicza oznaczająca brak zmian
const NO_CHANGES = {
operations: [],
};
export function cartPaymentMethodsTransformRun(input) {
// Gdy warunek spełniony - zwracamy operację ukrycia tej metody
return {
operations: [
{
paymentMethodHide: {
paymentMethodId: hidePaymentMethod.id,
},
},
],
};
}
Jak widać, logika jest dość prosta:
Obliczamy totalWeight - iterując po liniach koszyka mnożymy wagę produktu przez jego ilość i sumujemy.
Pobieramy maxWeight z metapola sklepu, który określa dopuszczalną wagę przesyłki.
Jeśli całkowita waga jest poniżej progu 300 kg - kończymy funkcję zwracając pustą listę operacji (NO_CHANGES). Shopify pozostawi listę metod płatności bez zmian.
Jeśli waga przekracza próg - wyszukujemy w dostępnych metodach płatności taką, która nazwa zawiera "Cash on Delivery" (tak zazwyczaj nazywa się płatność za pobraniem w Shopify, choć warto by to sprawdzić w danym sklepie - czasem może być przetłumaczone lub inaczej nazwane).
Jeśli znajdziemy tę metodę, zwracamy w wyniku jedną operację: paymentMethodHide z identyfikatorem tej metody. To instruuje Shopify, by nie wyświetlał tej metody klientowi.
Jeśli nie znajdziemy (co oznacza, że np. i tak nie była dostępna dla tego zamówienia), również nic nie robimy.
Tę funkcję Shopify będzie wywoływać za każdym razem, gdy klient dochodzi do etapu płatności w checkout (lub gdy się tam coś zmieni, np. zmieni adres, co może zmienić metody płatności). Dzięki temu, jeśli klient doda dużo towaru (ciężkiego) - zobaczy np. tylko przelew online/kartę jako opcje płatności. Gdy zmniejszy koszyk - opcja pobrania znów się pojawi (bo warunek przestanie być spełniony i funkcja nie będzie nic ukrywać).
Krok 4: Testy i wdrożenie
Tak zaimplementowaną funkcję testujemy na dev storze lub środowisku testowym: sprawdzamy koszyk o wadze 100 kg (pobranie powinno być widoczne) i koszyk 350 kg (pobranie powinno zniknąć). Jeśli działa - wdrażamy aplikację na produkcję (np. poprzez shopify app deploy i zainstalowanie jej na sklepie Plus klienta, jeśli to custom). Sprzedawca musi jedynie wpisać dopuszczalną wagę produktu w metapolu - funkcja działa globalnie, po prostu w tle egzekwując politykę firmy co do płatności.
To tylko prosty przykład, ale pokazuje on, jak wymaganie biznesowe (limit wagi dla pobrania) przekłada się na konkretną logikę w Shopify Function i jak stosunkowo niewiele kodu potrzeba, by taką regułę wdrożyć do checkoutu.
Shopify Functions stanowią potężne rozszerzenie możliwości platformy Shopify w zakresie personalizacji procesu zakupowego. Pozwalają programistom w kontrolowany, wydajny sposób ingerować w kluczowe momenty checkoutu - od naliczania rabatów, przez oferowanie metod dostawy i płatności, po walidację poprawności zamówienia. Dzięki temu wymagania biznesowe, które kiedyś były niemożliwe do spełnienia (lub wymagały kosztownych obejść), dziś mogą zostać zaimplementowane jako zgrabne kawałki kodu działające pod nadzorem Shopify.
Warto jednak pamiętać, że nie każde zagadnienie wymaga pisania własnej funkcji. Zawsze zaczynamy od oceny, czy prostsze, natywne narzędzia Shopify nie rozwiązują problemu. Gdy decydujemy się na Functions, należy dobrze zaplanować rozwiązanie: wybrać odpowiedni rodzaj funkcji, sprawdzić dostępność potrzebnych danych i operacji, uwzględnić ograniczenia (np. plan Shopify Plus dla własnych funkcji czy brak stackowania wielu promocji) oraz przemyśleć doświadczenie sprzedawcy w zarządzaniu tym rozwiązaniem.
Na horyzoncie Shopify wciąż dynamicznie rozwija ten obszar - pojawiają się nowe typy Functions (np. dotyczące realizacji zamówień, jak Fulfillment Constraints czy Order Routing), ulepszane są istniejące (chociażby bundlowanie produktów przez Cart Transform, które z każdą edycją API dostaje nowe możliwości). Dla sklepów na Plus funkcje stają się naturalnym następcą Scriptów, oferując lepszą wydajność i łatwiejszą obsługę. Dla pozostałych - poprzez aplikacje publiczne - otwierają drzwi do funkcjonalności dotąd zarezerwowanych dla największych graczy.
Shopify Functions w praktyce to zatem sztuka znajdowania równowagi: kiedy ich użyć, jak zaprojektować i jak połączyć z resztą ekosystemu (UI Extensions, zwykłe aplikacje), by osiągnąć zamierzony efekt biznesowy. Mając świadomość możliwości i ograniczeń, możemy projektować naprawdę innowacyjne i skuteczne rozwiązania na Shopify, zapewniając klientom lepsze doświadczenia, a biznesom - przewagę konkurencyjną poprzez personalizację.
Zamów bezpłatną konsultację eCommerce
Co dalej?
Ekspert skontaktuje się z Tobą po przeanalizowaniu Twoich wymagań.
W razie potrzeby podpisujemy NDA, aby zapewnić najwyższy poziom poufności.
Otrzymasz od nas kompleksową propozycję działania wraz z estymacją i harmonogramem.
Dziękujemy za kontakt!
Oops! Something went wrong while submitting the form.