Sign inGet Started

Wysyłanie wiadomości WhatsApp

Ten przewodnik opisuje endpoint wysyłania, POST /v1/whatsapp/messages. Tworzysz jeden ładunek JSON z odbiorcą i dokładnie jednym typem treści: wstępnie zatwierdzonym szablonem albo wiadomością serwisową zawierającą tekst, obraz, wideo, dźwięk, naklejkę, dokument, lokalizację, karty kontaktowe lub element do kliknięcia. Bird zwraca 202 Accepted z identyfikatorem wiadomości i dostarcza ją asynchronicznie. To, który z tych dwóch typów możesz wysłać, zależy od okna obsługi klienta. Każde żądanie wysyła jedną wiadomość do jednego odbiorcy i nie ma endpointu do wysyłki zbiorczej.

Minimalna wysyłka

Najmniejszy prawidłowy ładunek to odbiorca to oraz template z polem slug. Dodaj language, jeśli chcesz wybrać konkretny język; bez tego pola zostanie wysłany domyślny język szablonu. Uzupełnij zmienne zadeklarowane przez szablon za pomocą parameters.

Wywołanie curl używa hosta w USA; jeśli Twój klucz zaczyna się od bk_eu1_, wywołaj zamiast niego https://eu1.platform.bird.com. SDK odczytują region z klucza, więc nie ustawiają hosta.

const msg = await bird.whatsapp.send({
  to: "+15551234567",
  template: {
    slug: "bird_otp",
    parameters: { code: "123456" },
  },
});
console.log(msg.id, msg.status);

Okno obsługi klienta

To, który z tych dwóch typów możesz wysłać, zależy od jednego stanu: czy okno obsługi klienta jest otwarte.

Kontakt otwiera okno, gdy wyśle wiadomość na numer Twojej firmy lub na niego zadzwoni. Okno pozostaje otwarte przez 24 godziny i resetuje się za każdym razem, gdy kontakt ponownie do Ciebie napisze. Gdy jest otwarte, możesz wysłać wiadomość serwisową, czyli dowolną treść: tekst, obraz, wideo, dźwięk, naklejkę, dokument, lokalizację, karty kontaktowe lub treść interaktywną. Po jego wygaśnięciu dotrze do kontaktu tylko wstępnie zatwierdzony szablon, a odpowiedź na niego ponownie otwiera okno.

Bird śledzi okno za Ciebie, więc wiadomość serwisowa wysłana przy zamkniętym oknie zostaje odrzucona, zanim cokolwiek zostanie utworzone lub naliczone: żądanie zwraca 422 E15044 WhatsAppServiceWindowClosed. Sprawdzenie działa w trybie best effort i w razie awarii przepuszcza żądanie, więc 202 nie dowodzi, że okno było faktycznie otwarte w chwili wysyłki. Jeśli okno wygaśnie między przyjęciem a wysyłką, wiadomość kończy się błędem asynchronicznie, z service_window_expired w polu last_error wiadomości.

Pełny cykl życia, czyli co otwiera okno, co je resetuje i jak wpływa na ceny, opisuje strona okno obsługi klienta.

Budowanie ładunku żądania

Odbiorca

to wskazuje jeden cel, podany jako numer telefonu, identyfikator użytkownika w zakresie firmy lub identyfikator grupy. Numer telefonu ma format E.164: początkowy znak +, kod kraju i numer abonenta, na przykład +14155550100. Weryfikujemy numer, więc wartość, która nie może być prawdziwym numerem, pod który da się zadzwonić (zła długość, nieprzydzielony prefiks), zostaje odrzucona z błędem 422 WhatsAppInvalidRecipient, zanim cokolwiek zostanie naliczone. Nie ma tablicy odbiorców ani wysyłki zbiorczej, więc aby dotrzeć do wielu osób spoza jednej grupy, wykonaj jedno wywołanie na każdego odbiorcę.

Identyfikator użytkownika w zakresie firmy, taki jak US.13491208655302741918, adresuje kontakt, którego numeru telefonu nie znasz. W ten sposób odpowiadasz kontaktowi, który napisał do Ciebie bez ujawnienia numeru. Zmieniają się dwie rzeczy: numer nadawcy musi należeć do tego samego portfolio firmowego, do którego przypisany jest identyfikator, a szablon z kodem jednorazowym wymaga numeru telefonu. Szablon zarządzany przez Bird zostaje odrzucony przy przyjęciu z błędem 422 WhatsAppRecipientNotSupportedForTemplate. Szablon uwierzytelniający utworzony przez Twój obszar roboczy zostaje przyjęty, a potem kończy się niepowodzeniem, ponieważ Meta wymaga dla niego numeru telefonu.

