openreceive 0.4.25 → 0.4.27
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 +4 -4
- data/CHANGELOG.md +16 -0
- data/lib/openreceive/version.rb +1 -1
- data/skills/integrate-openreceive/SKILL.md +20 -5
- data/skills/integrate-openreceive/references/astro.md +653 -0
- data/skills/integrate-openreceive/references/btcpay.md +1 -1
- data/skills/integrate-openreceive/references/django.md +37 -3
- data/skills/integrate-openreceive/references/fastapi.md +38 -3
- data/skills/integrate-openreceive/references/fastify.md +41 -3
- data/skills/integrate-openreceive/references/flask.md +37 -3
- data/skills/integrate-openreceive/references/laravel.md +16 -3
- data/skills/integrate-openreceive/references/lovable.md +12 -2
- data/skills/integrate-openreceive/references/mobile.md +492 -0
- data/skills/integrate-openreceive/references/nestjs.md +54 -15
- data/skills/integrate-openreceive/references/next.md +44 -4
- data/skills/integrate-openreceive/references/node.md +45 -4
- data/skills/integrate-openreceive/references/nuxt.md +606 -0
- data/skills/integrate-openreceive/references/php.md +38 -10
- data/skills/integrate-openreceive/references/rails.md +29 -11
- data/skills/integrate-openreceive/references/react-router.md +617 -0
- data/skills/integrate-openreceive/references/sveltekit.md +650 -0
- data/skills/integrate-openreceive/references/tanstack-start.md +734 -0
- data/skills/integrate-openreceive/references/woocommerce.md +5 -5
- metadata +7 -1
|
@@ -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
|
|
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/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.
|
|
20
|
+
These directions describe OpenReceive 0.4.27.
|
|
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
|
|
267
|
-
settlement gate is a row in `openreceive_meta`,
|
|
268
|
-
|
|
269
|
-
|
|
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.
|
|
591
|
-
|
|
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,
|
|
@@ -712,8 +737,11 @@ foreach (\OpenReceive\Server\Doctor::report(
|
|
|
712
737
|
- where the handler is mounted;
|
|
713
738
|
- the receive-only wallet preflight.
|
|
714
739
|
|
|
715
|
-
`$engine->doctor()` is the same report for an engine you already built
|
|
716
|
-
|
|
740
|
+
`$engine->doctor()` is the same report for an engine you already built, but it
|
|
741
|
+
runs the wallet preflight only when you pass the same factory:
|
|
742
|
+
`$engine->doctor(walletCheck: static fn () => \OpenReceive\Server\Service::fromEnvironment())`.
|
|
743
|
+
Without it the preflight line reads `skipped`. Put the report behind a
|
|
744
|
+
`bin/doctor` script. The demo's is twelve lines.
|
|
717
745
|
→ [Doctor](https://openreceive.org/guides/api-reference.md#openreceiveserverdoctor)
|
|
718
746
|
|
|
719
747
|
Then open the checkout in a browser. Confirm the payment-method icons and
|
|
@@ -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
|
|
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.
|
|
20
|
+
These directions describe OpenReceive 0.4.27.
|
|
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>`.
|
|
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
|
|
@@ -409,13 +422,16 @@ That is the whole install. `openreceive-rails` depends on `openreceive`,
|
|
|
409
422
|
nothing else added. It is built from `NWC_URI`. If your app brings its own NWC
|
|
410
423
|
client, set `config.nwc_client` instead.
|
|
411
424
|
|
|
412
|
-
|
|
413
|
-
libsecp256k1 from source
|
|
414
|
-
|
|
415
|
-
`
|
|
425
|
+
Two native builds need system packages. `nwc-ruby` uses `rbsecp256k1`, which
|
|
426
|
+
builds libsecp256k1 from source and needs the autotools; without them
|
|
427
|
+
`bundle install` fails with `autoreconf: not found`. Its connection libraries
|
|
428
|
+
also need a newer `openssl` gem than Ruby ships, and Bundler compiles that gem
|
|
429
|
+
against the OpenSSL headers; without them it fails installing `openssl` at
|
|
430
|
+
`checking for openssl/ssl.h... no`. Minimal images (`ruby:3.3-slim`, fresh
|
|
431
|
+
Docker builds) have neither. Install them before bundling:
|
|
416
432
|
|
|
417
433
|
```sh
|
|
418
|
-
apt-get install -y autoconf automake libtool build-essential pkg-config
|
|
434
|
+
apt-get install -y autoconf automake libtool build-essential pkg-config libssl-dev
|
|
419
435
|
```
|
|
420
436
|
|
|
421
437
|
Full Ruby images and typical developer machines already have these.
|
|
@@ -603,9 +619,11 @@ settlement transaction, only for the first settled attempt for a reference.
|
|
|
603
619
|
|
|
604
620
|
The engine's controllers inherit from `config.parent_controller`. The generated
|
|
605
621
|
initializer sets it to `"ApplicationController"`. That is how the engine picks
|
|
606
|
-
up your application's `protect_from_forgery`.
|
|
607
|
-
|
|
608
|
-
it automatically
|
|
622
|
+
up your application's `protect_from_forgery`. The layout that renders the
|
|
623
|
+
checkout needs `<%= csrf_meta_tags %>` in its `<head>`: add it if it is not
|
|
624
|
+
there. The checkout client sends `X-CSRF-Token` from it automatically; without
|
|
625
|
+
it, every checkout answers 403 "Can't verify CSRF token authenticity". Do not
|
|
626
|
+
skip forgery protection for the engine to get past that 403.
|
|
609
627
|
|
|
610
628
|
The same inheritance also brings every global `before_action` that your
|
|
611
629
|
`ApplicationController` declares. A filter that redirects signed-out users to a
|