OpenReceive 0.4.19 fixes two bugs that broke checkout in 0.4.18: Prisma on PostgreSQL failed every checkout, and Next.js 16 production builds (Turbopack) could not reach the wallet. Upgrade if you use either.
Optional swaps let payers use USDT, USDC, SOL and ETH; a configured swap provider converts them to BTC over Lightning in the merchant's connected wallet. Asset and network availability depends on the provider.
- New:
examples/next-postgres-starter, a one-product Next.js shop on Postgres that uses only the published packages. Its README has a Vercel Deploy button that creates a Neon database and asks forNWC_URI; every build creates the tables. It needs 0.4.19, because of the Turbopack fix below. Checked with a Next 16 production build: through PgBouncer in transaction mode, it minted a real invoice and refused a stranger's browser. - New guide: Bitcoin checkout in v0, covering starting from the starter or adding checkout to an existing v0 app (with a prompt that fetches the Next.js directions), environment variables per Vercel environment, and how settlement runs without a worker.
- Next.js and Express directions: if the user says the two codes are already set as the hosting platform's environment variables or secrets (v0, Vercel, Replit, Lovable), the agent no longer asks for them or writes an env file.
- Node: a Next.js 16 production build (Turbopack, the default) could not
reach the wallet. The NWC client was loaded through
new Function("return import(...)")andrequire.resolve; Turbopack rewritesrequire.resolveto a numeric module id, so preflight failed withThe "path" argument must be of type string. Received type numberand every payment route answered 503. The test runs used the fake wallet, so they never loaded the real client. It is now a plainawait import("@getalby/sdk/nwc"): still lazy, and something any bundler resolves. That also removes thenew Functioncall that Cloudflare Workers forbid. Verified with a Next 16 production build against a real wallet. - Node: Prisma on PostgreSQL failed every checkout. The per-reference lock
selected
pg_advisory_xact_lock(...), whosevoidresult Prisma's raw queries cannot read ("Failed to deserialize column of type 'void'"), so each create threw before an invoice existed. The lock now selects a constant from the function.pg, Knex and TypeORM were not affected, and the Ruby, Python and PHP engines read thevoidcolumn fine. The ORM lanes had covered Prisma only on SQLite. - New CI lane: the payments contract (concurrent retries, rollback,
write-once settlement, the reconcile gate) runs through PgBouncer in
transaction mode with prepared statements off, for
pg, Knex, Prisma (@prisma/adapter-pg) and TypeORM. That is the connection serverless hosts get from Supabase's port 6543 and Neon's pooler. All four pass. Run it locally withtests/orms/pooler/compose.yml. - Fastify: with the documented mount,
register(openReceiveFastify, { prefix: "/openreceive" }), an unknown path under the prefix got Fastify's own 404 instead of OpenReceive's JSON 404.openreceive doctor --urlprobes for that 404, so its routes check failed on a working install, and an eval agent wrote a fake OpenReceive 404 to pass it. The register scope is now the mount, and the router answers every path inside it. - Agent directions for every library stack (Node, Fastify, Next, FastAPI, Django, Rails, PHP, Laravel) end the way WooCommerce Step 3 does: doctor is clean, the user gets the checkout link, the quickstart's browser check is theirs, the agent cannot pay the invoice, and one message says "Setup is finished" with no offer or question. A new non-negotiable keeps the agent in the application: no other project's files, no browser or Playwright. Eval runs on Node and Fastify ended on "checkout is live", took "Yes, go ahead" as a request for the browser check, and loaded Playwright from another checkout. BTCPay's directions end on a clean health check the same way.
- WordPress, ready for WordPress.org review: the plugin zip no longer ships
the engine's PHPStan cache, test suites, examples or tool configs from
bundled dependencies, or a
.DS_Store. The 0.4.18 zip was 28 MB unpacked in 2,742 files; it is now about 10 MB in 1,100. The build fails if a generated autoloader still points at a pruned test file. The zip now carriescomposer.jsonso reviewers can see the dependencies. It also leaves out the fake wallet (DemoWalletand the engine'sTestingclasses): definingOPENRECEIVE_DEMO_WALLETon a store now enables nothing. The Docker example's staged plugin keeps it for its tests.paragonie/sodium_compatis no longer bundled: the plugin requires the sodium extension, and WordPress core already ships that polyfill. - WordPress: the plugin is named "OpenReceive" in its header and readme, so
the WordPress.org slug becomes
openreceive. The directory derives the slug from the header and the name it showed would have producedopenreceive-bitcoin-lightning-payments-for-woocommerce. Every PHP file exits when loaded outside WordPress. Activation also refuses 32-bit PHP, andwp openreceive doctorreports it. - WordPress: readme.txt is rewritten as the directory listing, with a full
external-services section (wallet relay, price feeds, swap provider). The
price mirror's terms and privacy policy live at the new site-owned path
/privacy. - New guide: WordPress hosting requirements, covering GMP and sodium availability on common hosts and how to check a site. WordPress's Site Health screen cannot detect a missing GMP.