openreceive 0.4.25 → 0.4.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92de70ca1044470b160698913fc4bcec615f0529de243fc7df86eddcd6d7cf95
4
- data.tar.gz: e390588c785aa70eb0641f34e31d6953886592db3c2c24ddd67f8e17e797a1ea
3
+ metadata.gz: 66faa619377624dd7e90952d52d7ef0210a0d0ce4726647b34534caef7225e11
4
+ data.tar.gz: 320f45f340b8e2138f7ae6a7ee0fb7c5e9703e3a42bd0c94692622afbd9bee41
5
5
  SHA512:
6
- metadata.gz: 2a14369f2156c50c446260eafe5d4915406d90e3a075a547770f2e0f6fcbd44c9c73c2b89ea3c11266b9afde8df7732a45ae5225cc0cc32f966d27bd74f23283
7
- data.tar.gz: e6aae3ef1fccb7348e8b48a5150cb2e2d1ba437137256e06adde9c4f37c40666be992dae9c4a63de5ef931551f1afca600470b0af18003ff6c52e63608a904ee
6
+ metadata.gz: a048e3a24ef863bfcc34d2277db739631dd529f701d44d7d310b33eec681649ef6942bb8169ff3e6b820591338027ab4b599d04070708249c1567b280b4dca0d
7
+ data.tar.gz: 67476c05c9dff09b48f41fed17e26ce81150e26089a81658b2e03023ab505e53fbf444f5487d2721ab0def24e3c91fbc352c56a4abd69e469cf8b7371694ad5e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.26 - 2026-10-14
4
+
5
+ Release with the complete 0.4.26 package family. The bundled agent skill's
6
+ directions say that a paid order's page shows that it is paid and no
7
+ checkout, and that a Docker Compose app recreates its container after
8
+ writing `.env`. The plain PHP directions describe the engine's new default
9
+ cache. No Ruby runtime changes from 0.4.25.
10
+
3
11
  ## 0.4.25 - 2026-10-13
4
12
 
5
13
  Release with the complete 0.4.25 package family. The bundled agent skill
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenReceive
4
- VERSION = "0.4.25"
4
+ VERSION = "0.4.26"
5
5
  end
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/btcpay/full.md
17
17
  - Never tick the spend-capable override to make a save succeed.
18
18
  - Do not suggest rotating or revoking a code because it was pasted here.
19
19
 
20
- These directions describe OpenReceive 0.4.25.
20
+ These directions describe OpenReceive 0.4.26.
21
21
 
22
22
  Connect a BTCPay Server store to a receive-only NWC wallet with the OpenReceive
23
23
  plugin, and optionally let payers pay BTCPay invoices with USDT, USDC, ETH or
@@ -3,7 +3,7 @@ This is the full file; follow it from Step 0.
3
3
  # OpenReceive agent directions (Django)
4
4
 
5
5
  ```sh
6
- # READ THIS FIRST: this file is 46 KB and a summary drops required steps. Download it whole:
6
+ # READ THIS FIRST: this file is 47 KB and a summary drops required steps. Download it whole:
7
7
  curl -fsSL https://openreceive.org/agent-directions/django/full.md
8
8
  # Skip the download only if you already have all of it: pasted, read from disk or fetched raw.
9
9
  ```
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/django/full.md
17
17
  - Do not suggest rotating or revoking a code because it was pasted here.
18
18
  - Start the quickstart only once the NWC code is saved, and the LSC code is saved or the user said "Bitcoin only".
19
19
 
20
- These directions describe OpenReceive 0.4.25.
20
+ These directions describe OpenReceive 0.4.26.
21
21
 
22
22
  Add OpenReceive to a Django project — the app you are already working in. You
23
23
  do not need a copy of the OpenReceive source: the Python package is on PyPI
@@ -127,6 +127,8 @@ you store it. Ask one question per message.
127
127
  `settings.py` before anything reads the environment. When the app is started
128
128
  with Docker Compose, give the service `env_file: .env`. Restart the server
129
129
  after writing the file.
130
+ Under Compose, recreate the container with `docker compose up -d`:
131
+ `docker compose restart` keeps its old environment.
130
132
 
131
133
  Do not invent placeholder URIs. Start the quickstart only once `NWC_URI` is
132
134
  saved and `LSC_URI_PRIMARY` is saved or explicitly declined. The first boot
@@ -255,7 +257,12 @@ itself, and they hold for every integration.
255
257
  such window. On the drop-ins: `resumePaymentHash`, fed from `onState`, on
256
258
  `<Checkout>`; the `resume-payment-hash` attribute, fed from the
257
259
  `openreceive-state` event (`event.detail.state.payment_hash`), on
258
- `<openreceive-checkout>`. https://openreceive.org/guides/swap-refunds.md
260
+ `<openreceive-checkout>`.
261
+ That visit can come hours later, and `authorize` must still know the payer:
262
+ a session that expired in between answers 403 and strands the deposit. On a
263
+ guest shop, tie the order to a long-lived signed cookie, or put a secret
264
+ per-order token in its URL that your page trades for that cookie.
265
+ https://openreceive.org/guides/swap-refunds.md
259
266
  - Show the payer WHAT THEY ARE BUYING. Return an optional `description` beside
260
267
  the price from `amount_for` and both drop-ins render it above the
261
268
  amount. Without it the checkout is a QR and "$1.00" with no sign of what the
@@ -303,6 +310,12 @@ products, and you do not join them.
303
310
  expired invoice does not cancel the order; a later checkout may mint another
304
311
  attempt. The engine refuses a new checkout under a reference that already
305
312
  settled (409).
313
+ - **A paid order's page says it is paid and shows no checkout.** Nothing is left
314
+ to pay, and a checkout cannot start a new payment for a paid order. Mount the
315
+ checkout only while the order is unpaid. When it settles on the page, update
316
+ the page's status line from the `openreceive-settled` event on
317
+ `<openreceive-checkout>`: `on_paid` has already marked the order paid. Keep
318
+ that checkout mounted, because it is the payer's receipt.
306
319
  - **Do not relate to `OpenReceivePayment`.** No `ForeignKey`, no `OneToOne`, no