to przyjmuje jeszcze jedną postać: identyfikator grupy WhatsApp, taki jak wag_01krdgeqcxet5s7t44vh8rt9mg, który wysyła wiadomość do wszystkich uczestników danego czatu grupowego. Wysyłka do grupy pomija from i raportuje dostarczenie dla całej grupy, a nie dla jednego odbiorcy, dlatego opisuje ją osobna strona Wysyłanie do grupy WhatsApp.

Szablon

template wskazuje zatwierdzony wcześniej szablon do wysłania:

  • slug (wymagane): slug szablonu, na przykład bird_order_confirmation. Musi odpowiadać szablonowi z Twojego katalogu (małe litery, cyfry i podkreślenia).
  • language: tag języka szablonu, na przykład en lub pt-BR. Pomiń go, aby wysłać domyślny język szablonu. Podanie języka, którego szablon nie ma, zwraca błąd 422 z listą dostępnych języków. Przyjęta wiadomość zwraca ustalony język.
  • parameters: wartości wypełniające zmienne szablonu, w postaci jednego obiektu z kluczami według nazw (zobacz Komponenty i parametry). Pomiń je w przypadku szablonu bez zmiennych.
  • components: te same wartości w strukturze komponentów Meta, zamiast parameters. Niektóre szablony przyjmują tylko tę postać.

Przeglądaj swoje szablony, ich języki i podgląd każdego z nich na stronie Templates.

Komponenty i parametry

Szablony zawierają zmienne nazwane ({{ref}}, {{amount}}) lub numerowane ({{1}}, {{2}}). Wypełnij je przez parameters, jeden obiekt. Pole variables wersji szablonu wymienia przyjmowane klucze i oznacza te opcjonalne. Każdy klucz jest jednym z poniższych:

  • własna nazwa zmiennej nazwanej, na przykład order_id
  • numer zmiennej numerowanej, na przykład 1
  • header_url, header_filename lub header_location dla nagłówka z multimediami lub lokalizacją oraz header_url_1, header_url_2 i kolejne dla nagłówka karty karuzeli
  • button_url dla numerowanego sufiksu przycisku URL oraz button_url_1, button_url_2 i kolejne dla przycisku karty karuzeli. Sufiks nazwany przyjmuje własną nazwę.
  • code dla kodu szablonu uwierzytelniającego oraz dla wartości przycisku kopiowania kodu
  • dane wejściowe odczytywane przez powiązania parametrów danego języka

Każda wartość jest ciągiem znaków, liczbą lub wartością logiczną. header_location przyjmuje obiekt z polami latitude i longitude. Pomiń nagłówek z multimediami, aby wysłać zatwierdzoną próbkę szablonu. Szablon zaimportowany z Meta nie ma próbki, więc wymaga klucza nagłówka z multimediami. Klucze, których dany język nie używa, są ignorowane.

Przykład kodu
{
  "to": "+15551234567",
  "from": "+13124495648",
  "template": {
    "slug": "order_update",
    "language": "en",
    "parameters": { "order_id": "A-4192", "first_name": "Ava" }
  }
}

W CLI przekaż obiekt za pomocą --parameters:

Przykład kodu
bird whatsapp send --to +15551234567 --from +13124495648 \
  --template order_update --language en \
  --parameters '{"order_id":"A-4192","first_name":"Ava"}'

Szablon uwierzytelniający, którego treść brzmi {{1}} is your verification code, a przycisk kopiuje kod, przyjmuje kod jeden raz jako code. Bird wstawia go zarówno do treści, jak i do przycisku:

Przykład kodu
{
  "parameters": { "code": "481920" }
}

Języka, którego powiązania odczytują dane kontaktu, na przykład bird.contact.first_name, nie można wysłać jako pojedynczej wiadomości i zwraca on E15091. Zamiast tego wyślij go w ramach broadcastu, w którym wypełniają go dane kontaktu każdego odbiorcy. Broadcast pomija odbiorcę, którego dane kontaktu pozostawiają wymaganą wartość pustą. Wyślij parameters albo components, nie oba naraz. Niektóre szablony przyjmują tylko parameters: szablon, którego język oblicza wartości za pomocą powiązań parametrów, oraz szablon ze zmiennymi nazwanymi w karcie karuzeli lub w adresie URL przycisku.

