openreceive 0.4.29 → 0.4.30

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 +6 -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 +4 -1
@@ -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.29.
20
+ These directions describe OpenReceive 0.4.30.
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
@@ -447,13 +447,12 @@ enough; drop the `.md` for the same page a person would read.
447
447
  - https://openreceive.org/guides/api-reference.md — every route, option and error code
448
448
  - https://openreceive.org/guides/custom-checkout-route.md — advanced: replacing the shipped adapter's routes with your own
449
449
  - https://openreceive.org/guides/react-material-ui-recipe.md — a worked custom UI on a component library
450
+ - https://openreceive.org/guides/payment-safety-upgrade.md — coordinated upgrades and reviewed repair of existing attempts
450
451
  - https://openreceive.org/guides.md — the index, if what you need is not above
451
452
 
452
453
  Questions, or a problem with the library itself:
453
454
  https://openreceive.org/contact
454
455
 
455
- - https://openreceive.org/guides/payment-safety-upgrade.md — coordinated upgrades and reviewed repair of existing attempts
456
-
457
456
  ---
458
457
 
459
458
  ## The quickstart, in full
@@ -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.29.
20
+ These directions describe OpenReceive 0.4.30.
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
@@ -438,13 +438,12 @@ enough; drop the `.md` for the same page a person would read.
438
438
  - https://openreceive.org/guides/react-material-ui-recipe.md — a worked custom UI on a component library
439
439
  - 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
440
440
  - 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
441
+ - https://openreceive.org/guides/payment-safety-upgrade.md — coordinated upgrades and reviewed repair of existing attempts
441
442
  - https://openreceive.org/guides.md — the index, if what you need is not above
442
443
 
443
444
  Questions, or a problem with the library itself:
444
445
  https://openreceive.org/contact
445
446
 
446
- - https://openreceive.org/guides/payment-safety-upgrade.md — coordinated upgrades and reviewed repair of existing attempts
447
-
448
447
  ---
449
448
 
450
449
  ## The quickstart, in full
@@ -473,8 +472,8 @@ stays the same.
473
472
  | Server | `@openreceive/next`, `@openreceive/express`, `@openreceive/fastify` |
474
473
  | Frontend | `@openreceive/react`, `@openreceive/vue`, `@openreceive/svelte`, `@openreceive/angular`, `@openreceive/elements` (plain HTML) |
475
474
 