307
320
  `ManyToMany` either direction, and no admin `inline` on it. `reference` is not
308
321
  unique (many attempts per order). Fulfillment is a guarded transition on YOUR
@@ -3,7 +3,7 @@ This is the full file; follow it from Step 0.
3
3
  # OpenReceive agent directions (FastAPI)
4
4
 
5
5
  ```sh
6
- # READ THIS FIRST: this file is 41 KB and a summary drops required steps. Download it whole:
6
+ # READ THIS FIRST: this file is 42 KB and a summary drops required steps. Download it whole:
7
7
  curl -fsSL https://openreceive.org/agent-directions/fastapi/full.md
8
8
  # Skip the download only if you already have all of it: pasted, read from disk or fetched raw.
9
9
  ```
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/fastapi/full.md
17
17
  - Do not suggest rotating or revoking a code because it was pasted here.
18
18
  - Start the quickstart only once the NWC code is saved, and the LSC code is saved or the user said "Bitcoin only".
19
19
 
20
- These directions describe OpenReceive 0.4.25.
20
+ These directions describe OpenReceive 0.4.26.
21
21
 
22
22
  Add OpenReceive to a FastAPI application — the app you are already working in.
23
23
  You do not need a copy of the OpenReceive source: the engine is on PyPI
@@ -126,6 +126,8 @@ you store it. Ask one question per message.
126
126
  with `uvicorn --env-file .env` (update the app's run script or Procfile, not
127
127
  just your own command). When it is started with Docker Compose, give the
128
128
  service `env_file: .env`. Restart the server after writing the file.
129
+ Under Compose, recreate the container with `docker compose up -d`:
130
+ `docker compose restart` keeps its old environment.
129
131
  Doctor needs the file too: run it as
130
132
  `dotenv -f .env run -- openreceive doctor …`. The `dotenv` command comes
131
133
  with python-dotenv, which `uvicorn --env-file` already needs; if it is
@@ -248,7 +250,12 @@ itself, and they hold for every integration.
248
250
  such window. On the drop-ins: `resumePaymentHash`, fed from `onState`, on
249
251
  `<Checkout>`; the `resume-payment-hash` attribute, fed from the
250
252
  `openreceive-state` event (`event.detail.state.payment_hash`), on
251
- `<openreceive-checkout>`. https://openreceive.org/guides/swap-refunds.md
253
+ `<openreceive-checkout>`.
254
+ That visit can come hours later, and `authorize` must still know the payer:
255
+ a session that expired in between answers 403 and strands the deposit. On a
256
+ guest shop, tie the order to a long-lived signed cookie, or put a secret
257
+ per-order token in its URL that your page trades for that cookie.
258
+ https://openreceive.org/guides/swap-refunds.md
252
259
  - Show the payer WHAT THEY ARE BUYING. Return an optional `description` beside
253
260
  the price from `amount_for` and both drop-ins render it above the amount.
254
261
  Without it the checkout is a QR and "$1.00" with no sign of what the dollar
@@ -308,6 +315,13 @@ orders, users, or products, and you do not join them.
308
315
  expired invoice does not cancel the order; a later checkout may mint another
309
316
  attempt. The library refuses a new checkout under a reference that already
310
317
  settled (409).
318
+ - **A paid order's page says it is paid and shows no checkout.** Nothing is left
319
+ to pay, and a checkout cannot start a new payment for a paid order. Mount the
320
+ checkout only while the order is unpaid. When it settles on the page, update
321
+ the page's status line from `onSettled` on `<Checkout>`, or the
322
+ `openreceive-settled` event on `<openreceive-checkout>`: `on_paid` has already
323
+ marked the order paid. Keep that checkout mounted, because it is the payer's
324
+ receipt.
311
325
  - **Pass a sync SQLAlchemy `Engine` for this app's database.** Do not add an
312
326
  ORM relationship from Order to `openreceive_payments`, and do not implement
313
327
  `PaymentRepository` unless no SQLAlchemy engine can reach this database.
@@ -3,7 +3,7 @@ This is the full file; follow it from Step 0.
3
3
  # OpenReceive agent directions (Fastify)
4
4
 
5
5
  ```sh
6
- # READ THIS FIRST: this file is 39 KB and a summary drops required steps. Download it whole:
6
+ # READ THIS FIRST: this file is 40 KB and a summary drops required steps. Download it whole:
7
7
  curl -fsSL https://openreceive.org/agent-directions/fastify/full.md
8
8
  # Skip the download only if you already have all of it: pasted, read from disk or fetched raw.
9
9
  ```
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/fastify/full.md
17
17
  - Do not suggest rotating or revoking a code because it was pasted here.
18
18
  - Start the quickstart only once the NWC code is saved, and the LSC code is saved or the user said "Bitcoin only".
19
19
 
20
- These directions describe OpenReceive 0.4.25.
20
+ These directions describe OpenReceive 0.4.26.
21
21
 
22
22
  Add OpenReceive to a Fastify application — the app you are already working in.
23
23
  You do not need a copy of the OpenReceive source: the packages are on npm, and
@@ -123,6 +123,8 @@ you store it. Ask one question per message.
123
123
  `import "dotenv/config";` at the top of the server entry, as the quickstart
124
124
  does. When the app is started with Docker Compose, give the service
125
125
  `env_file: .env`. Restart the server after writing the file.
126
+ Under Compose, recreate the container with `docker compose up -d`:
127
+ `docker compose restart` keeps its old environment.
126
128
 
127
129
  Do not invent placeholder URIs. Start the quickstart only once `NWC_URI` is
128
130
  saved and `LSC_URI_PRIMARY` is saved or explicitly declined. The first boot
@@ -235,7 +237,12 @@ itself, and they hold for every integration.
235
237
  such window. On the drop-ins: `resumePaymentHash`, fed from `onState`, on
236
238
  `<Checkout>`; the `resume-payment-hash` attribute, fed from the
237
239
  `openreceive-state` event (`event.detail.state.payment_hash`), on