Niektóre szablony przyjmują tylko components, ponieważ jeden klucz nie pozwala rozróżnić ich miejsc na wartości. Dzieje się tak, gdy szablon numeruje {{1}} w więcej niż jednym bloku, na przykład w nagłówku i w treści. Dzieje się tak również, gdy jeden blok ma dwa przyciski URL z numerowanymi sufiksami albo zmienną {{button_url}} obok numerowanego przycisku URL. Wysłanie takiego szablonu z parameters zwraca 422.

Wypełnianie szablonu według komponentów. components to alternatywa dla parameters i jedyna forma dla szablonu, którego nie da się zaadresować jednym kluczem. Każdy komponent określa type (header, body, button lub carousel) i tablicę parameters. Komponent carousel przyjmuje zamiast niej tablicę cards, z jednym wpisem na każdą zatwierdzoną kartę, w kolejności zatwierdzenia. Każda karta zawiera własną tablicę components z wpisami header, body i button. Każdy parametr określa własny type (text, image, video, gif, document lub location) i zawiera odpowiadające mu pole: text zwykły ciąg znaków, image/video/gif/document publiczny https url, a location punkt na mapie. Szablon z nazwanymi parametrami wymaga name w każdym parametrze, dokładnie zgodnego z nazwami zadeklarowanymi w szablonie (zobacz Opis pól). Szablon pozycyjny pomija name i przyjmuje wartości w kolejności {{n}}, więc pierwszy parametr wypełnia {{1}}. W obu przypadkach parametry niezgodne z deklaracją szablonu zwracają 422 WhatsAppTemplateParameterMismatch. Komponent header w szablonie zarządzanym przez Bird jest pomijany, ponieważ żaden szablon zarządzany przez Bird nie deklaruje zmiennej nagłówka, ale w szablonie utworzonym w Twoim obszarze roboczym jest przekazywany dalej. W ten sposób szablon użytkowy lub marketingowy z nagłówkiem multimedialnym otrzymuje swój obraz.

Ten sam szablon z kodem weryfikacyjnym przyjmuje kod pozycyjnie (bez name) jednocześnie jako parametr treści i parametr przycisku:

Przykład kodu
{
  "components": [
    { "type": "body", "parameters": [{ "type": "text", "text": "481920" }] },
    { "type": "button", "parameters": [{ "type": "text", "text": "481920" }] }
  ]
}

Kategoria i nadawca

Kategoria szablonu (authentication, utility lub marketing) określa, jak WhatsApp traktuje wiadomość, a wraz z krajem docelowym także jej koszt.

To, kto jest właścicielem nadawcy, decyduje, czy go podajesz:

  • Szablon zarządzany przez Bird (jego slug zaczyna się od bird_) jest wysyłany z numeru, który Bird utrzymuje dla tej kategorii, więc pomiń from. Ustawienie go zwraca 422 WhatsAppSenderNotAllowed.
  • Wszystko inne podaje własnego nadawcę w from: wiadomość serwisowa dowolnego typu i każdy szablon utworzony w Twoim obszarze roboczym. Numer musi należeć do Twojego obszaru roboczego. Pominięcie go zwraca 422 WhatsAppSenderRequired, a numer, z którego obszar roboczy nie może wysyłać, zwraca 422 WhatsAppSenderNotFound. Utworzony szablon musi też należeć do tego samego konta WhatsApp Business Account co numer, w przeciwnym razie wysyłka zwraca 422 WhatsAppSenderWABAMismatch.

Konfiguracja numeru telefonu opisuje oba typy numerów oraz sposób podłączenia własnego numeru.

Wiadomości serwisowe

