npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jungherz-de/stripe-jack

v1.1.2

Published

Export Stripe transactions to DATEV (EXTF Buchungsstapel, BEDI documents, PRAP) — German accounting, cron-ready.

Readme


German bookkeeping expects a very specific package: an EXTF booking batch, the matching invoice PDFs in a BEDI archive, and a deferred-revenue schedule for subscriptions. StripeJack produces exactly that from a Stripe account, in one command, ready to upload to DATEV Unternehmen online.

It is verified against a real DATEV export produced by other software for the same month: in compatibility mode the output matches field for field, header timestamp aside.

Installation

npm install -g @jungherz-de/stripe-jack

Or without installing:

npx @jungherz-de/stripe-jack export --month 2026-07

Requires Node.js 20 or newer.

Quick Start

stripe-jack init         # asks for your Stripe key and account numbers, writes .env
stripe-jack accounts     # check the configuration, no API call
stripe-jack export       # export the last completed month

init defaults every account number from the chart of accounts you pick (SKR 03 or 04) and validates the result before writing, so a typo surfaces immediately rather than on the first export. Prefer to fill the file in yourself? Copy .env.example.

The archive lands in ./out, next to a manifest with counts, totals and checksums.

Configuration

stripe-jack init writes the file for you. It ends up looking like this — the full reference is in docs/configuration.md (German):

STRIPE_API_SEC_KEY=sk_live_…

# From the letter of your tax firm
DATEV_BERATER=1234567
DATEV_MANDANT=12345
DATEV_SACHKONTENLAENGE=4
EXTF_SKR=04

# Core accounts (SKR 04 shown; SKR 03 equivalents in the reference)
KONTO_DEBITOR=10004        # receivables
KONTO_GEBUEHREN=6855       # Stripe and PSP fees
KONTO_GELDTRANSIT=1461     # money in transit to the bank account
KONTO_GUTHABEN=1810        # the Stripe balance itself
KONTO_KLAERUNG=1370        # suspense account
ERLOES_REGEL=4400          # standard-rate revenue

StripeJack only ever reads, so a restricted key (rk_live_…) belongs here rather than a full secret key. The quickest route is Stripe’s permission template for read-only accounting access; only Basic Business Contact Information has to be added as Read on top — that is how the merchant’s country is read, and the country decides every revenue account. No write access is needed at all. Full list: docs/configuration.md.

CLI

stripe-jack init                                     # interactive setup, writes .env
stripe-jack export                                   # last completed month, all accounts
stripe-jack export --month 2026-07
stripe-jack export --from 2026-07-01 --to 2026-07-31
stripe-jack export --account shop --out ./exports --no-mail
stripe-jack export --month 2026-07 --dry-run         # report only, write nothing
stripe-jack export --month 2026-07 --force           # replace an existing export

stripe-jack accounts                                 # show the resolved configuration
stripe-jack verify --month 2026-07 --against old-export.zip

Exit codes: 0 success · 1 configuration · 2 Stripe/network · 3 data · 4 mail · 5 lock held. A failed mail never costs you the archive — it is on disk before the first byte goes out.

Running on a schedule

15 4 3 * * cd /srv/stripe-jack && /usr/bin/npx stripe-jack export >> /var/log/stripe-jack.log 2>&1

With no arguments StripeJack exports the last completed month. Runs are locked per account, already-exported periods are not silently overwritten, and logs are JSON lines when stdout is not a terminal. systemd and launchd units are in docs/cron.md (German).

Multiple accounts

STRIPE_ACCOUNTS=main,shop
MAIN_STRIPE_API_SEC_KEY=sk_live_…
MAIN_DATEV_MANDANT=54321
SHOP_STRIPE_API_SEC_KEY=sk_live_…
SHOP_DATEV_MANDANT=40921

Each account is exported into its own subdirectory with its own chart of accounts, lock and recipient. See docs/multi-account.md (German).

Sending the export

MAIL_ENABLED=true
MAIL_SMTP_HOST=smtp.example.com
[email protected]
[email protected]

The mail carries the archive plus a summary of counts, totals and any warnings. --dry-run reports what would be sent without sending it.

What gets exported

DATEV_Stripe_<client>_<uuid>_2026-07.zip
├── Stripe_PRAP_…xlsx              deferred revenue per subscription invoice
├── Income_By_Product_…xlsx        net revenue per product, weekly/monthly/yearly
├── EXTF_Stripe_Zahlungen_…csv     one batch of payment bookings
├── EXTF_Stripe_Rechnungen_…csv    one batch of invoice bookings
└── documents.zip                  invoice PDFs + BEDI document.xml index

Field-by-field description of the format: docs/datev-format.md (German).

Booking rules

The Stripe balance is modelled as a bank-like account. Payments clear receivables, fees become an expense, payouts move through a money-in-transit account, and refunds reverse the same account pair rather than swapping accounts — so tax automation on the revenue accounts keeps working.

The revenue account is derived, not configured per customer: domestic standard and reduced rate, intra-community reverse charge, One-Stop-Shop, third country. Anything StripeJack cannot classify with confidence goes to the suspense account with a warning, never to a plausible guess.

Full decision tree, the deferral maths and the foreign-currency handling: docs/booking-rules.md (German).

Replacing an existing tool

StripeJack ships two profiles:

| Profile | Behaviour | |---|---| | strict (default) | correct German bookkeeping | | compat | follows the conventions of older export tools |

# Compare against an export produced by your current tool
stripe-jack verify --month 2026-07 --profile compat --against old-export.zip
# → No differences.

Use compat for the switch-over month so nothing changes for your tax advisor, then move to strict. The five differences are documented in docs/compatibility.md (German).

Privacy and self-hosting

StripeJack runs on your machine. There is no service behind it, no account, no sign-up, and no server of ours that ever sees anything.

That matters for GDPR. An export carries personal data — customer names, addresses, invoice amounts and the invoice PDFs. With StripeJack the parties to that data are your company, Stripe (which already holds it) and your tax firm. No additional provider is introduced, so there is no processor to contract under Art. 28 GDPR, no third-party server location to assess, and no extra entry in your record of processing activities.

The tool opens exactly two kinds of outbound connection, both from your own machine: to api.stripe.com to read, and to your own SMTP server if — and only if — you switch mailing on. There is no telemetry, no usage reporting and no update check. The source is open, and every outbound call lives in src/stripe/ and src/output/mailer.ts.

Nothing is stored beyond the archive and its manifest in your output directory: no database, no cache, no temporary spool.

Details, including operating it under its own system user and what to do about access and erasure requests: docs/datenschutz.md (German).

Using it with Claude Code

The package ships a SKILL.md. Point Claude Code (or any agent that reads skill files) at this repository and it knows how to run the tool, what the exit codes mean, and how to walk you through setup by asking for the values it cannot guess.

"Set up StripeJack for my Stripe account and export last month."

Nothing about the tool requires an agent — stripe-jack init does the same guided setup on its own.

Development

npm install
npm run typecheck
npm run lint
npm test          # unit tests + an offline golden-master test
npm run build

The golden-master test replays a recorded Stripe response and compares the result with a reference export for the same month. Both sides are anonymised by scripts/anonymize-fixture.ts, which applies one replacement table to the Stripe data and to the reference CSVs — pseudonyms keep the original string length, so the 60-character truncation the format relies on is still exercised.

No customer data and no live keys are in this repository.

License

MIT © Jungherz GmbH

StripeJack is not affiliated with Stripe, Inc. or DATEV eG. It produces import files according to publicly documented formats; verifying the resulting bookings remains your and your tax advisor's responsibility.