238
- `<openreceive-checkout>`. https://openreceive.org/guides/swap-refunds.md
240
+ `<openreceive-checkout>`.
241
+ That visit can come hours later, and `authorize` must still know the payer:
242
+ a session that expired in between answers 403 and strands the deposit. On a
243
+ guest shop, tie the order to a long-lived signed cookie, or put a secret
244
+ per-order token in its URL that your page trades for that cookie.
245
+ https://openreceive.org/guides/swap-refunds.md
239
246
  - Show the payer WHAT THEY ARE BUYING. Return an optional `description` beside
240
247
  the price from `amountFor` and both drop-ins render it above the amount.
241
248
  Without it the checkout is a QR and "$1.00" with no sign of what the dollar
@@ -290,6 +297,13 @@ products, and you do not join them.
290
297
  expired invoice does not cancel the order; a later checkout may mint another
291
298
  attempt. The library refuses a new checkout under a reference that already
292
299
  settled (409).
300
+ - **A paid order's page says it is paid and shows no checkout.** Nothing is left
301
+ to pay, and a checkout cannot start a new payment for a paid order. Mount the
302
+ checkout only while the order is unpaid. When it settles on the page, update
303
+ the page's status line from `onSettled` on `<Checkout>`, or the
304
+ `openreceive-settled` event on `<openreceive-checkout>`: `onPaid` has already
305
+ marked the order paid. Keep that checkout mounted, because it is the payer's
306
+ receipt.
293
307
  - **Pass this app's `db` handle.** Do not add a Prisma/Drizzle relation from
294
308
  Order to `openreceive_payments`, and do not implement `PaymentRepository`
295
309
  unless no supported handle can reach this database. `reference` is not unique
@@ -3,7 +3,7 @@ This is the full file; follow it from Step 0.
3
3
  # OpenReceive agent directions (Flask)
4
4
 
5
5
  ```sh
6
- # READ THIS FIRST: this file is 43 KB and a summary drops required steps. Download it whole:
6
+ # READ THIS FIRST: this file is 44 KB and a summary drops required steps. Download it whole:
7
7
  curl -fsSL https://openreceive.org/agent-directions/flask/full.md
8
8
  # Skip the download only if you already have all of it: pasted, read from disk or fetched raw.
9
9
  ```
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/flask/full.md
17
17
  - Do not suggest rotating or revoking a code because it was pasted here.
18
18
  - Start the quickstart only once the NWC code is saved, and the LSC code is saved or the user said "Bitcoin only".
19
19
 
20
- These directions describe OpenReceive 0.4.25.
20
+ These directions describe OpenReceive 0.4.26.
21
21
 
22
22
  Add OpenReceive to a Flask application — the app you are already working in.
23
23
  You do not need a copy of the OpenReceive source: the engine is on PyPI
@@ -131,6 +131,8 @@ you store it. Ask one question per message.
131
131
  `dotenv -f .env run -- gunicorn …` (python-dotenv's CLI,
132
132
  `pip install "python-dotenv[cli]"`), in the app's run script or Procfile,
133
133
  not just your own command. Restart the server after writing the file.
134
+ Under Compose, recreate the container with `docker compose up -d`:
135
+ `docker compose restart` keeps its old environment.
134
136
  Doctor reads `.env` from its working directory by itself. Never `source`,
135
137
  `export` or `cat` the file: the codes contain `&`, and the shell prints the
136
138
  pieces.
@@ -252,7 +254,12 @@ itself, and they hold for every integration.
252
254
  such window. On the drop-ins: `resumePaymentHash`, fed from `onState`, on
253
255
  `<Checkout>`; the `resume-payment-hash` attribute, fed from the
254
256
  `openreceive-state` event (`event.detail.state.payment_hash`), on
255
- `<openreceive-checkout>`. https://openreceive.org/guides/swap-refunds.md
257
+ `<openreceive-checkout>`.
258
+ That visit can come hours later, and `authorize` must still know the payer:
259
+ a session that expired in between answers 403 and strands the deposit. On a
260
+ guest shop, tie the order to a long-lived signed cookie, or put a secret
261
+ per-order token in its URL that your page trades for that cookie.
262
+ https://openreceive.org/guides/swap-refunds.md
256
263
  - Show the payer WHAT THEY ARE BUYING. Return an optional `description` beside
257
264
  the price from `amount_for` and both drop-ins render it above the amount.
258
265
  Without it the checkout is a QR and "$1.00" with no sign of what the dollar
@@ -315,6 +322,12 @@ orders, users, or products, and you do not join them.
315
322
  expired invoice does not cancel the order; a later checkout may mint another
316
323
  attempt. The library refuses a new checkout under a reference that already
317
324
  settled (409).
325
+ - **A paid order's page says it is paid and shows no checkout.** Nothing is left
326
+ to pay, and a checkout cannot start a new payment for a paid order. Mount the
327
+ checkout only while the order is unpaid. When it settles on the page, update
328
+ the page's status line from the `openreceive-settled` event on
329
+ `<openreceive-checkout>`: `on_paid` has already marked the order paid. Keep
330
+ that checkout mounted, because it is the payer's receipt.
318
331
  - **Pass a sync SQLAlchemy `Engine` for this app's database.** Do not add an
319
332
  ORM relationship from Order to `openreceive_payments`, and do not implement
320
333
  `PaymentRepository` unless no SQLAlchemy engine can reach this database.
@@ -3,7 +3,7 @@ This is the full file; follow it from Step 0.
3
3
  # OpenReceive agent directions (Laravel)
4
4
 
5
5
  ```sh
6
- # READ THIS FIRST: this file is 45 KB and a summary drops required steps. Download it whole:
6
+ # READ THIS FIRST: this file is 46 KB and a summary drops required steps. Download it whole:
7
7
  curl -fsSL https://openreceive.org/agent-directions/laravel/full.md
8
8
  # Skip the download only if you already have all of it: pasted, read from disk or fetched raw.
9
9
  ```
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/laravel/full.md
17
17
  - Do not suggest rotating or revoking a code because it was pasted here.