Zamiast template przekaż dokładnie jedno z pól: text, image, video, audio, sticker, document, location, contact_cards lub interactive. Wszystkie dziewięć to wiadomości serwisowe, więc wymagają otwartego okna obsługi klienta. Każda z nich wymaga też from, czyli numeru należącego do Twojego obszaru roboczego; numery zarządzane przez Bird nie mogą ich przesyłać.

  • text: { "body": "..." }, do 4096 znaków. Dodaj "preview_url": true, aby wyświetlić podgląd linku dla pierwszego adresu URL w body.
  • image, video, audio, sticker, document: każde z nich przyjmuje publiczny URL https, który WhatsApp pobiera w chwili wysyłki (url), więc podpisany URL musi pozostać ważny dłużej niż trwa wysyłka. URL http jest od razu odrzucany. WhatsApp sam pobiera plik, więc wiadomość z URL-em, do którego nie może dotrzeć, z URL-em zwracającym nieobsługiwany typ albo z plikiem przekraczającym limit rozmiaru dla danego typu zostaje przyjęta, a następnie kończy się niepowodzeniem, z media_rejected w polu last_error wiadomości i własnym powodem WhatsApp w description. image, video i document przyjmują też opcjonalne caption; document przyjmuje też opcjonalne filename; audio przyjmuje opcjonalną flagę voice, która wyświetla nagranie jako notatkę głosową.
  • location: { "latitude": ..., "longitude": ... } (oba wymagane, w stopniach dziesiętnych) oraz opcjonalnie name i address.
  • contact_cards: tablica do pięciu kontaktów udostępnianych w jednej wiadomości. Pole name każdej wizytówki wymaga formatted_name oraz co najmniej jednej innej części (first_name, last_name, middle_name, prefix lub suffix); phone_numbers, emails, urls i addresses przyjmują po maksymalnie dziesięć wpisów, a org i birthday (jako YYYY-MM-DD) są opcjonalne. Jeśli wizytówka zawiera phone_number w formacie E.164, otrzymuje przycisk otwierający czat z tym numerem.
  • interactive: tekst główny oraz element do dotknięcia, w jednym z sześciu typów: przyciski odpowiedzi, menu listy, przycisk z linkiem, karuzela multimediów albo pojedynczy przycisk z prośbą o lokalizację lub numer telefonu odbiorcy. Strona Wiadomości interaktywne opisuje strukturę każdego typu, odpowiedzi generowane po dotknięciu oraz limity.
Przykład kodu
{
  "to": "+16505551234",
  "from": "+13124495648",
  "text": { "body": "Your order shipped: https://example.com/track/A1B2C3", "preview_url": true }
}

Żądanie bez treści lub z więcej niż jednym typem treści jest odrzucane z kodem 422.

Cytowanie wiadomości

Ustaw in_reply_to_message_id na identyfikator wiadomości WhatsApp, aby wysłać swoją wiadomość jako odpowiedź na nią, tak jak dotknięcie opcji odpowiedzi w aplikacji WhatsApp cytuje wiadomość. Odbiorca widzi Twoją wiadomość z cytowaną wiadomością nad nią, a pole jest zwracane przy każdym odczycie wiadomości.

Działa to również w drugą stronę: wiadomość przychodząca, którą WhatsApp oznacza jako odpowiedź, zawiera w tym samym polu identyfikator cytowanej wiadomości. Dzięki temu wiesz, na którą z Twoich wiadomości odpowiada. Wiadomość przychodząca, której WhatsApp nie oznacza, nie zawiera identyfikatora, a ustalenie cytowanej wiadomości również może się nie udać. Aby niezawodnie powiązać wiadomości, używaj jawnych identyfikatorów odpowiedzi interaktywnych razem ze stanem rozmowy lub zadania zapisanym w Twojej aplikacji. Wychodzące metadata pozostają w rekordzie wiadomości wychodzącej i nie są automatycznie kopiowane do odpowiedzi.

Cytat jest rozpoznawany przed przyjęciem wysyłki, więc cytat, którego nie da się wyświetlić, powoduje odrzucenie samego żądania i nic nie zostaje utworzone ani naliczone. Identyfikator, który nie wskazuje żadnej wiadomości w tym obszarze roboczym, albo wskazuje wiadomość starszą niż 15 dni, przez które wiadomość można cytować, zwraca 404 E15071 WhatsAppReferencedMessageNotFound. Identyfikator wskazujący wiadomość, która nigdy nie dotarła do WhatsApp, albo wiadomość z innej rozmowy niż ta wyznaczona przez to i from tej wysyłki, zwraca 422 E15072 WhatsAppMessageNotQuotable. Jeśli Bird nie może połączyć się z magazynem danych, który to rozstrzyga, wysyłka zwraca 503 E15073 WhatsAppMessageLookupUnavailable; w takim przypadku spróbuj ponownie. Cytowanie działa zarówno przy wysyłce szablonu, jak i wiadomości o dowolnej treści.

