Lumipat sa pangunahing nilalaman

Mga Webhook

Ang mga webhook ay nagpapahintulot sa isang simbahan na mag-push ng real-time na mga notification sa mga third-party na tool — mga automation platform (Zapier, Make, n8n), mga CRM, mga accounting system, o anumang tumatanggap ng HTTP POST. Kapag nagbago ang isang tao, grupo, o sambahayan sa B1, ang B1 ay nagpapadala ng signed na JSON payload sa bawat URL na naka-subscribe sa kaganapang iyon.

Bago Kayo Magsimula

  • Ang isang church admin na may pahintulot na Edit Church Settings ay nagrerehistro at namamahala ng mga webhook
  • Ang inyong receiving endpoint ay dapat maaabot sa HTTPS sa isang pampublikong address
  • Magkaroon ng paraan upang itago ang signing secret nang ligtas — ipinakikita ito nang isang beses lamang

Pangkalahatang Tanawin

Ang mga webhook ay outbound lamang: ang B1 ay tumatawag sa inyong endpoint, hindi kayo tumatawag sa B1. Ang bawat webhook ay isang per-church na subscription na binubuo ng isang destination URL, isang signing secret, at isang listahan ng mga naka-subscribe na kaganapan.

Ang paghahatid ay gumagamit ng durable outbox: kapag nangyari ang isang naka-subscribe na kaganapan, ang B1 ay nagtatalang ng delivery row at ang isang background worker ay nagpo-POST nito sa loob ng humigit-kumulang isang minuto. Ang mga nabigong paghahatid ay sinusubukan muli na may exponential backoff. Walang nawawala kung mabagal ang paghahatid o panandaliang down ang inyong endpoint.

Pagpaparehistro ng Webhook

Sa B1Admin

Pumunta sa Settings → Webhooks → New Webhook. Maglagay ng pangalan, ang payload URL, at piliin ang mga kaganapan kung saan mag-subscribe. Sa pag-save, ang signing secret ay ipinapakita nang isang beses — kopyahin ito kaagad at itago ito sa inyong integration. Hindi na ito muling ipapakita (maaari ninyong i-rotate ito mamaya, ngunit hindi ninyo mababawi ang orihinal).

Sa Pamamagitan ng API

Ang lahat ng endpoint ay nasa ilalim ng Membership module base path /membership/webhooks at nangangailangan ng JWT mula sa isang church admin na may pahintulot na Settings / Edit.

POST /membership/webhooks
Authorization: Bearer <jwt>
Content-Type: application/json

{
"name": "Zapier — new members",
"url": "https://hooks.zapier.com/hooks/catch/123/abc",
"events": ["person.created", "person.updated", "group.member.added"]
}

Ang create response — at lamang ang create response — ay naglalaman ng secret:

{
"id": "a1b2c3d4e5f",
"name": "Zapier — new members",
"url": "https://hooks.zapier.com/hooks/catch/123/abc",
"events": ["person.created", "person.updated", "group.member.added"],
"active": true,
"secret": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822c"
}
Method & PathLayunin
GET /membership/webhooksI-list ang mga webhook ng simbahan (walang secret)
GET /membership/webhooks/eventsAng katalogo ng mga valid na pangalan ng kaganapan
GET /membership/webhooks/:idMag-load ng isang webhook
POST /membership/webhooksLumikha (walang id) o mag-update (na may id)
POST /membership/webhooks/:id/regenerate-secretI-rotate ang signing secret; ibinabalik ang bagong halaga nang isang beses
DELETE /membership/webhooks/:idBurahin ang isang webhook
GET /membership/webhooks/:id/deliveriesMga kamakailang pagtatangka sa paghahatid para sa isang webhook
GET /membership/webhooks/deliveries/:deliveryIdBuong payload at response para sa isang paghahatid
POST /membership/webhooks/deliveries/:deliveryId/redeliverMuling i-queue ang isang paghahatid

Katalogo ng Kaganapan

Ang mga pangalan ng kaganapan ay sumusunod sa pattern na {entity}.{action}. Kunin ang live na listahan mula sa GET /membership/webhooks/events.

KaganapanUmaapoy kapag
person.createdIsang tao ay idinagdag
person.updatedAng rekord ng tao ay binago
person.destroyedIsang tao ay binura
household.createdIsang sambahayan ay idinagdag
household.updatedAng sambahayan ay binago
household.destroyedAng sambahayan ay binura
group.createdIsang grupo ay idinagdag
group.updatedAng grupo ay binago
group.destroyedAng grupo ay binura
group.member.addedIsang tao ay idinagdag sa grupo
group.member.removedIsang tao ay inalis sa grupo

Format ng Payload

Ang bawat paghahatid ay isang HTTP POST na may JSON body at mga header na ito:

HeaderPaglalarawan
Content-TypeLaging application/json
X-B1-EventAng pangalan ng kaganapan, hal. person.created
X-B1-Delivery-IdNatatanging id para sa pagtatangkang ito sa paghahatid — gamitin ito upang mag-deduplicate
X-B1-SignatureHMAC-SHA256 signature ng raw body (tingnan sa ibaba)
X-B1-TimestampUnix epoch seconds kapag ipinadala ang request
User-AgentB1-Webhooks/1.0

Ang body ay nakabalot sa nabagong resource sa isang maliit na envelope:

{
"event": "person.created",
"churchId": "AbC123XyZ90",
"occurredAt": "2026-05-17T14:32:08.114Z",
"data": {
"id": "Pq7Rs2Tu4Vw",
"churchId": "AbC123XyZ90",
"name": { "display": "Jordan Rivera", "first": "Jordan", "last": "Rivera" },
"contactInfo": { "email": "jordan@example.com" }
}
}

Para sa mga kaganapan ng *.destroyed, ang data ay naglalaman lamang ng id at churchId ng binurang rekord.

Pag-verify ng mga Signature

Laging i-verify ang X-B1-Signature bago pagkatiwalaan ang isang payload. Ang signature ay sha256= na sinusundan ng hex HMAC-SHA256 ng raw na request body na kinakabitan ng inyong signing secret. I-compute ito sa mga byte na inyong natanggap — huwag muling i-serialize ang parsed na JSON.

Node.js

const crypto = require("crypto");

function isValid(rawBody, signatureHeader, secret) {
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody, "utf8").digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(signatureHeader || "");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Python

import hashlib, hmac

def is_valid(raw_body: bytes, signature_header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature_header or "")

PHP

function isValid(string $rawBody, string $signatureHeader, string $secret): bool {
$expected = "sha256=" . hash_hmac("sha256", $rawBody, $secret);
return hash_equals($expected, $signatureHeader ?? "");
}

Tanggihan ang anumang request na ang signature ay hindi tumutugma. Opsyonal ding tanggihan ang mga request na ang X-B1-Timestamp ay higit sa ilang minuto ang tanda upang limitahan ang mga replay window.

Paghahatid at Mga Retry

Ang inyong endpoint ay dapat tumugon ng 2xx status nang mabilis hangga't maaari — ideal pagkatapos lamang ng pag-queue ng trabaho, hindi pagkatapos ng pagproseso nito. Ang anumang hindi 2xx na response, pagkabigo sa koneksyon, o response na mas mabagal sa 10 segundo ay binibilang bilang nabigong paghahatid.

Ang mga nabigong paghahatid ay sinusubukan muli na may exponential backoff — 16 na pagtatangka sa humigit-kumulang 5 araw. Ang interval ay lumalaki mula 1 minuto, sa pamamagitan ng mga oras, hanggang sa 3-araw na agwat para sa mga huling pagtatangka. Pagkatapos ng ika-16 na nabigong pagtatangka, ang paghahatid ay minarkahan na exhausted at inabandona.

Ang paghahatid ay at-least-once: ang isang paghahatid ay maaaring dumating nang higit sa isang beses (halimbawa, kung ang inyong endpoint ay nagtagumpay ngunit ang response ay nawala). Gamitin ang X-B1-Delivery-Id header upang mag-deduplicate — iproseso ang bawat id nang isang beses lamang at tratuhin ang mga pag-uulit bilang no-op.

Auto-disabling

Kung ang isang webhook ay gumagawa ng tatlong sunud-sunod na exhausted na paghahatid, ang B1 ay awtomatikong nag-disable nito. Ayusin ang inyong endpoint, pagkatapos ay muling paganahin ang webhook sa B1Admin (o sa pamamagitan ng POST /membership/webhooks na may "active": true).

Pag-inspect at Muling Paghahatid

Ang webhook editor sa B1Admin ay nagpapakita ng Recent Deliveries na talahanayan — kaganapan, status, bilang ng pagtatangka, response code, at timestamp. Ang pagpili ng isang row ay nagbubunyag ng buong payload na ipinadala at ang response na bumalik.

Gamitin ang Redeliver upang muling i-queue ang anumang nakaraang paghahatid na may orihinal na payload — kapaki-pakinabang pagkatapos ayusin ang isang bug sa inyong endpoint, o upang mag-backfill ng mga kaganapan na namiss ng inyong endpoint habang ito ay down.

Mga Kinakailangan sa URL

Dahil ang mga URL ng webhook ay ibinibigay ng simbahan, ang B1 ay nagpapatupad ng mga guards laban sa server-side request forgery. Ang isang URL ng webhook ay tinatanggihan — sa pagpaparehistro at muling sinusuri bago ng bawat paghahatid — kung ito ay:

  • hindi gumagamit ng https
  • tumuturo sa localhost, isang .local / .internal na hostname, o
  • nare-resolve sa private, loopback, link-local, o cloud-metadata na IP address

Ang inyong endpoint ay dapat na isang publicly na maaabot na HTTPS service.