18
18
  - Start the quickstart only once the NWC code is saved, and the LSC code is saved or the user said "Bitcoin only".
19
19
 
20
- These directions describe OpenReceive 0.4.25.
20
+ These directions describe OpenReceive 0.4.26.
21
21
 
22
22
  Add OpenReceive to a Laravel application — the app you are already working in.
23
23
  You do not need a copy of the OpenReceive source: the package is on Packagist
@@ -130,6 +130,8 @@ you store it. Ask one question per message.
130
130
  `.env` the server reads (an image that copies `.env.example` over it
131
131
  drops them), start `php artisan serve` with `--no-reload`, or set
132
132
  `clear_env = no` for php-fpm. Restart the server after writing the file.
133
+ Under Compose, recreate the container with `docker compose up -d`:
134
+ `docker compose restart` keeps its old environment.
133
135
 
134
136
  Do not invent placeholder URIs. Start the quickstart only once `NWC_URI` is
135
137
  saved and `LSC_URI_PRIMARY` is saved or explicitly declined. The first boot
@@ -248,7 +250,12 @@ itself, and they hold for every integration.
248
250
  such window. On the drop-ins: `resumePaymentHash`, fed from `onState`, on
249
251
  `<Checkout>`; the `resume-payment-hash` attribute, fed from the
250
252
  `openreceive-state` event (`event.detail.state.payment_hash`), on
251
- `<openreceive-checkout>`. https://openreceive.org/guides/swap-refunds.md
253
+ `<openreceive-checkout>`.
254
+ That visit can come hours later, and `authorize` must still know the payer:
255
+ a session that expired in between answers 403 and strands the deposit. On a
256
+ guest shop, tie the order to a long-lived signed cookie, or put a secret
257
+ per-order token in its URL that your page trades for that cookie.
258
+ https://openreceive.org/guides/swap-refunds.md
252
259
  - Show the payer WHAT THEY ARE BUYING. Return an optional `description` beside
253
260
  the price from `amountFor` and both drop-ins render it above the
254
261
  amount. Without it the checkout is a QR and "$1.00" with no sign of what the
@@ -293,6 +300,12 @@ not replace your orders, users, or products, and you do not join them.
293
300
  expired invoice does not cancel the order; a later checkout may mint another
294
301
  attempt. The engine refuses a new checkout under a reference that already
295
302
  settled (409).
303
+ - **A paid order's page says it is paid and shows no checkout.** Nothing is left
304
+ to pay, and a checkout cannot start a new payment for a paid order. Mount the
305
+ checkout only while the order is unpaid. When it settles on the page, update
306
+ the page's status line from the `openreceive-settled` event on
307
+ `<openreceive-checkout>`: `onPaid` has already marked the order paid. Keep
308
+ that checkout mounted, because it is the payer's receipt.
296
309
  - **Do not model `openreceive_payments`.** No Eloquent model, no `hasMany`, no
297
310
  `belongsTo`, no foreign key either direction. `reference` is not unique (many
298
311
  attempts per order). Fulfillment is a guarded transition on YOUR order row
@@ -17,7 +17,7 @@ If your fetch tool gave you a summary, fetch that URL again for the full text.
17
17
  - Do not suggest rotating or revoking a code because it was pasted here.
18
18
  - Start Step 1 only once NWC_URI is saved, and LSC_URI_PRIMARY is saved or the user said "Bitcoin only".
19
19
 
20
- These directions describe OpenReceive 0.4.25.
20
+ These directions describe OpenReceive 0.4.26.
21
21
 
22
22
  Add OpenReceive to this Lovable app: a TanStack Start app on Cloudflare
23
23
  Workers, with Lovable Cloud or a connected Supabase project as its database.
@@ -117,7 +117,7 @@ saved or explicitly declined.
117
117
 
118
118
  ## Step 1 — the packages
119
119
 
120
- Add `@openreceive/http` and `@openreceive/react` at 0.4.25 or newer.
120
+ Add `@openreceive/http` and `@openreceive/react` at 0.4.26 or newer.
121
121
  Nothing else: no `pg`, no Postgres driver, no OpenReceive scaffold. Do not
122
122
  change the Vite or Wrangler configuration.
123
123
 
@@ -157,6 +157,12 @@ every settlement.
157
157
  - **The order is unpaid or paid.** Do not copy attempt statuses (`pending`,
158
158
  `expired`, `failed`, `attention`) onto it, and do not add a relation to
159
159
  `openreceive_payments`.
160
+ - **A paid order's page says it is paid and shows no checkout.** Nothing is left
161
+ to pay, and a checkout cannot start a new payment for a paid order. Mount the
162
+ checkout only while the order is unpaid. When it settles on the page, update
163
+ the page's status line from `onSettled` on `<Checkout>`: `openreceive_on_paid`
164
+ has already marked the order paid. Keep that checkout mounted, because it is
165
+ the payer's receipt.
160
166
 
161
167
  ## Step 4 — `openreceive_on_paid`
162
168
 
@@ -3,7 +3,7 @@ This is the full file; follow it from Step 0.
3
3
  # OpenReceive agent directions (NestJS)
4
4
 
5
5
  ```sh
6
- # READ THIS FIRST: this file is 41 KB and a summary drops required steps. Download it whole:
6
+ # READ THIS FIRST: this file is 42 KB and a summary drops required steps. Download it whole:
7
7
  curl -fsSL https://openreceive.org/agent-directions/nestjs/full.md
8
8
  # Skip the download only if you already have all of it: pasted, read from disk or fetched raw.
9
9
  ```
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/nestjs/full.md
17
17
  - Do not suggest rotating or revoking a code because it was pasted here.
18
18
  - Start the quickstart only once the NWC code is saved, and the LSC code is saved or the user said "Bitcoin only".
19
19
 
20
- These directions describe OpenReceive 0.4.25.
20
+ These directions describe OpenReceive 0.4.26.
21
21
 
22
22
  Add OpenReceive to a NestJS application — the app you are already working in,
23
23
  on Nest's default Express platform. You do not need a copy of the OpenReceive