Przykład kodu
{
  "to": "+16505551234",
  "from": "+13124495648",
  "in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
  "text": { "body": "Yes, that slot is still free." }
}

Tagi i metadane

Trzy opcjonalne pola dołączają do wiadomości Twój własny kontekst; wszystkie trzy są zwracane przy odczytach API i trafiają do każdego zdarzenia webhooka dotyczącego wiadomości:

  • tags: do 20 ustrukturyzowanych etykiet { "name": ..., "value": ... } dla wymiarów o małej liczbie wartości, według których filtrujesz i raportujesz (kampania, wariant eksperymentu). Nazwy i wartości mogą zawierać litery ASCII, cyfry, podkreślenie i łącznik; nazwy mają maksymalnie 32 znaki i muszą być unikalne w ramach wysyłki, wartości maksymalnie 64 znaki. Filtruj listę wiadomości według tagu (?tag=campaign lub ?tag=campaign:launch-week), a strona Metrics pokazuje dostarczalność w podziale na tagi.
  • metadata: jeden dowolny obiekt JSON, do 2 KB po serializacji, na kontekst pojedynczej wysyłki, którego nie potrzebujesz jako wymiaru filtrowania (wewnętrzny identyfikator zamówienia, odwołanie do sesji).
  • reference: jeden ciąg znaków o długości od 1 do 255 znaków, po którym chcesz wyszukiwać wiadomość, na przykład numer zamówienia lub zgłoszenia. ?reference= na liście wiadomości dopasowuje go dokładnie, z rozróżnieniem wielkości liter, a kilka wiadomości może mieć tę samą wartość. Ustawiaj go tylko wtedy, gdy musisz po nim wyszukiwać, a pozostałe dane umieszczaj w metadata.
Przykład kodu
{
  "tags": [{ "name": "campaign", "value": "order-confirmations" }],
  "metadata": { "order_id": "ord_8271" },
  "reference": "ord_8271"
}

Opis pól

PoleTypWymaganeLimity / uwagi
tostringtakJeden odbiorca na wiadomość: numer telefonu w formacie E.164, identyfikator użytkownika w zakresie firmy, którego nie akceptuje żaden szablon z jednorazowym kodem weryfikacyjnym, lub identyfikator grupy WhatsApp (wag_…), który wysyła wiadomość do wszystkich uczestników tej grupy
fromstring (E.164)nie**Pomiń dla szablonu zarządzanego przez Bird, który sam wybiera nadawcę, oraz dla wysyłki do grupy, która używa numeru tej grupy; wymagane dla wiadomości serwisowej i dla szablonu utworzonego w Twoim obszarze roboczym, a numer musi należeć do Twojego obszaru roboczego
template.slugstringnie**Slug szablonu, który Twój obszar roboczy może wysyłać; slugi zarządzane przez Bird zaczynają się od bird_
template.languagestringnie*Tag języka szablonu (en, pt-BR); pomiń, aby wysłać szablon w jego domyślnym języku
template.parametersobiektnieWypełnia zmienne szablonu według nazwy, np. ref lub code; maksymalnie 16 KB, a bird jest zarezerwowane
template.componentstablicanieAlternatywa dla parameters, jeden wpis na komponent: type to header, body, button lub carousel, a carousel przyjmuje cards zamiast parameters
template.components[].parameters[].namestringnie†Symbol zastępczy, który wypełnia ta wartość, np. ref; w szablonie z nazwanymi parametrami jest wymagany i musi odpowiadać nazwom zadeklarowanym w szablonie, a w szablonie pozycyjnym się go pomija
textobiektnie**Wiadomość serwisowa {body, preview_url?} ze zwykłym tekstem (do 4096 znaków); zobacz Zwykły tekst
image, video, audio, sticker, documentobiektnie**Wiadomość serwisowa z multimediami z url (oraz opcjonalnie caption lub filename, tam gdzie są obsługiwane); zobacz Wiadomości serwisowe
locationobiektnie**Pinezka {latitude, longitude, name?, address?}; zobacz Lokalizacje
contact_cardstablicanie**Maksymalnie 5 ustrukturyzowanych obiektów kontaktów vCard; zobacz Wizytówki kontaktów
interactiveobiektnie**Tekst treści i jeden typ elementu do dotknięcia; to wiadomość serwisowa, więc wymaga otwartego okna obsługi. Zobacz Wiadomości interaktywne
in_reply_to_message_idciąg znakównieIdentyfikator wiadomości WhatsApp przechowywanej w tym obszarze roboczym, cytowanej w wysyłanej wiadomości; zwracany przy odczytach. Zobacz Cytowanie wiadomości
tagstablicanieDo 20 etykiet {name, value}; nazwa ≤ 32 znaki, wartość ≤ 64, nazwy unikalne
referencestringnie1–255 znaków; dokładne dopasowanie dla ?reference= na liście wiadomości
metadataobiektnieDowolny JSON, do 2 KB po serializacji

