Documentation for starnerz/laravel-daraja, a Laravel package for the Safaricom M-Pesa Daraja APIs.
Published at https://laraveldaraja.com/. It moved there from a GitHub Pages project site on 1 September 2026; DOMAIN-SWITCH.md records how, and what is still open.
Requires Node 22.12 or higher — Astro rejects older and odd-numbered releases.
.nvmrc pins the major version.
npm install
npm run dev # http://localhost:4321/daraja-docs
npm run build # writes to dist/
npm run preview # serve the built siteRegenerate the lock file with the npm the CI runner uses, not whatever is
installed locally. Node 22 ships npm 10; npm 11 omits optional dependencies —
@emnapi/runtime, reached through sharp's wasm fallback — that npm 10's
npm ci then refuses to install:
npx npm@10 install --package-lock-onlysrc/
├── content/docs/
│ ├── index.mdx landing page
│ ├── getting-started/ install, configure, sandbox
│ ├── tutorials/ start-to-finish integrations
│ ├── apis/ one page per API family
│ ├── guides/ callbacks, testing, credentials, going live
│ ├── reference/ config, events, exceptions, commands, error codes
│ ├── upgrade/ 4.x to 5.0
│ ├── changelog.md generated — see below
│ └── legal/ privacy policy
├── components/ HireMe, AnalyticsPolicy
├── pages/
│ ├── og/[...route].ts one OpenGraph card per page
│ └── robots.txt.ts
├── routeData.ts search titles, OG tags, JSON-LD
└── seo.ts the search-title map
Sidebar order is defined in astro.config.mjs, not inferred from the file tree.
Starlight uses one title for the sidebar label, the <h1> and the <title>.
Sidebar labels want to be short; <title> wants the words people actually type.
src/seo.ts maps route ids to search titles and src/routeData.ts swaps them
in, so the two can differ. A page with no entry there keeps Starlight's default.
src/routeData.ts emits JSON-LD on every page: SoftwareSourceCode and
SoftwareApplication on the home page, TechArticle elsewhere, and
BreadcrumbList throughout. Pages may also declare faq in their frontmatter
to publish FAQPage markup:
faq:
- question: What are the Daraja sandbox test credentials?
answer: >-
The Test Credentials page in the developer portal supplies …Only ever mark up answers that are visible on the page. Invisible FAQ markup is a rich-results violation and the fastest way to lose them.
Validate changes with Google's Rich Results Test or Schema.org's validator.
src/pages/og/[...route].ts renders a 1200×630 card per page from its title and
description, using the fonts in src/fonts/ and src/assets/logo-og.png. They
are cached in node_modules/.astro-og-canvas between local builds. To restyle
them, edit getImageOptions and delete that cache.
Regenerate src/assets/logo-og.png from the SVG with:
node -e "require('sharp')('src/assets/logo.svg',{density:600}).resize(160,160).png().toFile('src/assets/logo-og.png')"npm run social renders social/laravel-daraja.png and
social/daraja-docs.png at 1280×640 — the image GitHub shows when a repo is
shared on Slack, X or WhatsApp. There is no API for setting it, so upload each
one under Settings → Social preview on the matching repository.
starlight-llms-txt publishes /llms.txt, /llms-small.txt and
/llms-full.txt — a clean corpus for AI coding assistants, which is an
increasingly large share of "which M-Pesa package should I use". Configured
under plugins in astro.config.mjs.
src/content/docs/changelog.md is generated from the package's CHANGELOG.md
and committed. Refresh it after each release:
npm run sync:changelog # from the package's default branch
npm run sync:changelog -- ../laravel-daraja/CHANGELOG.md # from a local checkoutNo analytics ship by default. The build emits tags only for the environment variables that are set, passed through by the deploy workflow from repository variables:
| Variable | Effect |
|---|---|
PLAUSIBLE_DOMAIN |
Cookieless analytics. |
GA4_MEASUREMENT_ID |
Google Analytics 4. Sets cookies — read DOMAIN-SWITCH.md first. |
GOOGLE_SITE_VERIFICATION |
google-site-verification meta tag. |
BING_SITE_VERIFICATION |
msvalidate.01 meta tag. |
The privacy policy renders itself from the same variables, so it cannot drift from what the deployed site actually measures.
Pushing to main builds and deploys via .github/workflows/deploy.yml.
GitHub Pages must be set to GitHub Actions as its source under
Settings → Pages.
The tutorials are the top of a funnel that currently has no bottom. Every one
of them ends at a problem the free package leaves you to solve by hand — the
unmatched payments pile in tutorials/c2b-paybill, the failed payouts needing
a human decision in tutorials/b2c-payouts, the sweep for stuck attempts, the
per-tenant reconciliation in tutorials/multi-tenant. Those are the places a
reader is most receptive to being told there is a dashboard for this.
Nothing has been added yet, deliberately: Mizani is not finished, and sending traffic to a product that is not ready spends the goodwill once. When the panel is ready:
- A shared component, in the shape of
src/components/HireMe.astro, so the wording lives in one file and every tutorial picks up an edit. - Placed at the point in each page where the manual work is described, not
bolted to the bottom. The
## Nextsection of each tutorial is the natural home. - Honest about what it is. These pages earn their traffic by being accurate about M-Pesa; an advertisement that oversells undoes that in one visit.
HireMestays where it is. Consulting and the product are different offers to different readers, and a page carrying both asks the reader to choose between them.
Until then the tutorials link only to the free guides, which is the correct behaviour rather than an oversight — do not add a placeholder.
API details come from the Safaricom developer portal, recorded in the package
repository under docs/api-specs/. When Safaricom changes an endpoint, update
the spec there first, then the page here.