@@ -129,6 +129,8 @@ you store it. Ask one question per message.
129
129
  it. Otherwise put `import "dotenv/config";` first in `src/main.ts`, as the
130
130
  quickstart does. When the app is started with Docker Compose, give the
131
131
  service `env_file: .env`. Restart the server after writing the file.
132
+ Under Compose, recreate the container with `docker compose up -d`:
133
+ `docker compose restart` keeps its old environment.
132
134
 
133
135
  Do not invent placeholder URIs. Start the quickstart only once `NWC_URI` is
134
136
  saved and `LSC_URI_PRIMARY` is saved or explicitly declined. The first boot
@@ -253,7 +255,12 @@ itself, and they hold for every integration.
253
255
  such window. On the drop-ins: `resumePaymentHash`, fed from `onState`, on
254
256
  `<Checkout>`; the `resume-payment-hash` attribute, fed from the
255
257
  `openreceive-state` event (`event.detail.state.payment_hash`), on
256
- `<openreceive-checkout>`. https://openreceive.org/guides/swap-refunds.md
258
+ `<openreceive-checkout>`.
259
+ That visit can come hours later, and `authorize` must still know the payer:
260
+ a session that expired in between answers 403 and strands the deposit. On a
261
+ guest shop, tie the order to a long-lived signed cookie, or put a secret
262
+ per-order token in its URL that your page trades for that cookie.
263
+ https://openreceive.org/guides/swap-refunds.md
257
264
  - Show the payer WHAT THEY ARE BUYING. Return an optional `description` beside
258
265
  the price from `amountFor` and both drop-ins render it above the amount.
259
266
  Without it the checkout is a QR and "$1.00" with no sign of what the dollar
@@ -305,6 +312,13 @@ products, and you do not join them.
305
312
  expired invoice does not cancel the order; a later checkout may mint another
306
313
  attempt. The library refuses a new checkout under a reference that already
307
314
  settled (409).
315
+ - **A paid order's page says it is paid and shows no checkout.** Nothing is left
316
+ to pay, and a checkout cannot start a new payment for a paid order. Mount the
317
+ checkout only while the order is unpaid. When it settles on the page, update
318
+ the page's status line from `onSettled` on `<Checkout>`, or the
319
+ `openreceive-settled` event on `<openreceive-checkout>`: `onPaid` has already
320
+ marked the order paid. Keep that checkout mounted, because it is the payer's
321
+ receipt.
308
322
  - **Pass this app's `db` handle.** Do not add a Prisma/Drizzle relation from
309
323
  Order to `openreceive_payments`, and do not implement `PaymentRepository`
310
324
  unless no supported handle can reach this database. `reference` is not unique
@@ -3,7 +3,7 @@ This is the full file; follow it from Step 0.
3
3
  # OpenReceive agent directions (Next.js)
4
4
 
5
5
  ```sh
6
- # READ THIS FIRST: this file is 41 KB and a summary drops required steps. Download it whole:
6
+ # READ THIS FIRST: this file is 42 KB and a summary drops required steps. Download it whole:
7
7
  curl -fsSL https://openreceive.org/agent-directions/next/full.md
8
8
  # Skip the download only if you already have all of it: pasted, read from disk or fetched raw.
9
9
  ```
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/next/full.md
17
17
  - Do not suggest rotating or revoking a code because it was pasted here.
18
18
  - Start the quickstart only once the NWC code is saved, and the LSC code is saved or the user said "Bitcoin only".
19
19
 
20
- These directions describe OpenReceive 0.4.25.
20
+ These directions describe OpenReceive 0.4.26.
21
21
 
22
22
  Add OpenReceive to a Next.js App Router application — the app you are already
23
23
  working in. You do not need a copy of the OpenReceive source: the packages are
@@ -128,6 +128,8 @@ you store it. Ask one question per message.
128
128
  give a credential a `NEXT_PUBLIC_` prefix, which inlines it into the browser
129
129
  bundle. When the app is started with Docker Compose, give the service
130
130
  `env_file: .env.local`. Restart the dev server after writing the file.
131
+ Under Compose, recreate the container with `docker compose up -d`:
132
+ `docker compose restart` keeps its old environment.
131
133
 
132
134
  Do not invent placeholder URIs. Start the quickstart only once `NWC_URI` is
133
135
  saved and `LSC_URI_PRIMARY` is saved or explicitly declined. The first boot
@@ -240,7 +242,12 @@ itself, and they hold for every integration.
240
242
  such window. On the drop-ins: `resumePaymentHash`, fed from `onState`, on
241
243
  `<Checkout>`; the `resume-payment-hash` attribute, fed from the
242
244
  `openreceive-state` event (`event.detail.state.payment_hash`), on
243
- `<openreceive-checkout>`. https://openreceive.org/guides/swap-refunds.md
245
+ `<openreceive-checkout>`.
246
+ That visit can come hours later, and `authorize` must still know the payer:
247
+ a session that expired in between answers 403 and strands the deposit. On a
248
+ guest shop, tie the order to a long-lived signed cookie, or put a secret
249
+ per-order token in its URL that your page trades for that cookie.
250
+ https://openreceive.org/guides/swap-refunds.md
244
251
  - Show the payer WHAT THEY ARE BUYING. Return an optional `description` beside
245
252
  the price from `amountFor` and both drop-ins render it above the amount.
246
253
  Without it the checkout is a QR and "$1.00" with no sign of what the dollar
@@ -296,6 +303,12 @@ products, and you do not join them.
296
303
  expired invoice does not cancel the order; a later checkout may mint another
297
304
  attempt. The library refuses a new checkout under a reference that already
298
305
  settled (409).
306
+ - **A paid order's page says it is paid and shows no checkout.** Nothing is left
307
+ to pay, and a checkout cannot start a new payment for a paid order. Mount the
308
+ checkout only while the order is unpaid. When it settles on the page, update
309
+ the page's status line from `onSettled` on `<Checkout>`: `onPaid` has already
310
+ marked the order paid. Keep that checkout mounted, because it is the payer's
311
+ receipt.
299
312
  - **Pass this app's `db` handle.** Do not add a Prisma/Drizzle relation from