* language jest opcjonalne; jeśli je pominiesz, zostanie wysłany domyślny język szablonu. † name jest wymagane w każdym parametrze szablonu z nazwanymi parametrami. W szablonie pozycyjnym je pomiń. Zobacz Komponenty i parametry. ** Przekaż dokładnie jedno z dwojga: template albo pole treści wiadomości serwisowej (text, image, video, audio, sticker, document, location, contact_cards, interactive); zobacz Wiadomości serwisowe.

Model asynchroniczny: co oznacza 202

Udane wysłanie zwraca 202 Accepted z identyfikatorem wiadomości i status: accepted. 202 jest zwracany dopiero wtedy, gdy wysyłka zostanie trwale przyjęta; wiadomość nigdy nie jest przyjmowana, a potem po cichu odrzucana. Trwałe błędy, które możesz naprawić, kończą się od razu odpowiedzią 422: nieprawidłowy odbiorca, nieznany slug lub język szablonu, niezgodność parametrów albo wiadomość serwisowa wysłana przy zamkniętym oknie obsługi klienta (WhatsAppServiceWindowClosed). Niezasilony portfel do nich nie należy: wysyłka zostaje przyjęta, a wiadomość kończy się statusem rejected z insufficient_balance, gdy Bird spróbuje ją obciążyć. Faktyczne doręczenie odbywa się asynchronicznie: wiadomość przechodzi w stan sent, gdy przekazujemy ją do WhatsApp, a następnie w status końcowy (delivered lub failed) po nadejściu potwierdzenia. Informują o tym zdarzenia, webhooki i endpointy odczytu. Potwierdzenie odczytu jest udostępniane osobno, jako znacznik czasu read_at i zdarzenie whatsapp.read, a nie jako status.

Uwaga dotycząca prywatności: w przypadku szablonów z kategorii authentication API nigdy nie zwraca wypełnionych wartości. Echo 202 i każdy późniejszy odczyt zawierają dla tych wiadomości pustą tablicę components, więc kod weryfikacyjny nigdy nie pojawia się ponownie.

Bezpieczne ponowne próby

Wysyłaj nagłówek Idempotency-Key z unikalną wartością dla każdej logicznej wysyłki, a ponowne próby staną się bezpieczne. Jeśli pierwsze żądanie się powiodło, ale nie otrzymałeś odpowiedzi (przekroczenie limitu czasu, zerwane połączenie), powtórzenie go z tym samym kluczem zwraca pierwotny wynik zamiast wysyłać zduplikowaną wiadomość i za nią naliczać opłatę. Powtórzona odpowiedź zawiera nagłówek Idempotency-Replay. Format klucza i czas jego przechowywania opisuje strona idempotentność.

Odbieranie odpowiedzi

Wiadomości przychodzące trafiają do tego samego zasobu co wychodzące, a każda z nich resetuje okno obsługi. Strona Odbieranie wiadomości WhatsApp opisuje ich odczyt przez API, pobieranie multimediów wysłanych przez kontakt oraz webhook whatsapp.received.

Koszty i rozliczenia

WhatsApp nalicza opłatę za każdą wiadomość na podstawie kategorii szablonu i kraju odbiorcy; zobacz cennik WhatsApp. Opłata za wiadomość jest naliczana w dwóch krokach, w dwóch różnych momentach, a obiekt cost w wiadomości podaje oba:

PoleCo to jestKiedy się pojawia
transaction_amountOpłata Bird za obsługę wysyłkiGdy Bird przetwarza przyjętą wysyłkę, przed jej nadaniem
passthrough_amountCzęść ceny wiadomości należna Meta, którą Bird przenosi bez zmianGdy nadejdzie odpowiednie potwierdzenie delivered lub read
amountSuma dotychczas wycenionych składnikówRośnie wraz z pojawieniem się każdego składnika
currency_codeWaluta portfela Twojej organizacji, wspólna dla obu składnikówRazem z pierwszym składnikiem