476
- Express: [quickstart-node.md](https://openreceive.org/guides/quickstart-node.md) · Fastify:
477
- [quickstart-fastify.md](https://openreceive.org/guides/quickstart-fastify.md). This page is the Next.js one.
475
+ Express: [Express quickstart](https://openreceive.org/guides/quickstart-node.md) · Fastify:
476
+ [Fastify quickstart](https://openreceive.org/guides/quickstart-fastify.md). This page is the Next.js one.
478
477
  An agent given the Express guide goes wrong on Next.js in three places: Next
479
478
  needs no `dotenv`, no `app.use`, and it needs a client component for the
480
479
  checkout.
@@ -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.29.
20
+ These directions describe OpenReceive 0.4.30.
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
@@ -428,13 +428,12 @@ enough; drop the `.md` for the same page a person would read.
428
428
  - https://openreceive.org/guides/custom-checkout-route.md — advanced: replacing the shipped adapter's routes with your own
429
429
  - https://openreceive.org/guides/react-material-ui-recipe.md — a worked custom UI on a component library
430
430
  - 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
431
+ - https://openreceive.org/guides/payment-safety-upgrade.md — coordinated upgrades and reviewed repair of existing attempts
431
432
  - https://openreceive.org/guides.md — the index, if what you need is not above
432
433
 
433
434
  Questions, or a problem with the library itself:
434
435
  https://openreceive.org/contact
435
436
 
436
- - https://openreceive.org/guides/payment-safety-upgrade.md — coordinated upgrades and reviewed repair of existing attempts
437
-
438
437
  ---
439
438
 
440
439
  ## The quickstart, in full
@@ -463,8 +462,8 @@ stays the same.
463
462
  | Server | `@openreceive/express`, `@openreceive/fastify`, `@openreceive/next` |
464
463
  | Frontend | `@openreceive/react`, `@openreceive/vue`, `@openreceive/svelte`, `@openreceive/angular`, `@openreceive/elements` (plain HTML) |
465
464
 
466
- Fastify: [quickstart-fastify.md](https://openreceive.org/guides/quickstart-fastify.md) · Next.js:
467
- [quickstart-next.md](https://openreceive.org/guides/quickstart-next.md). This page is the Express one.
465
+ Fastify: [Fastify quickstart](https://openreceive.org/guides/quickstart-fastify.md) · Next.js:
466
+ [Next.js quickstart](https://openreceive.org/guides/quickstart-next.md). This page is the Express one.
468
467
 
469
468
  On a fresh project, also install what this guide assumes you already have: the
470
469
  framework and an env loader (`npm install express dotenv`). Install your ORM
@@ -3,7 +3,7 @@ This is the full file; follow it from Step 0.
3
3
  # OpenReceive agent directions (Nuxt)
4
4
 
5
5
  ```sh
6
- # READ THIS FIRST: this file is 33 KB and a summary drops required steps. Download it whole:
6
+ # READ THIS FIRST: this file is 34 KB and a summary drops required steps. Download it whole:
7
7
  curl -fsSL https://openreceive.org/agent-directions/nuxt/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/nuxt/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.30.
21
21
 
22
22
  Add OpenReceive to a Nuxt application — the app you are already working in,
23
23
  on Nitro's `node-server` preset. OpenReceive ships no Nuxt package: the
@@ -419,13 +419,12 @@ enough; drop the `.md` for the same page a person would read.
419
419
  - https://openreceive.org/guides/custom-checkout-route.md — advanced: replacing the shipped adapter's routes with your own
420
420
  - https://openreceive.org/guides/react-material-ui-recipe.md — a worked custom UI on a component library
421
421
  - https://openreceive.org/guides/quickstart-next.md — each hook explained step by step, on Next.js; they are the same here
422
+ - https://openreceive.org/guides/payment-safety-upgrade.md — coordinated upgrades and reviewed repair of existing attempts
422
423
  - https://openreceive.org/guides.md — the index, if what you need is not above
423
424
 
424
425
  Questions, or a problem with the library itself:
425
426
  https://openreceive.org/contact
426
427
 
427
- - https://openreceive.org/guides/payment-safety-upgrade.md — coordinated upgrades and reviewed repair of existing attempts
428
-
429
428
  ---
430
429
 
431
430
  ## The quickstart, in full
@@ -464,7 +463,7 @@ npm install @openreceive/http @openreceive/vue pg
464
463
  On Node, with Nitro's default `node-server` preset. The wallet connection and
465
464
  your database driver need Node, so the route cannot run on an edge runtime.
466
465
  The Vercel, Netlify and AWS Lambda presets deploy Node functions: read
467
- Bitcoin checkout on serverless hosts first. For
466
+ [Bitcoin checkout on serverless hosts](https://openreceive.org/guides/serverless.md) first. For
468
467
  Cloudflare Workers, the [TanStack Start recipe](https://openreceive.org/guides/tanstack-start-recipe.md#where-it-runs)
469
468
  explains what a Worker needs. This recipe was not run on those hosts.
470
469
 
@@ -529,24 +528,24 @@ export default defineEventHandler((event) => handleOpenReceive(event));
529
528
  Put it in `server/routes/`, not `server/api/`, which would add `/api` to
530
529
  the path. `native` is the request's `H3Event`, so `authorize` can check the
531
530
  session your app already has: its cookies, or the user your session module
532
- reads from the event. The Next.js quickstart
531
+ reads from the event. The [Next.js quickstart](https://openreceive.org/guides/quickstart-next.md)
533
532
  explains each hook. They are the same here.
534
533
 
535
534
  One stack serves the whole server process. `getRequestIP` returns the socket
536
535
  address. Behind your own reverse proxy, `{ xForwardedFor: true }` reads the
537
536
  first address in `x-forwarded-for`, which is safe only when that proxy sets
538
- the header (Rate limiting).
537
+ the header ([Rate limiting](https://openreceive.org/guides/rate-limiting.md)).
539
538
 
540
539
  ### Your database
541
540
 
542
541
  `db` is a `pg` Pool, `node:sqlite` or `better-sqlite3`, or one of the
543
- adapters in Node ORM recipes. With Drizzle, pass
542
+ adapters in [Node ORM recipes](https://openreceive.org/guides/node-orms.md). With Drizzle, pass
544
543
  the `pg` Pool underneath it.
545
544
 
546
545
  Create OpenReceive's two tables with your migrations
547
546
  (`npx openreceive scaffold payments --orm <your orm>`), or run
548
547
  `paymentsSchemaSql("postgres")` from `@openreceive/http` once. It is
549
- idempotent. See Payment storage.
548
+ idempotent. See [Payment storage](https://openreceive.org/guides/storage.md).
550
549
 
551
550
  ### The checkout page
552
551
 
@@ -585,7 +584,7 @@ if (error.value) {
585
584
  The page renders on the server and starts the checkout in the browser. The
586
585
  payer picks Bitcoin and gets the invoice. Keep it at the order's own URL: a
587
586
  payer with a swap deposit in flight comes back to it
588
- (Swap refunds).
587
+ ([Swap refunds](https://openreceive.org/guides/swap-refunds.md)).
589
588
 
590
589
  ### Settings
591
590
 
@@ -0,0 +1,446 @@
1
+ This is the full file; follow it from Step 0.
2
+
3
+ # OpenReceive agent directions (Odoo)
4
+
5
+ ```sh
6
+ # READ THIS FIRST: this file is 23 KB and a summary drops required steps. Download it whole:
7
+ curl -fsSL https://openreceive.org/agent-directions/odoo/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.30.
21
+
22
+ Install and configure the OpenReceive payment provider in the Odoo you are
23
+ working in. Preserve its website, customers, products, orders, invoices and
24
+ prices. The module is a ZIP; its Python side is the `openreceive` package from
25
+ PyPI at the same version. Do not install anything else into Odoo, do not
26
+ change Odoo's own files, and do not 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
+ The module needs Odoo 19 or 20. With Odoo's official Docker image, run Odoo's
36
+ commands through the image's entrypoint, which adds the database connection:
37
+ `docker compose exec -T odoo /entrypoint.sh odoo …` (`-T` passes stdin
38
+ through; use the Odoo service's own name). `-d <database>` names the
39
+ database; `docker compose exec -T db psql -U <user> -l` lists them when you
40
+ do not know it. On a server, run `odoo …` (or `odoo-bin …`) as Odoo's own
41
+ user with its config file (`-c`).
42
+
43
+ ## Step 0 — ask for the two codes, one question at a time
44
+
45
+ Before anything else, check one thing: whether OpenReceive is already
46
+ installed (`odoo openreceive doctor -d <database>`). If the command exists, it
47
+ prints `NWC_URI: present-redacted` or `missing` (likewise the LSC
48
+ connections), never the values. A code that is already saved is not asked for
49
+ again; if both are saved, skip to Step 3.
50
+
51
+ Otherwise your next action is a question to the user. Do not download the
52
+ module, edit Docker files or search anywhere else before asking it. Do not
53
+ read Odoo's config file, its database, container environments or other
54
+ projects looking for a code: a new install has neither code yet.
55
+
56
+ The user never runs a command and never edits a file. They paste each code
57
+ into this chat; you store it. That is the supported path: do not ask them to
58
+ run the save command themselves, and do not tell them to revoke or replace a
59
+ code because it was pasted here. Ask one question per message.
60
+
61
+ 1. **First message — the NWC code, and nothing else.**
62
+
63
+ > To receive payments I need a receive-only wallet code. In Rizful: open
64
+ > the menu, tap NWC, choose Receive-only NWC code, and tap Copy
65
+ > (https://openreceive.org/get_a_nwc_code_to_receive_payments). If you would
66
+ > rather run your own wallet, Alby Hub works too: Connections → Add
67
+ > Connection → Read Only. Paste the code here and I will store it.
68
+
69
+ 2. **When they paste it.** If it does not start with `nostr+walletconnect://`,
70
+ ask them to copy the receive-only code again. Otherwise do not repeat it:
71
+ reply only that you have it, then ask the next question. You store it in
72
+ Step 2.
73
+ 3. **Second message — swaps.** If the user asked for stablecoins, USDT, USDC,
74
+ ETH, SOL, altcoins or "crypto" (as in "Bitcoin and stablecoin payments"),
75
+ this message IS the walkthrough below: do not skip it, and do not ask yes
76
+ or no first. Otherwise ask whether customers should also be able to pay
77
+ with USDT, USDC, ETH or SOL, then give the walkthrough. The walkthrough:
78
+
79
+ > Go to https://lightning-swap.com, sign in for API keys, create a key, and
80
+ > copy the whole URI (https://openreceive.org/set_up_swap_provider). Paste
81
+ > it here and I will store it — or say "Bitcoin only" and I will continue
82
+ > without it.
83
+
84
+ Mention FixedFloat only if they already use it.
85
+ 4. **When they paste it.** If it does not start with
86
+ `lightning+swapconnect://`, ask them to copy it again. Swaps are now on,
87
+ so keep the route back (the swap non-negotiable below).
88
+
89
+ Do not report setup as complete until the NWC code is saved, and the LSC code
90
+ is saved or the user said "Bitcoin only". Never invent a placeholder code.
91
+
92
+ ## Step 1 — install the module
93
+
94
+ The `openreceive` Python package must be importable by Odoo's own Python.
95
+ Odoo's official Docker image keeps its packages under the system's package
96
+ manager, so build an image that adds it:
97
+
98
+ 1. Put a `Dockerfile` next to the Compose file, with the same tag as the Odoo
99
+ service's `image:` line:
100
+
101
+ ```dockerfile
102
+ FROM odoo:<tag>
103
+ USER root
104
+ RUN pip3 install --no-cache-dir --break-system-packages --ignore-installed typing_extensions h11 \
105
+ && pip3 install --no-cache-dir --break-system-packages openreceive==0.4.30
106
+ USER odoo
107
+ ```
108
+
109
+ The first line installs two packages beside the system's copies, which pip
110
+ cannot replace; do not add other packages, and do not install
111
+ `cryptography`: Odoo keeps using the system's.
112
+ 2. In the Compose file, replace that service's `image:` line with `build: .`
113
+ (the folder that holds the Dockerfile). Change nothing else in the file.
114
+ 3. Run `docker compose up -d --build`.
115
+
116
+ On a server, install `openreceive==0.4.30` with the pip of the Python
117
+ that runs Odoo (its virtualenv when it has one). On Odoo.sh, add
118
+ `openreceive==0.4.30` to the repository's `requirements.txt`. If you
119
+ cannot tell which Python runs Odoo, say so and stop.
120
+
121
+ The module is the ZIP attached to this GitHub release, with its folder,
122
+ `payment_openreceive`, at the top. Unzip it into the folder Odoo reads extra
123
+ modules from: with the official image, the host folder mounted at
124
+ `/mnt/extra-addons` (the Compose file's `volumes:` says which); on a server, a
125
+ folder on the config file's `addons_path`. Never install the GitHub
126
+ source-code ZIP or a ZIP from an older release.
127
+
128
+ ```sh
129
+ curl -fsSLO https://github.com/OpenReceive/openreceive/releases/download/v0.4.30/openreceive-odoo-0.4.30.zip
130
+ unzip -oq openreceive-odoo-0.4.30.zip -d <that folder> && rm openreceive-odoo-0.4.30.zip
131
+ ```
132
+
133
+ Then install it into the database and restart Odoo:
134
+
135
+ ```sh
136
+ docker compose exec -T odoo /entrypoint.sh odoo -d <database> -i payment_openreceive --stop-after-init --no-http
137
+ docker compose restart odoo
138
+ ```
139
+
140
+ Installing creates the module's two tables in Odoo's database, its payment
141
+ provider "OpenReceive" with the payment method "Bitcoin Lightning", a
142
+ scheduled action that records payments made after the customer left, and the
143
+ `odoo openreceive` command. The provider stays hidden from customers until a
144
+ wallet code is saved and Step 2 publishes it. If the install says the
145
+ `openreceive` package is missing, the image or virtualenv from the step above
146
+ is not the one Odoo runs: fix that, do not work around it.
147
+
148
+ ## Step 2 — store the codes
149
+
150
+ Store each code yourself, one per command, and never as a shell argument:
151
+
152
+ 1. Write the code with your file-editing tool, not a shell command (no
153
+ `echo`, `printf` or heredoc), to a new file outside the Odoo folders, such
154
+ as `/tmp/openreceive-code`.
155
+ 2. Run `odoo openreceive configure --nwc-uri=- -d <database> < /tmp/openreceive-code`.
156
+ In Docker: `docker compose exec -T odoo /entrypoint.sh odoo openreceive configure --nwc-uri=- -d <database> < /tmp/openreceive-code`.
157
+ For the LSC code, use `--lsc-uri-primary=-`.
158
+ 3. Delete the file (`rm /tmp/openreceive-code`), whether the command passed
159
+ or not.
160
+
161
+ The command asks the wallet first and saves the code, in the module's own
162
+ table, only when the wallet answers as receive-only; a failure saves nothing.
163
+ If it reports spend methods such as `pay_invoice`, ask the user for a
164
+ receive-only code again. Saving the swap code renames the payment method to
165
+ "Bitcoin & stablecoins". Never write a code into Odoo's database, its config
166
+ file or any file in its folders yourself.
167
+
168
+ Then publish the provider, in every company:
169
+ `odoo openreceive configure --enable -d <database>`, and run
170
+ `odoo openreceive doctor -d <database>`. Doctor names any failed check and
171
+ exits nonzero; fix it before going on.
172
+
173
+ ## Step 3 — mint a test invoice, then stop
174
+
175
+ Create a small draft payment transaction for a test contact the command
176
+ creates once (`openreceive-test@example.invalid`, with no order, so no
177
+ customer sees it), and mint its Lightning invoice:
178
+
179
+ ```sh
180
+ odoo openreceive test-invoice --new -d <database>
181
+ ```
182
+
183
+ To use a transaction that already exists, pass `--reference <its reference>`
184
+ instead of `--new`. `test-invoice` goes through the same route as the
185
+ checkout page. It prints the amount in sats, the BOLT11 invoice and the
186
+ methods the checkout offers, each swap asset marked available or followed by
187
+ the reason it is not. That reason is the answer; report it. A reason about the
188
+ provider's minimum or maximum is about this amount, not a fault. `test-invoice`
189
+ and `doctor` are the whole check.
190
+
191
+ The checkout page itself belongs to the customer who starts a payment: tell
192
+ the user to try it from the shop, by putting a product in the cart and paying
193
+ with "Bitcoin Lightning" (or "Bitcoin & stablecoins").
194
+
195
+ You cannot pay the invoice: the code is receive-only. Do not pay, settle or
196
+ mark the transaction paid, and do not look for a way to (a wallet control
197
+ port, a test endpoint, another wallet). If the user wants a real settlement
198
+ test, they pay a shop order with their own wallet; afterwards the order is
199
+ confirmed.
200
+
201
+ Setup ends here. Once doctor is clean, your last message starts "Setup is
202
+ finished" and has at most six short lines: the methods the checkout offers
203
+ (Bitcoin, plus USDT, USDC, ETH and SOL when the swap code is saved), and one
204
+ line of what to try in the shop. Do not list each coin's availability, mention
205
+ a minimum, or say a coin will not work: a provider minimum depends on the
206
+ order total, and real orders will differ. Do not list what you changed or
207
+ what doctor checked. Send nothing after it. Do not add containers, services,
208
+ workers or cron jobs: the module's scheduled action runs inside Odoo.
209
+
210
+ ## Non-negotiables
211
+
212
+ - Never print, log or commit a code, never put one in a shell argument, and
213
+ never write one into source files, Odoo's config file, the database or
214
+ browser code. Doctor's present/missing is all you report.
215
+ - Do not suggest rotating, revoking or replacing a code because it was pasted
216
+ into this chat; that is the supported path.
217
+ - Work only in this Odoo. Never read or run anything from another project or
218
+ directory on this machine (its `node_modules`, tools or source), for any
219
+ reason. A browser, Playwright, hand-made calls to the checkout's routes,
220
+ database queries and reading the module's source are not part of setup:
221
+ when doctor or `test-invoice` fails, report its output.
222
+ - Receive-only NWC is required. Never get past the preflight with a code that
223
+ can spend.
224
+ - The module owns only its two payment tables and its settings table in
225
+ Odoo's database. Odoo owns customers, orders, invoices, prices and email.
226
+ Do not add an external payment database or custom fulfillment code, and do
227
+ not edit Odoo's own files or modules. The Dockerfile that adds the Python
228
+ package and the one Compose line that builds it are the only deployment
229
+ change.
230
+ - IF SWAPS ARE ON, KEEP THE ROUTE BACK. A deposit that arrives short or late
231
+ becomes refundable, and the customer claims it later from the same
232
+ transaction's checkout page. Keep the module installed while swap payments
233
+ may still need a refund. https://openreceive.org/guides/swap-refunds.md
234
+ - A receive-only wallet cannot send refunds. Refund a settled payment manually
235
+ from the wallet.
236
+
237
+ ## Further reading
238
+
239
+ - [Odoo Quickstart](https://openreceive.org/guides/quickstart-odoo.md)
240
+ - [Automated Swaps](https://openreceive.org/guides/automated-swaps.md)
241
+ - [Swap Refunds](https://openreceive.org/guides/swap-refunds.md)
242
+ - [Lightning Swap Connect URI](https://openreceive.org/guides/lightning-swap-connect.md)
243
+ - [Security](https://openreceive.org/guides/security.md)
244
+ - [Price Feeds](https://openreceive.org/guides/price-feeds.md)
245
+
246
+ ---
247
+
248
+ ## The quickstart, in full
249
+
250
+ 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 provider-form screens are only for an Odoo with no shell.
251
+ The page it comes from is https://openreceive.org/guides/quickstart-odoo.
252
+
253
+ ## Odoo quickstart
254
+
255
+ [Odoo](https://www.odoo.com) runs shops, sales and invoicing. The OpenReceive
256
+ module adds a payment provider to it: the customer pays an online order, or an
257
+ invoice's payment link, with Bitcoin over Lightning, straight into your own
258
+ wallet, on a checkout page of your own site. With a swap provider, the same
259
+ page also takes USDT, USDC, SOL and ETH, which the provider converts to BTC
260
+ over Lightning into the same wallet.
261
+
262
+ Odoo keeps owning customers, orders, invoices and prices. The module keeps its
263
+ payment attempts in two tables of Odoo's own PostgreSQL database. When a
264
+ payment settles, it marks Odoo's payment transaction done in the same database
265
+ transaction that settles the payment, then runs Odoo's own post-processing:
266
+ the order is confirmed, or the invoice paid, and Odoo sends its emails as it
267
+ does for any other provider.
268
+
269
+ Requirements: Odoo 19 or 20, self-hosted or on Odoo.sh, and the `openreceive`
270
+ Python package at the module's version. Odoo Online cannot install modules, so
271
+ it cannot run this one. A shop that already runs BTCPay Server can use
272
+ [Odoo via BTCPay Server](https://openreceive.org/guides/odoo.md) instead.
273
+
274
+ ### Install the module
275
+
276
+ Each GitHub release attaches the module as `openreceive-odoo-<version>.zip`,
277
+ with its folder, `payment_openreceive`, at the top. Unzip it into a folder on
278
+ Odoo's addons path, install the Python package where Odoo's Python finds it,
279
+ restart Odoo, and install **Payment Provider: OpenReceive** under **Apps**, or
280
+ from a terminal:
281
+
282
+ ```sh
283
+ cd /path/to/your/addons
284
+ curl -fsSLO https://github.com/OpenReceive/openreceive/releases/download/v0.4.30/openreceive-odoo-0.4.30.zip
285
+ unzip -oq openreceive-odoo-0.4.30.zip && rm openreceive-odoo-0.4.30.zip
286
+ odoo -d <database> -i payment_openreceive --stop-after-init
287
+ ```
288
+
289
+ How the Python package gets in depends on how Odoo runs:
290
+
291
+ - **Odoo.sh**: commit the `payment_openreceive` folder to your repository and
292
+ add `openreceive==0.4.30` to the repository's `requirements.txt`.
293
+ - **A source install with a virtualenv**: `pip install openreceive==0.4.30`
294
+ in Odoo's virtualenv.
295
+ - **Odoo's Docker image** or **its Debian package**: see below.
296
+
297
+ Installing the module creates its two tables, its payment provider,
298
+ "OpenReceive", with the payment method buyers pick, "Bitcoin Lightning", and a
299
+ scheduled action that records payments made after the customer left. The
300
+ provider stays hidden from customers until a wallet code is saved and you
301
+ publish it.
302
+
303
+ #### Odoo in Docker
304
+
305
+ Odoo's official image keeps its Python packages under the system's package
306
+ manager. Build your own image on top of it: put this `Dockerfile` next to your
307
+ `compose.yml`, with the same tag as your image,
308
+
309
+ ```dockerfile
310
+ FROM odoo:19.0
311
+ USER root
312
+ RUN pip3 install --no-cache-dir --break-system-packages --ignore-installed typing_extensions h11 \
313
+ && pip3 install --no-cache-dir --break-system-packages openreceive==0.4.30
314
+ USER odoo
315
+ ```
316
+
317
+ and in `compose.yml` replace the Odoo service's `image:` line with
318
+ `build: .`, then run `docker compose up -d --build`. The first `pip3` line
319
+ installs two packages beside the system's own copies, which pip cannot
320
+ replace; Odoo keeps using the system's other packages, its `cryptography`
321
+ included. Your database and the module folder you mount at
322
+ `/mnt/extra-addons` stay as they are.
323
+
324
+ Run Odoo's commands through the image's entrypoint, which adds the database
325
+ connection: `docker compose exec odoo /entrypoint.sh odoo <arguments>`. To
326
+ install the module from a terminal:
327
+
328
+ ```sh
329
+ docker compose exec odoo /entrypoint.sh odoo -d <database> -i payment_openreceive --stop-after-init --no-http
330
+ docker compose restart odoo
331
+ ```
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 **Invoicing** (or **Website**) → **Configuration** → **Payment Providers**,
340
+ open **OpenReceive**. Paste the code into **Receive-only NWC code** and save.
341
+ To accept stablecoins too, paste a swap provider code into **Swap provider
342
+ code**. Saving asks the wallet first and keeps the code only when the wallet
343
+ answers as receive-only. The codes go to the module's own table, which no Odoo
344
+ screen lists, and the form never shows them again; it says only whether each
345
+ is saved. Then publish the provider (Odoo 19: State **Enabled**; Odoo 20:
346
+ **Live** and **Published**).
347
+
348
+ From a terminal, pipe each code into `odoo openreceive configure` from your
349
+ secret manager or a protected file. Never type a code as a command argument:
350
+
351
+ ```sh
352
+ odoo openreceive configure --nwc-uri=- -d <database> < /secure/path/wallet-code
353
+ odoo openreceive configure --lsc-uri-primary=- -d <database> < /secure/path/swap-code
354
+ odoo openreceive configure --enable -d <database>
355
+ odoo openreceive doctor -d <database>
356
+ ```
357
+
358
+ In Docker, start each with `docker compose exec -T odoo /entrypoint.sh`; `-T`
359
+ passes the file through. `--enable` publishes the provider in every company.
360
+ Saving a swap code renames the payment method "Bitcoin & stablecoins"; a name
361
+ you gave it yourself stays. Skip the swap code for Bitcoin-only checkout.
362
+
363
+ `doctor` checks the module and the Python package versions, each code as set
364
+ or unset (never its value), the wallet, the tables, the provider in each
365
+ company, the payment method, the checkout's files, the scheduled action, the
366
+ price feed for each company's currency and the swap provider. It exits nonzero
367
+ when a check fails.
368
+
369
+ One wallet serves the whole database: every company's OpenReceive provider
370
+ uses the codes saved last.
371
+
372
+ ### Check it
373
+
374
+ Make a Lightning invoice through the same route the checkout page uses, for a
375
+ new $5 test transaction, or for any unpaid OpenReceive transaction by its
376
+ reference:
377
+
378
+ ```sh
379
+ odoo openreceive test-invoice --new -d <database>
380
+ odoo openreceive test-invoice --reference S00012-1 -d <database>
381
+ ```
382
+
383
+ `--new` creates a draft payment transaction for a test contact it creates
384
+ once, `openreceive-test@example.invalid`, with no order behind it, so no
385
+ customer sees it. `--amount=` changes the amount, in the company's currency.
386
+ It prints the amount in sats, the Lightning invoice, then each method the
387
+ checkout offers: Bitcoin Lightning, and each swap asset with its network and
388
+ whether it is available for this amount. A small amount is often below a swap
389
+ provider's minimum; that is the amount, not a fault.
390
+
391
+ ### How a payment works
392
+
393
+ 1. The customer picks OpenReceive on Odoo's payment step, at checkout or on an
394
+ invoice's payment link, and clicks **Pay**. Odoo creates its payment
395
+ transaction and sends the customer to the module's checkout page for it.
396
+ 2. The module charges the transaction's amount, in its currency, converted to
397
+ sats at the current BTC price. Only the browser session that started the
398
+ payment can see its checkout page and make or follow its invoice: Odoo
399
+ records that transaction in the session, as its own payment status page
400
+ does.
401
+ 3. Once the wallet reports the payment, the module marks the transaction done
402
+ and runs Odoo's post-processing in the same database transaction that
403
+ settles it: the order is confirmed or the invoice paid. Should the
404
+ post-processing fail, the transaction stays done and Odoo's own scheduled
405
+ action finishes it.
406
+ 4. The checkout takes the customer to Odoo's payment status page, which takes
407
+ them on to the order's confirmation.
408
+
409
+ The checkout asks the wallet while the page is open. If the customer closes it
410
+ before the payment settles, the module's scheduled action finds the payment
411
+ within a minute. `odoo openreceive reconcile -d <database>` runs one pass by
412
+ hand.
413
+
414
+ A customer who reloads the checkout page gets the same Lightning invoice
415
+ again while it is still valid. Paying again from the order starts a new Odoo
416
+ transaction with its own invoice; the earlier invoice still counts if paid.
417
+
418
+ Odoo's log records each settlement under `odoo.addons.payment_openreceive`.
419
+
420
+ ### Refunds and removal
421
+
422
+ The receive-only wallet cannot send refunds. Send a refund from your own
423
+ wallet, then record it in Odoo. A customer whose swap deposit never converted
424
+ reclaims it from the same transaction's checkout page, while the transaction
425
+ is still unpaid. If you turn on swaps, you commit to keeping that path
426
+ available. See [swap refunds](https://openreceive.org/guides/swap-refunds.md).
427
+
428
+ Uninstalling the module deletes the saved codes and keeps the two payment
429
+ tables, which are a record of payments received. Odoo keeps the provider and
430
+ its transactions, as it does for any provider whose module is removed.
431
+
432
+ ### Tested, and not tested
433
+
434
+ Tested on 2026-10-19 with Odoo 19 and Odoo 20 from their official Docker
435
+ images, PostgreSQL 17, a test wallet and a test swap provider: install from
436
+ the built ZIP, configure from stdin and from the provider form, the doctor,
437
+ `test-invoice --new`, and a signed-in customer ordering through the shop and
438
+ paying by Lightning and by USDT on Solana in Chromium, after which the sale
439
+ order is confirmed. A payment whose page was closed was recorded by the
440
+ scheduled action. Another customer, a visitor and a request without Odoo's
441
+ CSRF token were refused. The module's own tests run on both series.
442
+
443
+ Not tested: Odoo.sh, Odoo's Debian package, paying an invoice from its
444
+ payment link, multi-company shops, and Odoo 18 or older, which the module does
445
+ not install on. Lightning cannot pull a payment, so
446
+ OpenReceive offers no subscriptions or saved payment tokens.
@@ -17,7 +17,7 @@ curl -fsSL https://openreceive.org/agent-directions/paymenter/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.29.
20
+ These directions describe OpenReceive 0.4.30.
21
21
 
22
22
  Install and configure the OpenReceive payment gateway in the Paymenter billing
23
23
  panel you are working in. Preserve its theme, clients, products, invoices and
@@ -97,7 +97,7 @@ release. With Paymenter's official Docker image, download and unpack it inside
97
97
  the container, as the web user:
98
98
 
99
99
  ```sh
100
- docker compose exec -T -u nginx paymenter sh -c 'cd /app/extensions/Gateways && curl -fsSLO https://github.com/OpenReceive/openreceive/releases/download/v0.4.29/openreceive-paymenter-0.4.29.zip && unzip -q openreceive-paymenter-0.4.29.zip && rm openreceive-paymenter-0.4.29.zip'
100
+ docker compose exec -T -u nginx paymenter sh -c 'cd /app/extensions/Gateways && curl -fsSLO https://github.com/OpenReceive/openreceive/releases/download/v0.4.30/openreceive-paymenter-0.4.30.zip && unzip -q openreceive-paymenter-0.4.30.zip && rm openreceive-paymenter-0.4.30.zip'
101
101
  docker compose exec -T -u nginx paymenter php artisan app:extension:install gateway OpenReceive
102
102
  ```
103
103
 
@@ -207,7 +207,6 @@ Paymenter's scheduler has never run, say so in one line of that message.
207
207
  - [Lightning Swap Connect URI](https://openreceive.org/guides/lightning-swap-connect.md)
208
208
  - [Security](https://openreceive.org/guides/security.md)
209
209
  - [Price Feeds](https://openreceive.org/guides/price-feeds.md)
210
- - [Payment Safety Upgrade](https://openreceive.org/guides/payment-safety-upgrade.md)
211
210
 
212
211
  ---
213
212
 
@@ -243,9 +242,9 @@ directory, next to Stripe and PayPal:
243
242
 
244
243
  ```sh
245
244
  cd /var/www/paymenter
246
- curl -fsSLO https://github.com/OpenReceive/openreceive/releases/download/v0.4.29/openreceive-paymenter-0.4.29.zip
247
- unzip -q openreceive-paymenter-0.4.29.zip -d extensions/Gateways
248
- rm openreceive-paymenter-0.4.29.zip
245
+ curl -fsSLO https://github.com/OpenReceive/openreceive/releases/download/v0.4.30/openreceive-paymenter-0.4.30.zip
246
+ unzip -q openreceive-paymenter-0.4.30.zip -d extensions/Gateways
247
+ rm openreceive-paymenter-0.4.30.zip
249
248
  chown -R www-data:www-data extensions/Gateways/OpenReceive
250
249
  sudo -u www-data php artisan app:extension:install gateway OpenReceive
251
250
  ```