300
313
  Order to `openreceive_payments`, and do not implement `PaymentRepository`
301
314
  unless no supported handle can reach this database. `reference` is not unique
@@ -398,6 +411,7 @@ enough; drop the `.md` for the same page a person would read.
398
411
  - https://openreceive.org/guides/custom-checkout-route.md — advanced: replacing the shipped adapter's routes with your own
399
412
  - https://openreceive.org/guides/react-material-ui-recipe.md — a worked custom UI on a component library
400
413
  - https://openreceive.org/guides/tanstack-start-recipe.md — the same handler as a TanStack Start server route, if this app is TanStack Start after all
414
+ - https://openreceive.org/guides/sveltekit-recipe.md, https://openreceive.org/guides/nuxt-recipe.md, https://openreceive.org/guides/astro-recipe.md and https://openreceive.org/guides/react-router-recipe.md — the same handler as a SvelteKit, Nuxt, Astro or React Router route, if this app is one of those
401
415
  - https://openreceive.org/guides.md — the index, if what you need is not above
402
416
 
403
417
  Questions, or a problem with the library itself:
@@ -3,7 +3,7 @@ This is the full file; follow it from Step 0.
3
3
  # OpenReceive agent directions (Node.js)
4
4
 
5
5
  ```sh
6
- # READ THIS FIRST: this file is 38 KB and a summary drops required steps. Download it whole:
6
+ # READ THIS FIRST: this file is 39 KB and a summary drops required steps. Download it whole:
7
7
  curl -fsSL https://openreceive.org/agent-directions/node/full.md
8
8
  # Skip the download only if you already have all of it: pasted, read from disk or fetched raw.
9
9
  ```
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/node/full.md
17
17
  - Do not suggest rotating or revoking a code because it was pasted here.
18
18
  - Start the quickstart only once the NWC code is saved, and the LSC code is saved or the user said "Bitcoin only".
19
19
 
20
- These directions describe OpenReceive 0.4.25.
20
+ These directions describe OpenReceive 0.4.26.
21
21
 
22
22
  Add OpenReceive to a Node application — the app you are already working in. You
23
23
  do not need a copy of the OpenReceive source: the packages are on npm, and the
@@ -125,6 +125,8 @@ you store it. Ask one question per message.
125
125
  `import "dotenv/config";` at the top of the server entry, as the quickstart
126
126
  does. When the app is started with Docker Compose, give the service
127
127
  `env_file: .env`. Restart the server after writing the file.
128
+ Under Compose, recreate the container with `docker compose up -d`:
129
+ `docker compose restart` keeps its old environment.
128
130
 
129
131
  Do not invent placeholder URIs. Start the quickstart only once `NWC_URI` is
130
132
  saved and `LSC_URI_PRIMARY` is saved or explicitly declined. The first boot
@@ -236,7 +238,12 @@ itself, and they hold for every integration.
236
238
  such window. On the drop-ins: `resumePaymentHash`, fed from `onState`, on
237
239
  `<Checkout>`; the `resume-payment-hash` attribute, fed from the
238
240
  `openreceive-state` event (`event.detail.state.payment_hash`), on
239
- `<openreceive-checkout>`. https://openreceive.org/guides/swap-refunds.md
241
+ `<openreceive-checkout>`.
242
+ That visit can come hours later, and `authorize` must still know the payer:
243
+ a session that expired in between answers 403 and strands the deposit. On a
244
+ guest shop, tie the order to a long-lived signed cookie, or put a secret
245
+ per-order token in its URL that your page trades for that cookie.
246
+ https://openreceive.org/guides/swap-refunds.md
240
247
  - Show the payer WHAT THEY ARE BUYING. Return an optional `description` beside
241
248
  the price from `amountFor` and both drop-ins render it above the amount.
242
249
  Without it the checkout is a QR and "$1.00" with no sign of what the dollar
@@ -286,6 +293,13 @@ products, and you do not join them.
286
293
  expired invoice does not cancel the order; a later checkout may mint another
287
294
  attempt. The library refuses a new checkout under a reference that already
288
295
  settled (409).
296
+ - **A paid order's page says it is paid and shows no checkout.** Nothing is left
297
+ to pay, and a checkout cannot start a new payment for a paid order. Mount the
298
+ checkout only while the order is unpaid. When it settles on the page, update
299
+ the page's status line from `onSettled` on `<Checkout>`, or the
300
+ `openreceive-settled` event on `<openreceive-checkout>`: `onPaid` has already
301
+ marked the order paid. Keep that checkout mounted, because it is the payer's
302
+ receipt.
289
303
  - **Pass this app's `db` handle.** Do not add a Prisma/Drizzle relation from
290
304
  Order to `openreceive_payments`, and do not implement `PaymentRepository`
291
305
  unless no supported handle can reach this database. `reference` is not unique
@@ -387,6 +401,7 @@ enough; drop the `.md` for the same page a person would read.
387
401
  - https://openreceive.org/guides/api-reference.md — every route, option and error code
388
402
  - https://openreceive.org/guides/custom-checkout-route.md — advanced: replacing the shipped adapter's routes with your own
389
403
  - https://openreceive.org/guides/react-material-ui-recipe.md — a worked custom UI on a component library
404
+ - https://openreceive.org/guides/sveltekit-recipe.md, https://openreceive.org/guides/nuxt-recipe.md, https://openreceive.org/guides/astro-recipe.md and https://openreceive.org/guides/react-router-recipe.md — the same handler as a SvelteKit, Nuxt, Astro or React Router route, if this app is one of those
390
405
  - https://openreceive.org/guides.md — the index, if what you need is not above
391
406
 
392
407
  Questions, or a problem with the library itself:
@@ -3,7 +3,7 @@ This is the full file; follow it from Step 0.
3
3
  # OpenReceive agent directions (PHP)
4
4
 