Obie kwoty są ciągami dziesiętnymi, podanymi bez podatku.

Uwaga: do 30 września 2026 r. wiadomość serwisowa nie zawiera udziału Meta, podobnie jak szablon użytkowy dostarczony w otwartym oknie obsługi klienta. Od 1 października 2026 r. Meta pobiera opłaty za oba rodzaje wiadomości, z wyjątkiem 72-godzinnego bezpłatnego okna punktu wejścia, a każdy firmowy numer telefonu ma 1000 bezpłatnych wiadomości serwisowych miesięcznie: zmiany cen od października 2026.

Oba składniki są wyceniane na podstawie różnych danych. Opłata Bird zależy od kategorii wysłanego szablonu i kraju odbiorcy. Kraj wynika z numeru kierunkowego kraju w numerze telefonu, a przy wysyłce na identyfikator użytkownika w zakresie firmy z dwuliterowego prefiksu tego identyfikatora. Udział Meta zależy od kategorii, którą Meta sama zgłasza w odpowiednim potwierdzeniu, i może się ona różnić od kategorii szablonu: Meta może zgłosić authentication-international, gdy mają zastosowanie jej reguły dotyczące miejsca docelowego, lokalizacji firmy i uprawnień. Zobacz stawki authentication-international w WhatsApp.

Zawartość cost zależy od tego, jak daleko dotarła wiadomość:

  • W momencie 202 pole cost ma wartość null. Nic nie zostało jeszcze wycenione.
  • Po przetworzeniu pole transaction_amount jest ustawione, a amount ma tę samą wartość. passthrough_amount pozostaje null.
  • Po odpowiednim potwierdzeniu delivered lub read pomyślnie zarejestrowana opłata Meta wypełnia passthrough_amount, a amount odzwierciedla zarejestrowane składniki.

Składnik o wartości null oznacza, że w tej projekcji nie zarejestrowano żadnej kwoty. Nie dowodzi to, że wiadomość była bezpłatna. Składnik jawnie wyceniony na zero ma wartość "0.00000".

Obie opłaty zawodzą też w różny sposób. Opłata Bird zawodzi w trybie zamkniętym: gdy nie może zostać pobrana po 202, bo portfel nie pokrywa wysyłki lub trasa nie ma skonfigurowanej ceny, wiadomość kończy się stanem rejected z kodem błędu insufficient_balance lub price_not_found i nic nie zostaje pobrane. Wiadomość rejected nigdy nie dotarła do WhatsApp i to odróżnia ją od failed. Udział Meta zawodzi w trybie otwartym: jeśli w chwili nadejścia potwierdzenia w portfelu brakuje środków lub brakuje stawki, opłata zostaje pominięta bez cofania zaobserwowanego stanu wiadomości. Druga opłata nigdy nie wstrzymuje dostarczenia.

Wiadomość obciążona przez Bird zachowuje tę opłatę za wysyłkę, nawet jeśli dostarczenie później się nie powiedzie. Opłata Meta jest przetwarzana z odpowiedniego wywołania zwrotnego delivered lub read, gdy Meta zgłasza zwykłe ceny z kategorią i miejscem docelowym, które da się ustalić. Obie ścieżki wywołań zwrotnych używają tej samej tożsamości opłaty i polegają na deduplikacji w usłudze rozliczeń. Uzgadniaj powtórzone potwierdzenia z rekordami rozliczeniowymi, zamiast traktować projekcję wiadomości jako trwałe potwierdzenie obciążenia. Ceny serwisowe lub ceny bezpłatnego punktu wejścia mogą zerować składnik Meta. Nieustalony składnik nie świadczy o tym, że wiadomość była bezpłatna.

Do uzgodnień finansowych używaj księgi rozliczeń. Pola cost wiadomości są projekcjami opłat i mogą być opóźnione lub niekompletne. Różnicę między obserwacjami wiadomości a rekordami rozliczeniowymi opisuje strona Metryki WhatsApp.

Zdarzenia WhatsApp nie zawierają kosztów. Aby odczytać którykolwiek składnik, pobierz wiadomość ponownie za pomocą GET /v1/whatsapp/messages/{id}.

Dalsze kroki