Build a Connect integration
Walk through a complete example: connect an org with OAuth, read its donations, and receive webhooks.
This walks through a complete Connect integration end to end, the way a CRM or
church tool would build it: a "Connect with Givebear" button that runs OAuth,
a dashboard that reads the connected org's donations, and a live webhook feed.
It uses the @givebear/connect client for
every call.
The snippets here are TypeScript because the example repo is a Next.js app. Building in another language? The same flow is plain HTTP: authentication and webhooks show every call in curl, Python, PHP, Ruby, and Go.
This example lives in its own repo you can fork and run end to end:
Fork on GitHub
Open in StackBlitz
Prefer a single call with no setup? The quickstart has a paste-and-run snippet.
1. Connect an organization with OAuth
Register an OAuth app under Dashboard -> OAuth apps in your personal
dashboard, then add a "Connect with Givebear" button. The flow is: send the admin to /api/auth/oauth2/authorize,
they approve the scopes for one organization, and you exchange the returned code
for an access token. See authentication
for the full flow and the scopes to request (donations:read, reference:read,
webhooks:write for this example).
Bind a client to the org's token once you have it:
import { GivebearConnect } from "@givebear/connect";
/** A Connect client bound to the session's access token. */
export function givebear(token: string) {
return new GivebearConnect({ token });
}2. Read the connected org's data
With the client, list the organization and its donations. Every credential is scoped to one org, so there is no org id to pass.
const gb = givebear(session.token);
const org = await gb.organization.get();
const { data: donations } = await gb.donations.list({ limit: 25 });Use donations.listAll() to walk every page automatically. See the
API reference for every endpoint.
3. Receive webhooks
Register an endpoint with the client, then verify every delivery with
verifyWebhook. The signing secret is returned once, on creation.
const endpoint = await gb.webhooks.create({
url: "https://your-app.example.com/api/webhooks",
events: ["donation.created"],
});
// Store endpoint.secret now: it is shown only once.import { verifyWebhook, WebhookVerificationError } from "@givebear/connect";
export async function POST(req: Request) {
const body = await req.text();
try {
const event = await verifyWebhook({
secret,
signature: req.headers.get("x-givebear-signature") ?? "",
body,
});
// event.data.id resolves via the read API, e.g. gb.donations.get(event.data.id)
return new Response("ok");
} catch (err) {
if (err instanceof WebhookVerificationError) {
return new Response("Invalid signature", { status: 400 });
}
throw err;
}
}See webhooks for the full event catalog and delivery behavior.
Test webhooks locally
Givebear must reach your app to deliver events, so expose your local server with
a tunnel (cloudflared tunnel --url http://localhost:3000 or ngrok http 3000),
point the endpoint URL at the tunnel, then make a test donation and watch the
event arrive.