5
5
  ```sh
6
- # READ THIS FIRST: this file is 41 KB and a summary drops required steps. Download it whole:
6
+ # READ THIS FIRST: this file is 42 KB and a summary drops required steps. Download it whole:
7
7
  curl -fsSL https://openreceive.org/agent-directions/php/full.md
8
8
  # Skip the download only if you already have all of it: pasted, read from disk or fetched raw.
9
9
  ```
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/php/full.md
17
17
  - Do not suggest rotating or revoking a code because it was pasted here.
18
18
  - Start the quickstart only once the NWC code is saved, and the LSC code is saved or the user said "Bitcoin only".
19
19
 
20
- These directions describe OpenReceive 0.4.25.
20
+ These directions describe OpenReceive 0.4.26.
21
21
 
22
22
  Add OpenReceive to a PHP application — the app you are already working in. You
23
23
  do not need a copy of the OpenReceive source: the engine is on Packagist
@@ -124,6 +124,8 @@ you store it. Ask one question per message.
124
124
  front controller before `Service::fromEnvironment()`. When the app is started
125
125
  with Docker Compose, give the service `env_file: .env`. Restart PHP-FPM or
126
126
  the server after writing the file.
127
+ Under Compose, recreate the container with `docker compose up -d`:
128
+ `docker compose restart` keeps its old environment.
127
129
 
128
130
  Do not invent placeholder URIs. Start the quickstart only once `NWC_URI` is
129
131
  saved and `LSC_URI_PRIMARY` is saved or explicitly declined. The first boot
@@ -246,6 +248,10 @@ itself, and they hold for every integration.
246
248
  `payment_hash` and reopen the attempt with `POST /swaps/status`, which has no
247
249
  such window. On the element: the `resume-payment-hash` attribute, fed from
248
250
  the `openreceive-state` event (`event.detail.state.payment_hash`).
251
+ That visit can come hours later, and `authorize` must still know the payer:
252
+ a session that expired in between answers 403 and strands the deposit. On a
253
+ guest shop, tie the order to a long-lived signed cookie, or put a secret
254
+ per-order token in its URL that your page trades for that cookie.
249
255
  https://openreceive.org/guides/swap-refunds.md
250
256
  - Show the payer WHAT THEY ARE BUYING. Return an optional `description` beside
251
257
  the price from `amountFor` and the drop-in renders it above the amount.
@@ -263,10 +269,11 @@ itself, and they hold for every integration.
263
269
  array keys, and the browser packages' TypeScript APIs are camelCase.
264
270
  - Money is integers or decimal strings — never binary floats. `amountFor`
265
271
  returns `'value' => '12.00'`, a string; never `12.00`.
266
- - PHP starts every request from nothing. The engine is built for that — the
267
- settlement gate is a row in `openreceive_meta`, not process memory — so do
268
- not add a cache, a static, or an APCu entry to "remember" the wallet or a
269
- reconcile timer between requests.
272
+ - PHP starts every request from nothing. The engine is built for that: the
273
+ settlement gate is a row in `openreceive_meta`, and under a web server
274
+ `Service::fromEnvironment()` keeps the wallet's info and the market data in
275
+ a private temp directory. So do not add a cache, a static, or an APCu entry
276
+ to "remember" the wallet or a reconcile timer between requests.
270
277
 
271
278
  ## Your tables, not ours
272
279
 
@@ -298,6 +305,12 @@ not replace your orders, users, or products, and you do not join them.
298
305
  expired invoice does not cancel the order; a later checkout may mint another
299
306
  attempt. The engine refuses a new checkout under a reference that already
300
307
  settled (409).
308
+ - **A paid order's page says it is paid and shows no checkout.** Nothing is left
309
+ to pay, and a checkout cannot start a new payment for a paid order. Mount the
310
+ checkout only while the order is unpaid. When it settles on the page, update
311
+ the page's status line from the `openreceive-settled` event on
312
+ `<openreceive-checkout>`: `onPaid` has already marked the order paid. Keep
313
+ that checkout mounted, because it is the payer's receipt.
301
314
  - **Pass this app's PDO.** `new SqlPaymentRepository(new PdoConnection($pdo))`
302
315
  over the connection the app already opens; do not implement
303
316
  `PaymentRepository` unless no PDO can reach this database. `reference` is not
