openreceive 0.4.29 → 0.4.31

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.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/lib/openreceive/version.rb +1 -1
  4. data/skills/integrate-openreceive/SKILL.md +10 -1
  5. data/skills/integrate-openreceive/references/astro.md +8 -9
  6. data/skills/integrate-openreceive/references/bolt.md +9 -7
  7. data/skills/integrate-openreceive/references/btcpay.md +3 -4
  8. data/skills/integrate-openreceive/references/django.md +2 -3
  9. data/skills/integrate-openreceive/references/edd.md +4 -5
  10. data/skills/integrate-openreceive/references/fastapi.md +4 -5
  11. data/skills/integrate-openreceive/references/fastify.md +4 -5
  12. data/skills/integrate-openreceive/references/flask.md +2 -3
  13. data/skills/integrate-openreceive/references/fossbilling.md +7 -8
  14. data/skills/integrate-openreceive/references/laravel.md +3 -4
  15. data/skills/integrate-openreceive/references/lovable.md +16 -12
  16. data/skills/integrate-openreceive/references/medusa.md +12 -5
  17. data/skills/integrate-openreceive/references/mobile.md +1 -1
  18. data/skills/integrate-openreceive/references/nestjs.md +2 -3
  19. data/skills/integrate-openreceive/references/next.md +4 -5
  20. data/skills/integrate-openreceive/references/node.md +4 -5
  21. data/skills/integrate-openreceive/references/nuxt.md +9 -10
  22. data/skills/integrate-openreceive/references/odoo.md +446 -0
  23. data/skills/integrate-openreceive/references/paymenter.md +5 -6
  24. data/skills/integrate-openreceive/references/php.md +2 -3
  25. data/skills/integrate-openreceive/references/prestashop.md +476 -0
  26. data/skills/integrate-openreceive/references/rails.md +2 -3
  27. data/skills/integrate-openreceive/references/react-router.md +8 -9
  28. data/skills/integrate-openreceive/references/sveltekit.md +9 -10
  29. data/skills/integrate-openreceive/references/tanstack-start.md +14 -11
  30. data/skills/integrate-openreceive/references/vendure.md +544 -0
  31. data/skills/integrate-openreceive/references/woocommerce.md +5 -6
  32. metadata +6 -2
@@ -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.29.
20
+ These directions describe OpenReceive 0.4.31.
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
@@ -409,13 +409,12 @@ enough; drop the `.md` for the same page a person would read.
409
409
  - https://openreceive.org/guides/api-reference.md — every route, option and error code; the PHP section names every class above
410
410
  - https://openreceive.org/guides/custom-checkout-route.md — advanced: replacing the shipped handler's routes with your own
411
411
  - https://openreceive.org/guides/react-material-ui-recipe.md — a worked custom UI on a component library
412
+ - https://openreceive.org/guides/payment-safety-upgrade.md — coordinated upgrades and reviewed repair of existing attempts
412
413
  - https://openreceive.org/guides.md — the index, if what you need is not above
413
414
 
414
415
  Questions, or a problem with the library itself:
415
416
  https://openreceive.org/contact
416
417
 
417
- - https://openreceive.org/guides/payment-safety-upgrade.md — coordinated upgrades and reviewed repair of existing attempts
418
-
419
418
  ---
420
419
 
421
420
  ## The quickstart, in full
@@ -0,0 +1,476 @@
1
+ This is the full file; follow it from Step 0.
2
+
3
+ # OpenReceive agent directions (PrestaShop)
4
+
5
+ ```sh
6
+ # READ THIS FIRST: this file is 25 KB and a summary drops required steps. Download it whole:
7
+ curl -fsSL https://openreceive.org/agent-directions/prestashop/full.md
8
+ # Skip the download only if you already have all of it: pasted, read from disk or fetched raw.
9
+ ```
10
+
11
+ **Step 0 in brief** (Step 0 below has the details):
12
+
13
+ - Before installing or editing anything, ask the user for a receive-only NWC code. One question per message.
14
+ - Next ask for the LSC code. If the user wants stablecoins, USDT, USDC, ETH, SOL or crypto, do not ask yes/no first.
15
+ - The user only pastes codes into this chat. Never ask them to run a command, edit a file or use an admin page.
16
+ - Store each code yourself as Step 2 says. Never put a code in a shell command.
17
+ - Do not suggest rotating or revoking a code because it was pasted here.
18
+ - Setup is done only when the NWC code is saved, and the LSC code is saved or the user said "Bitcoin only".
19
+
20
+ These directions describe OpenReceive 0.4.31.
21
+
22
+ Install and configure the OpenReceive payment module in the PrestaShop store
23
+ you are working in. Preserve its theme, customers, products, orders and
24
+ prices. The module is a ZIP that bundles the PHP engine and the checkout's
25
+ script: do not install Composer or npm packages into PrestaShop, and do not
26
+ clone the OpenReceive repository.
27
+
28
+ The one required credential is a receive-only NWC code (Nostr Wallet Connect):
29
+ a string from the merchant's wallet that can create invoices and read their
30
+ status, and cannot spend. A swap provider (an "LSC" code) optionally lets
31
+ customers pay with USDT, USDC, ETH or SOL instead; the provider converts the
32
+ payment to BTC over Lightning in the merchant's connected wallet. Available
33
+ assets and networks depend on the provider.
34
+
35
+ Run every `php` command below in PrestaShop's folder (the one that holds
36
+ `bin/console`), as the web server's user, never as root: a root run can leave
37
+ files in PrestaShop's `var/cache` that the web server cannot write. With
38
+ PrestaShop's official Docker image, that is
39
+ `docker compose exec -T -u www-data prestashop php bin/console …` (`-T` passes
40
+ stdin through; use the PrestaShop service's own name; the container starts in
41
+ `/var/www/html`). On a server, it is `sudo -u www-data php bin/console …` with
42
+ the site's own user.
43
+
44
+ ## Step 0 — ask for the two codes, one question at a time
45
+
46
+ Before anything else, check one thing: whether OpenReceive is already
47
+ installed (`php bin/console openreceive:doctor`). If the command exists, it
48
+ prints `NWC_URI: set` or `unset` (likewise `LSC_URI_PRIMARY`), never the
49
+ values. A code that is already set is not asked for again; if both are set,
50
+ skip to Step 3.
51
+
52
+ Otherwise your next action is a question to the user. Do not download the
53
+ module, edit Docker files or search anywhere else before asking it. Do not
54
+ read PrestaShop's `app/config/parameters.php`, deploy config, container
55
+ environments or other projects looking for a code: a new install has neither
56
+ code yet.
57
+
58
+ The user never runs a command and never edits a file. They paste each code
59
+ into this chat; you store it. That is the supported path: do not ask them to
60
+ run the save command themselves, and do not tell them to revoke or replace a
61
+ code because it was pasted here. Ask one question per message.
62
+
63
+ 1. **First message — the NWC code, and nothing else.**
64
+
65
+ > To receive payments I need a receive-only wallet code. In Rizful: open
66
+ > the menu, tap NWC, choose Receive-only NWC code, and tap Copy
67
+ > (https://openreceive.org/get_a_nwc_code_to_receive_payments). If you would
68
+ > rather run your own wallet, Alby Hub works too: Connections → Add
69
+ > Connection → Read Only. Paste the code here and I will store it.
70
+
71
+ 2. **When they paste it.** If it does not start with `nostr+walletconnect://`,
72
+ ask them to copy the receive-only code again. Otherwise do not repeat it:
73
+ reply only that you have it, then ask the next question. You store it in
74
+ Step 2.
75
+ 3. **Second message — swaps.** If the user asked for stablecoins, USDT, USDC,
76
+ ETH, SOL, altcoins or "crypto" (as in "Bitcoin and stablecoin payments"),
77
+ this message IS the walkthrough below: do not skip it, and do not ask yes
78
+ or no first. Otherwise ask whether customers should also be able to pay
79
+ with USDT, USDC, ETH or SOL, then give the walkthrough. The walkthrough:
80
+
81
+ > Go to https://lightning-swap.com, sign in for API keys, create a key, and
82
+ > copy the whole URI (https://openreceive.org/set_up_swap_provider). Paste
83
+ > it here and I will store it — or say "Bitcoin only" and I will continue
84
+ > without it.
85
+
86
+ Mention FixedFloat only if they already use it.
87
+ 4. **When they paste it.** If it does not start with
88
+ `lightning+swapconnect://`, ask them to copy it again. Swaps are now on,
89
+ so keep the route back (the swap non-negotiable below).
90
+
91
+ Do not report setup as complete until the NWC code is saved, and the LSC code
92
+ is saved or the user said "Bitcoin only". Never invent a placeholder code.
93
+
94
+ ## Step 1 — install the module
95
+
96
+ The module needs PrestaShop 9 on 64-bit PHP 8.2+ with GMP and sodium. Check
97
+ first: `php -m` must list both `gmp` and `sodium`. PrestaShop's official
98
+ Docker image has sodium but not GMP, so with it, build an image that adds GMP:
99
+
100
+ 1. Put a `Dockerfile` next to the Compose file, with the same tag as the
101
+ PrestaShop service's `image:` line:
102
+
103
+ ```dockerfile
104
+ FROM prestashop/prestashop:<tag>
105
+ RUN apt-get update && apt-get install -y --no-install-recommends libgmp-dev \
106
+ && docker-php-ext-install gmp && rm -rf /var/lib/apt/lists/*
107
+ ```
108
+
109
+ 2. In the Compose file, replace that service's `image:` line with `build: .`
110
+ (the folder that holds the Dockerfile). Change nothing else in the file.
111
+ 3. Run `docker compose up -d --build`. PrestaShop's files and configuration
112
+ stay in the service's volume; only PHP changes. Check `php -m` again.
113
+
114
+ On a server without GMP, say which PHP extension is missing and stop:
115
+ installing PHP extensions on the user's server is theirs to decide. On
116
+ PrestaShop 8, whose PHP stops at 8.1, say the module needs PrestaShop 9 and
117
+ stop.
118
+
119
+ The module is the ZIP attached to this GitHub release, one `openreceive`
120
+ folder. Unzip it into PrestaShop's `modules` folder; it changes no PrestaShop
121
+ file. Never install the GitHub source-code ZIP or a ZIP from an older release.
122
+ With the Docker image, download and unpack it inside the container, as the
123
+ web user, then install the module with PrestaShop's own console:
124
+
125
+ ```sh
126
+ docker compose exec -T -u www-data prestashop sh -c 'curl -fsSLO https://github.com/OpenReceive/openreceive/releases/download/v0.4.31/openreceive-prestashop-0.4.31.zip && unzip -oq openreceive-prestashop-0.4.31.zip -d modules && rm openreceive-prestashop-0.4.31.zip'
127
+ docker compose exec -T -u www-data prestashop php bin/console prestashop:module install openreceive
128
+ ```
129
+
130
+ On a server, unpack it into `modules` the same way, make `modules/openreceive`
131
+ the web user's, and run the same `prestashop:module install openreceive`.
132
+ Installing creates the module's two tables in PrestaShop's database and its
133
+ order state, "Awaiting Bitcoin payment", adds the payment option to checkout
134
+ and makes the `openreceive:*` console commands appear. The option stays
135
+ hidden until a wallet code is saved.
136
+
137
+ ## Step 2 — store the codes
138
+
139
+ Store each code yourself, one per command, and never as a shell argument:
140
+
141
+ 1. Write the code with your file-editing tool, not a shell command (no
142
+ `echo`, `printf` or heredoc), to a new file outside the PrestaShop
143
+ folder, such as `/tmp/openreceive-code`.
144
+ 2. Run `php bin/console openreceive:configure --nwc-uri=- < /tmp/openreceive-code`.
145
+ In Docker: `docker compose exec -T -u www-data prestashop php bin/console openreceive:configure --nwc-uri=- < /tmp/openreceive-code`.
146
+ For the LSC code, use `--lsc-uri-primary=-`.
147
+ 3. Delete the file (`rm /tmp/openreceive-code`), whether the command passed
148
+ or not.
149
+
150
+ The command asks the wallet first and saves the code, encrypted with the
151
+ shop's own key, only when the wallet answers as receive-only; a failure saves
152
+ nothing. If it reports spend methods such as `pay_invoice`, ask the user for a
153
+ receive-only code again. Saving the wallet code turns the payment option on;
154
+ saving the swap code renames it to "Bitcoin & stablecoins". Never write a code
155
+ into PrestaShop's database, `app/config/parameters.php` or any file in the
156
+ PrestaShop folder yourself.
157
+
158
+ Then run `php bin/console openreceive:doctor`. It names any failed check and
159
+ exits nonzero; fix it before going on.
160
+
161
+ ## Step 3 — mint a test invoice, then stop
162
+
163
+ Place a small test order for a hidden test product, bought by a test
164
+ customer the command creates once (`openreceive-test@example.invalid`, so no
165
+ real customer sees it and no email reaches anyone), and mint its Lightning
166
+ invoice:
167
+
168
+ ```sh
169
+ php bin/console openreceive:test-invoice --new
170
+ ```
171
+
172
+ To use an order that already awaits its OpenReceive payment, pass its id
173
+ instead of `--new`. `test-invoice` goes through the same route as the order's
174
+ confirmation page. It prints the amount in sats, the BOLT11 invoice, the
175
+ order's confirmation page and the methods the checkout offers, each swap asset
176
+ marked available or followed by the reason it is not. That reason is the
177
+ answer; report it. "Below the provider minimum" or "above the provider
178
+ maximum" is about this order's amount, not a fault. Only when the reason says
179
+ the provider is unreachable does doctor's "Swap provider" line have more
180
+ detail. `test-invoice` and `doctor` are the whole check.
181
+
182
+ Give the user the order's confirmation page, which opens the checkout on this
183
+ same invoice in any browser. Tell them to cancel the test order under
184
+ **Orders** when they are done: PrestaShop keeps every order.
185
+
186
+ You cannot pay the invoice: the code is receive-only. Do not pay, settle or
187
+ mark the order paid, and do not look for a way to (a wallet control port, a
188
+ test endpoint, another wallet). If the user wants a real settlement test, they
189
+ pay from the order's page with their own wallet; afterwards the order reads
190
+ "Payment accepted".
191
+
192
+ Setup ends here. Once doctor is clean and the user has the link, your last
193
+ message starts "Setup is finished" and has at most six short lines: the
194
+ order's page, the methods the checkout offers (Bitcoin, plus USDT, USDC, ETH
195
+ and SOL when the swap code is saved), the cron line below, and one line of
196
+ what to look at. Do not list each coin's availability, mention a minimum, or
197
+ say a coin will not work: a provider minimum depends on the order total, and
198
+ real orders will differ. Do not list what you changed or what doctor checked.
199
+ Send nothing after it.
200
+
201
+ PrestaShop has no scheduler, so the module's pass for customers who leave the
202
+ page before their payment settles needs one cron line, every five minutes:
203
+ `php bin/console openreceive:reconcile` as the web user. Give the user that
204
+ line in your last message; do not add it yourself, and do not add containers,
205
+ services or workers.
206
+
207
+ ## Non-negotiables
208
+
209
+ - Never print, log or commit a code, never put one in a shell argument, and
210
+ never write one into source files, `app/config/parameters.php`, the
211
+ database or browser code. Doctor's set/unset is all you report.
212
+ - Do not suggest rotating, revoking or replacing a code because it was pasted
213
+ into this chat; that is the supported path.
214
+ - Work only in this PrestaShop. Never read or run anything from another
215
+ project or directory on this machine (its `node_modules`, tools or source),
216
+ for any reason. A browser, Playwright, hand-made calls to the checkout's
217
+ routes, database queries and reading the module's source are not part of
218
+ setup: when doctor or `test-invoice` fails, report its output.
219
+ - Run `php` as the web server's user, never as root.
220
+ - Receive-only NWC is required. Never get past the preflight with a code that
221
+ can spend.
222
+ - The module owns only its two payment tables in PrestaShop's database.
223
+ PrestaShop owns customers, orders, prices, carriers and email. Do not add an
224
+ external payment database or custom fulfillment code, and do not edit
225
+ PrestaShop's own files or theme. The Dockerfile that adds GMP and the one
226
+ Compose line that builds it are the only deployment change.
227
+ - IF SWAPS ARE ON, KEEP THE ROUTE BACK. A deposit that arrives short or late
228
+ becomes refundable, and the customer claims it later from the same order's
229
+ page. Keep the module installed while swap payments may still need a
230
+ refund. https://openreceive.org/guides/swap-refunds.md
231
+ - A receive-only wallet cannot send refunds. Refund a settled payment manually
232
+ from the wallet.
233
+
234
+ ## Further reading
235
+
236
+ - [PrestaShop Quickstart](https://openreceive.org/guides/quickstart-prestashop.md)
237
+ - [Automated Swaps](https://openreceive.org/guides/automated-swaps.md)
238
+ - [Swap Refunds](https://openreceive.org/guides/swap-refunds.md)
239
+ - [Lightning Swap Connect URI](https://openreceive.org/guides/lightning-swap-connect.md)
240
+ - [Security](https://openreceive.org/guides/security.md)
241
+ - [Price Feeds](https://openreceive.org/guides/price-feeds.md)
242
+
243
+ ---
244
+
245
+ ## The quickstart, in full
246
+
247
+ Inlined verbatim so this file needs no network access. Steps 0–3 above are the setup and this is their reference: where the two differ, the steps win, and its back-office screens are only for a PrestaShop with no shell.
248
+ The page it comes from is https://openreceive.org/guides/quickstart-prestashop.
249
+
250
+ ## PrestaShop quickstart
251
+
252
+ [PrestaShop](https://prestashop-project.org) is an open-source e-commerce
253
+ platform. The OpenReceive module adds a payment option to it: the customer
254
+ pays with Bitcoin over Lightning, straight into your own wallet, on
255
+ PrestaShop's own order confirmation page. With a swap provider, the same page
256
+ also takes USDT, USDC, SOL and ETH, which the provider converts to BTC over
257
+ Lightning into the same wallet.
258
+
259
+ PrestaShop keeps owning customers, orders, prices and carriers. The module
260
+ keeps its payment attempts in two tables of PrestaShop's own database. When a
261
+ payment settles, it records it the way PrestaShop's payment modules do: an
262
+ order payment with the payment hash as its transaction id, in the same
263
+ database transaction that settles the payment. The order then moves to
264
+ PrestaShop's "Payment accepted", so PrestaShop makes the invoice, emails the
265
+ customer and runs its other modules as it does for any other payment.
266
+
267
+ Requirements: PrestaShop 9, on 64-bit PHP 8.2 or later with GMP and sodium,
268
+ and PrestaShop's MySQL or MariaDB database. PrestaShop 8 runs on PHP 8.1 at
269
+ most, below what the module needs. A cron job runs the module's reconcile
270
+ pass, as [below](#the-cron-job).
271
+
272
+ Already run BTCPay Server? [PrestaShop via BTCPay Server](https://openreceive.org/guides/prestashop.md) is
273
+ the other way in: BTCPay's own PrestaShop module, with OpenReceive inside
274
+ BTCPay.
275
+
276
+ ### Install the module
277
+
278
+ Each GitHub release attaches the module as a ZIP with one folder,
279
+ `openreceive`. In the back office, open **Modules → Module Manager**, click
280
+ **Upload a module** and drop the ZIP in: PrestaShop unpacks it into
281
+ `modules/openreceive` and installs it.
282
+
283
+ From a shell, unzip it into PrestaShop's `modules` folder instead, and
284
+ install it with PrestaShop's own console, in the folder that holds `bin/console`:
285
+
286
+ ```sh
287
+ cd /var/www/html
288
+ curl -fsSLO https://github.com/OpenReceive/openreceive/releases/download/v0.4.31/openreceive-prestashop-0.4.31.zip
289
+ unzip -oq openreceive-prestashop-0.4.31.zip -d modules
290
+ rm openreceive-prestashop-0.4.31.zip
291
+ chown -R www-data:www-data modules/openreceive
292
+ sudo -u www-data php bin/console prestashop:module install openreceive
293
+ ```
294
+
295
+ Use your own PrestaShop folder and web server user. Installing creates the
296
+ module's two tables and its order state, "Awaiting Bitcoin payment", and adds
297
+ the payment option to checkout. The option stays hidden until a wallet code is
298
+ saved.
299
+
300
+ The ZIP already bundles the module's dependencies and the checkout's script,
301
+ under their own prefixed names, so Composer never runs and nothing in
302
+ PrestaShop's own `vendor/` changes. The GitHub source-code ZIP is not an
303
+ installable module.
304
+
305
+ #### PrestaShop in Docker
306
+
307
+ PrestaShop's official image has sodium but not GMP. Build your own image on
308
+ top of it: put this `Dockerfile` next to your `compose.yml`, use the same tag
309
+ as your image,
310
+
311
+ ```dockerfile
312
+ FROM prestashop/prestashop:9.2.0-apache
313
+ RUN apt-get update && apt-get install -y --no-install-recommends libgmp-dev \
314
+ && docker-php-ext-install gmp && rm -rf /var/lib/apt/lists/*
315
+ ```
316
+
317
+ and in `compose.yml` replace the PrestaShop service's `image:` line with
318
+ `build: .`, then run `docker compose up -d --build`. PrestaShop's files, its
319
+ configuration and the module stay in the named volume at `/var/www/html`; only
320
+ PHP changes.
321
+
322
+ Run every command inside the container, in `/var/www/html`, as its web user
323
+ `www-data`. Unpack the release there too:
324
+
325
+ ```sh
326
+ docker compose exec -T -u www-data prestashop sh -c 'curl -fsSLO https://github.com/OpenReceive/openreceive/releases/download/v0.4.31/openreceive-prestashop-0.4.31.zip && unzip -oq openreceive-prestashop-0.4.31.zip -d modules && rm openreceive-prestashop-0.4.31.zip'
327
+ docker compose exec -T -u www-data prestashop php bin/console prestashop:module install openreceive
328
+ ```
329
+
330
+ Always pass `-u www-data`. A command that runs as root can leave files in
331
+ PrestaShop's `var/cache` that the web server cannot write.
332
+
333
+ ### Configure the wallet
334
+
335
+ You need a receive-only NWC code: a Nostr Wallet Connect code that can create
336
+ invoices and read payments but cannot spend. The module refuses a code that
337
+ can spend.
338
+
339
+ In the back office, open **Modules → Module Manager** and click **Configure**
340
+ on **OpenReceive**. Paste the code into **Receive-only NWC code** and save. To
341
+ accept stablecoins too, paste a swap provider code into **Swap provider
342
+ code**. PrestaShop stores both encrypted with the shop's own key, and the page
343
+ never shows them again; it says only whether each is set.
344
+
345
+ From a terminal, pipe each code into `openreceive:configure` from your secret
346
+ manager or a protected file. Never type a code as a command argument:
347
+
348
+ ```sh
349
+ sudo -u www-data php bin/console openreceive:configure --nwc-uri=- < /secure/path/wallet-code
350
+ sudo -u www-data php bin/console openreceive:configure --lsc-uri-primary=- < /secure/path/swap-code
351
+ sudo -u www-data php bin/console openreceive:doctor
352
+ ```
353
+
354
+ The settings page and `configure` both ask the wallet first and save the code
355
+ only when it answers as a receive-only wallet. Saving the wallet code turns
356
+ the payment option on. Saving a swap code renames the default "Bitcoin
357
+ Lightning" to "Bitcoin & stablecoins"; the settings page's **Payment option
358
+ name**, or `--name="…"`, sets your own. Skip the swap code for Bitcoin-only
359
+ checkout. Checkout offers the option in the currencies ticked for OpenReceive
360
+ under **Payment → Preferences**; installing ticks them all.
361
+
362
+ `doctor` checks the module, PHP and its GMP and sodium, each code as set or
363
+ unset (never its value), the order state, the payment option and its
364
+ currencies, the tables, the checkout's files, the wallet, the price feed for
365
+ every currency the shop sells in, each swap provider, and when the wallet was
366
+ last scanned. It exits nonzero when a check fails.
367
+
368
+ ### The cron job
369
+
370
+ PrestaShop has no scheduler of its own. While a customer has an order's page
371
+ open, its checkout records the payment the moment it settles. For a customer
372
+ who closes the page first, run the module's reconcile pass every five minutes
373
+ from cron, as the web server's user:
374
+
375
+ ```cron
376
+ */5 * * * * www-data php /var/www/html/bin/console openreceive:reconcile
377
+ ```
378
+
379
+ That line goes in `/etc/cron.d/`; in the web user's own crontab, leave out
380
+ `www-data`. On hosting with a control panel, add a cron job with the same
381
+ `php …/bin/console openreceive:reconcile` command. With Docker, the host's cron
382
+ runs `docker compose exec -T -u www-data prestashop php bin/console openreceive:reconcile`
383
+ from the Compose project's folder.
384
+
385
+ Each pass also finishes any order whose payment settled but which did not
386
+ move to "Payment accepted", and every checkout request runs one pass too.
387
+
388
+ ### Check it
389
+
390
+ Make a Lightning invoice through the same route the order page uses, for a
391
+ new $5 test order, or for any order awaiting its OpenReceive payment by its id:
392
+
393
+ ```sh
394
+ sudo -u www-data php bin/console openreceive:test-invoice --new
395
+ sudo -u www-data php bin/console openreceive:test-invoice <order id>
396
+ ```
397
+
398
+ `--new` places an order for a hidden, downloadable test product, bought by a
399
+ test customer it creates once, `openreceive-test@example.invalid`, so no real
400
+ customer sees the order and its email reaches no one. `--amount=` changes
401
+ what it costs. PrestaShop keeps every order: cancel the test order under
402
+ **Orders** when you are done. Like any new order, it may reach the back
403
+ office's notifications.
404
+
405
+ It prints the amount in sats, the Lightning invoice and the order's
406
+ confirmation page, then each method the checkout offers: Bitcoin Lightning,
407
+ and each swap asset with its network and whether it is available for this
408
+ amount. A small order is often below a swap provider's minimum; that is the
409
+ amount, not a fault. The order's confirmation page carries the order's secret
410
+ key, so it opens the checkout in any browser.
411
+
412
+ ### How a payment works
413
+
414
+ 1. The customer picks the OpenReceive option at checkout and places the
415
+ order. PrestaShop creates the order in "Awaiting Bitcoin payment" and opens
416
+ its order confirmation page with the checkout on it.
417
+ 2. The module charges the order's total with tax and shipping, in the order's
418
+ currency, converted to sats at the current BTC price. Only the customer the
419
+ order belongs to, signed in, or a browser PrestaShop already showed the
420
+ order to (its confirmation page, which needs the order's secret key, or
421
+ guest order tracking) may make or follow its payment, and only from a page
422
+ with the order's checkout, whose token comes back with each request.
423
+ 3. Once the wallet reports the payment, the module records an order payment
424
+ for it, with the payment hash as its transaction id, in the same database
425
+ transaction that settles it. Right after, the order moves to "Payment
426
+ accepted": PrestaShop makes the invoice, emails the customer and runs its
427
+ other modules' hooks. Should that step fail, the next pass finishes it.
428
+ 4. The page loads again and says the payment was received.
429
+
430
+ A customer who leaves can come back from **Order history** in their account,
431
+ or a guest from **Guest order tracking**: the order's page shows the
432
+ checkout again while the order awaits its payment, with the same Lightning
433
+ invoice while it is still valid.
434
+
435
+ An unpaid order stays in "Awaiting Bitcoin payment" until you cancel it, as
436
+ with any other payment that never came. If you cancel an order and its
437
+ payment arrives afterwards, the module records the payment on the order,
438
+ leaves the order cancelled, and logs a warning.
439
+
440
+ Every line the module logs goes to PrestaShop's `var/logs/openreceive.log`.
441
+ Warnings and errors also appear under **Advanced Parameters → Logs** in the
442
+ back office.
443
+
444
+ ### Refunds and removal
445
+
446
+ The receive-only wallet cannot send refunds. Send a refund from your own
447
+ wallet, then record it in PrestaShop. A customer whose swap deposit never
448
+ converted reclaims it from the same order's page, while the order still
449
+ awaits its payment. If you turn on swaps, you commit to keeping that path
450
+ available. See [swap refunds](https://openreceive.org/guides/swap-refunds.md).
451
+
452
+ Disabling the module hides the payment option and its checkout. Uninstalling
453
+ it also forgets both codes. It keeps the two tables, which are a record of
454
+ payments received, and the "Awaiting Bitcoin payment" order state, which
455
+ orders refer to.
456
+
457
+ ### Tested, and not tested
458
+
459
+ Tested on 2026-10-19 with PrestaShop 9.2.0's official Docker image with GMP
460
+ added (PHP 8.5), its Hummingbird theme, MariaDB 11.8, a test wallet and a
461
+ test swap provider: the module uploaded through **Upload a module** in the
462
+ back office, and installed from the unzipped ZIP with `bin/console
463
+ prestashop:module install`; the swap code saved on the Configure page and
464
+ both codes from stdin; the doctor; `test-invoice --new`; and in Chromium, a
465
+ signed-in customer checking out with OpenReceive and paying on the order
466
+ confirmation page by Lightning and by USDT on Solana, after which each order
467
+ reads "Payment accepted" with its invoice. Coming back to the order through
468
+ **Order history** resumed the same Lightning invoice. Another customer, with
469
+ an order of their own, and a visitor were refused. A payment that settled
470
+ with no page open was recorded by `openreceive:reconcile`. Uninstalling kept
471
+ the payment records and the order state and forgot the codes.
472
+
473
+ Not tested: PrestaShop 9.0 and 9.1, the Classic theme, nginx with PHP-FPM,
474
+ shared hosting, multistore, friendly URLs turned off, guest checkout and guest
475
+ order tracking, carts PrestaShop splits into several orders, and updating
476
+ from an older release of the module.
@@ -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.29.
20
+ These directions describe OpenReceive 0.4.31.
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
@@ -393,13 +393,12 @@ enough; drop the `.md` for the same page a person would read.
393
393
  - https://openreceive.org/guides/api-reference.md — every route, option and error code
394
394
  - https://openreceive.org/guides/custom-checkout-route.md — advanced: replacing the mounted engine's routes with your own
395
395
  - https://openreceive.org/guides/react-material-ui-recipe.md — a worked custom UI on a component library
396
+ - https://openreceive.org/guides/payment-safety-upgrade.md — coordinated upgrades and reviewed repair of existing attempts
396
397
  - https://openreceive.org/guides.md — the index, if what you need is not above
397
398
 
398
399
  Questions, or a problem with the library itself:
399
400
  https://openreceive.org/contact
400
401
 
401
- - https://openreceive.org/guides/payment-safety-upgrade.md — coordinated upgrades and reviewed repair of existing attempts
402
-
403
402
  ---
404
403
 
405
404
  ## The quickstart, in full
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/react-router/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.29.
20
+ These directions describe OpenReceive 0.4.31.
21
21
 
22
22
  Add OpenReceive to a React Router application in framework mode — the app
23
23
  you are already working in, on Node. OpenReceive ships no React Router
@@ -421,13 +421,12 @@ enough; drop the `.md` for the same page a person would read.
421
421
  - https://openreceive.org/guides/custom-checkout-route.md — advanced: replacing the shipped adapter's routes with your own
422
422
  - https://openreceive.org/guides/react-material-ui-recipe.md — a worked custom UI on a component library
423
423
  - https://openreceive.org/guides/quickstart-next.md — each hook explained step by step, on Next.js; they are the same here
424
+ - https://openreceive.org/guides/payment-safety-upgrade.md — coordinated upgrades and reviewed repair of existing attempts
424
425
  - https://openreceive.org/guides.md — the index, if what you need is not above
425
426
 
426
427
  Questions, or a problem with the library itself:
427
428
  https://openreceive.org/contact
428
429
 
429
- - https://openreceive.org/guides/payment-safety-upgrade.md — coordinated upgrades and reviewed repair of existing attempts
430
-
431
430
  ---
432
431
 
433
432
  ## The quickstart, in full
@@ -467,7 +466,7 @@ npm install @openreceive/http @openreceive/react pg
467
466
  On Node, with `react-router-serve` or your own Express server. The wallet
468
467
  connection and your database driver need Node, so the route cannot run on an
469
468
  edge runtime. On Vercel or Netlify, read
470
- Bitcoin checkout on serverless hosts first. For
469
+ [Bitcoin checkout on serverless hosts](https://openreceive.org/guides/serverless.md) first. For
471
470
  Cloudflare Workers, the [TanStack Start recipe](https://openreceive.org/guides/tanstack-start-recipe.md#where-it-runs)
472
471
  explains what a Worker needs. This recipe was not run on those hosts.
473
472
 
@@ -550,23 +549,23 @@ export default [
550
549
  `authorize` sees the incoming request with its cookies, so check it with the
551
550
  session your app already has. With `createCookieSessionStorage`,
552
551
  `currentVisitor` is `(await getSession(request.headers.get("cookie"))).get("visitor")`.
553
- The Next.js quickstart explains each hook.
552
+ The [Next.js quickstart](https://openreceive.org/guides/quickstart-next.md) explains each hook.
554
553
  They are the same here.
555
554
 
556
555
  One stack serves the whole server process. A loader cannot see the
557
556
  connection, so the client address comes from a header. Without a proxy that
558
- sets it, the limit does not apply (Rate limiting).
557
+ sets it, the limit does not apply ([Rate limiting](https://openreceive.org/guides/rate-limiting.md)).
559
558
 
560
559
  ### Your database
561
560
 
562
561
  `db` is a `pg` Pool, `node:sqlite` or `better-sqlite3`, or one of the
563
- adapters in Node ORM recipes. With Drizzle, pass
562
+ adapters in [Node ORM recipes](https://openreceive.org/guides/node-orms.md). With Drizzle, pass
564
563
  the `pg` Pool underneath it.
565
564
 
566
565
  Create OpenReceive's two tables with your migrations
567
566
  (`npx openreceive scaffold payments --orm <your orm>`), or run
568
567
  `paymentsSchemaSql("postgres")` from `@openreceive/http` once. It is
569
- idempotent. See Payment storage.
568
+ idempotent. See [Payment storage](https://openreceive.org/guides/storage.md).
570
569
 
571
570
  ### The checkout page
572
571
 
@@ -596,7 +595,7 @@ into your Tailwind entry (`app/app.css`); the checkout styles are compiled
596
595
  already. The page renders on the server and starts the checkout in the
597
596
  browser. The payer picks Bitcoin and gets the invoice. Keep it at the order's
598
597
  own URL: a payer with a swap deposit in flight comes back to it
599
- (Swap refunds).
598
+ ([Swap refunds](https://openreceive.org/guides/swap-refunds.md)).
600
599
 
601
600
  ### Settings
602
601