@@ -587,8 +600,20 @@ if (str_starts_with($path, '/openreceive')) {
587
600
 
588
601
  `Service::fromEnvironment()` builds the wallet client from `NWC_URI` and runs
589
602
  the receive-only preflight. A missing, invalid or spend-capable code throws
590
- before any route is served. PHP starts every request from nothing, so that
591
- check runs on every request that reaches the engine.
603
+ before any route is served.
604
+
605
+ PHP starts every request from nothing. Without a cache, every checkout route
606
+ would ask the wallet for its info event again and fetch the BTC price and the
607
+ swap provider's currencies and rates again, which costs seconds per click.
608
+ Under a web server, `fromEnvironment()` keeps them in a directory under the
609
+ system temp dir that only the PHP user can open
610
+ (`OpenReceive\Support\FileSharedCache`). The wallet's info is kept for 10
611
+ minutes. A new code gets a new directory, so it is always checked live.
612
+ Command-line runs, such as `bin/doctor` and the notifications worker, always
613
+ ask the wallet. No secret goes in the cache: codes, payments and swap data
614
+ stay out of it. If your app already runs a cache, pass it as `sharedCache:`
615
+ ([Service](https://openreceive.org/guides/api-reference.md#openreceiveserverservice)); `sharedCache: false`
616
+ turns caching off.
592
617
 
593
618
  The settlement gate the engine relies on lives in `openreceive_meta`, not in
594
619
  memory. That is why a fleet of PHP-FPM workers shares one wallet-scan budget,
@@ -3,7 +3,7 @@ This is the full file; follow it from Step 0.
3
3
  # OpenReceive agent directions (Rails)
4
4
 
5
5
  ```sh
6
- # READ THIS FIRST: this file is 42 KB and a summary drops required steps. Download it whole:
6
+ # READ THIS FIRST: this file is 43 KB and a summary drops required steps. Download it whole:
7
7
  curl -fsSL https://openreceive.org/agent-directions/rails/full.md
8
8
  # Skip the download only if you already have all of it: pasted, read from disk or fetched raw.
9
9
  ```
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/rails/full.md
17
17
  - Do not suggest rotating or revoking a code because it was pasted here.
18
18
  - Start the quickstart only once the NWC code is saved, and the LSC code is saved or the user said "Bitcoin only".
19
19
 
20
- These directions describe OpenReceive 0.4.25.
20
+ These directions describe OpenReceive 0.4.26.
21
21
 
22
22
  Add OpenReceive to a Rails application — the app you are already working in. You
23
23
  do not need a copy of the OpenReceive source: the gem is on RubyGems, the
@@ -122,6 +122,8 @@ you store it. Ask one question per message.
122
122
  add `dotenv-rails` to the Gemfile. When it is started with Docker Compose,
123
123
  give the service `env_file: .env`. Restart the server after writing the
124
124
  file; the values are read at boot.
125
+ Under Compose, recreate the container with `docker compose up -d`:
126
+ `docker compose restart` keeps its old environment.
125
127
 
126
128
  Do not invent placeholder URIs. Start the quickstart only once `NWC_URI` is
127
129
  saved and `LSC_URI_PRIMARY` is saved or explicitly declined. The first boot
@@ -237,7 +239,12 @@ itself, and they hold for every integration.
237
239
  such window. On the drop-ins: `resumePaymentHash`, fed from `onState`, on
238
240
  `<Checkout>`; the `resume-payment-hash` attribute, fed from the
239
241
  `openreceive-state` event (`event.detail.state.payment_hash`), on
240
- `<openreceive-checkout>`. https://openreceive.org/guides/swap-refunds.md
242
+ `<openreceive-checkout>`.
243
+ That visit can come hours later, and `authorize` must still know the payer:
244
+ a session that expired in between answers 403 and strands the deposit. On a
245
+ guest shop, tie the order to a long-lived signed cookie, or put a secret
246
+ per-order token in its URL that your page trades for that cookie.
247
+ https://openreceive.org/guides/swap-refunds.md
241
248
  - Show the payer WHAT THEY ARE BUYING. Return an optional `description` beside
242
249
  the price from `config.amount_for` and both drop-ins render it above the
243
250
  amount. Without it the checkout is a QR and "$1.00" with no sign of what the
@@ -282,6 +289,12 @@ not replace your orders, users, or products, and you do not join them.
282
289
  expired invoice does not cancel the order; a later checkout may mint another
283
290
  attempt. The engine refuses a new checkout under a reference that already
284
291
  settled (409).
292
+ - **A paid order's page says it is paid and shows no checkout.** Nothing is left
293
+ to pay, and a checkout cannot start a new payment for a paid order. Mount the
294
+ checkout only while the order is unpaid. When it settles on the page, update
295
+ the page's status line from the `openreceive-settled` event on
296
+ `<openreceive-checkout>`: `on_paid` has already marked the order paid. Keep
297
+ that checkout mounted, because it is the payer's receipt.
285
298
  - **Do not associate `OpenReceivePayment`.** No `has_many`, no `belongs_to`, no
286
299
  foreign key either direction. `reference` is not unique (many attempts per
287
300
  order). Fulfillment is a guarded transition on YOUR order row inside
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/woocommerce/full.md
17
17
  - Do not suggest rotating or revoking a code because it was pasted here.
18
18
  - Setup is done only when the NWC code is saved, and the LSC code is saved or the user said "Bitcoin only".
19
19
 
20
- These directions describe OpenReceive 0.4.25.
20
+ These directions describe OpenReceive 0.4.26.
21
21
 
22
22
  Install and configure the OpenReceive payment gateway in the WooCommerce store
23
23
  you are working in. Preserve its theme, checkout, customer accounts, order
@@ -95,7 +95,7 @@ is saved or the user said "Bitcoin only". Never invent a placeholder code.
95
95
  Install this release from the WordPress.org plugin directory:
96
96
 
97
97
  ```sh
98
- wp plugin install openreceive --version=0.4.25 --activate
98
+ wp plugin install openreceive --version=0.4.26 --activate
99
99
  ```
100
100
 
101
101
  If that fails because WordPress.org does not have this version yet, install
@@ -103,7 +103,7 @@ the ZIP attached to the same GitHub release. Never install the GitHub
103
103
  source-code ZIP or a ZIP from an older release:
104
104
 
105
105
  ```sh
106
- wp plugin install https://github.com/OpenReceive/openreceive/releases/download/v0.4.25/openreceive-wordpress-0.4.25.zip --activate
106
+ wp plugin install https://github.com/OpenReceive/openreceive/releases/download/v0.4.26/openreceive-wordpress-0.4.26.zip --activate
107
107
  ```
108
108
 
109
109
  It needs WooCommerce active, and PHP 8.2+ with GMP and sodium in BOTH the web
@@ -252,7 +252,7 @@ database or application.
252
252
 
253
253
  Each GitHub release also attaches the same plugin as a ZIP, for a site that
254
254
  cannot reach WordPress.org or when WordPress.org does not list a release yet.
255
- Download [openreceive-wordpress-0.4.25.zip](https://github.com/OpenReceive/openreceive/releases/download/v0.4.25/openreceive-wordpress-0.4.25.zip)
255
+ Download [openreceive-wordpress-0.4.26.zip](https://github.com/OpenReceive/openreceive/releases/download/v0.4.26/openreceive-wordpress-0.4.26.zip)
256
256
  and install it through **Plugins → Add New → Upload Plugin**. Historical
257
257
  releases may lack this asset. If that exact URL returns 404, build the same tag
258
258
  below; never silently install an older ZIP. The GitHub source-code ZIP is not
@@ -262,7 +262,7 @@ GMP/sodium, Composer and WP-CLI:
262
262
  ```sh
263
263
  git clone https://github.com/OpenReceive/openreceive.git
264
264
  cd openreceive
265
- git checkout v0.4.25
265
+ git checkout v0.4.26
266
266
  npm ci
267
267
  npm run build:packages
268
268
  composer install --working-dir=packages/php/wordpress
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openreceive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.25
4
+ version: 0.4.26
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenReceive