openreceive 0.4.3 → 0.4.5

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.
@@ -1,6 +1,6 @@
1
1
  # OpenReceive agent directions (Rails)
2
2
 
3
- These directions describe OpenReceive 0.4.3.
3
+ These directions describe OpenReceive 0.4.5.
4
4
 
5
5
  Add OpenReceive to a Rails application — the app you are already working in. You
6
6
  do not need a copy of the OpenReceive source: the gem is on RubyGems, the
@@ -14,6 +14,13 @@ models (`ShopOrder`, `ShopUser`, a signed-cookie visitor) over tables that
14
14
  already exist. Find this application's order, product, and user models — whatever
15
15
  they are actually named — and map the three hooks onto those.
16
16
 
17
+ Keep this application's view layer, its Devise/session authentication and its
18
+ database. Pick the frontend package that matches what already renders here
19
+ (`@openreceive/elements` for ERB/Hotwire; `/react`, `/vue`, `/svelte` or
20
+ `/angular` for an existing SPA) — do not add React to a Hotwire app. Reuse the
21
+ app's existing session or `current_user` in `config.authorize`; the engine's
22
+ migration adds only its own two tables to the app's database.
23
+
17
24
  ## What OpenReceive is
18
25
 
19
26
  A payment library that runs inside YOUR server. It mounts HTTP routes in the
@@ -217,8 +224,12 @@ built on `@openreceive/browser/headless`. Read that before writing components.
217
224
  "switch payment method".
218
225
  - No "Open wallet" button on desktop.
219
226
  - Wallet suggestions: `getPaymentWizardRoutes()` +
220
- `createWizardRouteDisplays`. Lightning only. Host the icons with
221
- `asset-base-url`. The registry answers ~37 wallets: pass
227
+ `createWizardRouteDisplays`. Lightning only. Every image ships inside
228
+ the JavaScript logos as data URIs, tutorials once `loadPayTutorialImages()`
229
+ resolves (`image` is `undefined` until then) — so serve nothing and set no
230
+ asset option. When it works, the logos and payment icons render; a missing
231
+ image means a CSP `img-src` that blocks `data:`, and the console names it.
232
+ The registry answers ~37 wallets: pass
222
233
  `providerPreviewLimit` and build "show all" from `display.providerCount`,
223
234
  or they push the QR off the screen.
224
235
 
@@ -233,10 +244,9 @@ enough; drop the `.md` for the same page a person would read.
233
244
  - https://openreceive.org/guides/frontend-checkout.md — the drop-in's props, attributes and slots
234
245
  - https://openreceive.org/guides/checkout-ux.md — read before building any custom UI
235
246
  - https://openreceive.org/guides/headless-checkout.md — the controller, the display models, refunds
236
- - https://openreceive.org/guides/provider-registry.md — where the packaged icons and pay
237
- tutorials come from, and how to serve them. The asset rule is the one a custom
238
- UI is most likely to get wrong; this is the page that owns it, not the summary
239
- in checkout-ux.md
247
+ - https://openreceive.org/guides/provider-registry.md — where the wallet logos and pay
248
+ tutorials come from: inside the JavaScript, nothing to serve. This is the page
249
+ that owns the image rule, not the summary in checkout-ux.md
240
250
  - https://openreceive.org/guides/automated-swaps.md — only if `LSC_URI_PRIMARY` is set
241
251
  - https://openreceive.org/guides/swap-refunds.md — the refund flow, and the route back to it. Read it before you turn swaps on
242
252
  - https://openreceive.org/guides/lightning-swap-connect.md — what an `LSC_URI_*` code actually is
@@ -261,7 +271,7 @@ passes. The page it comes from is https://openreceive.org/guides/quickstart-rail
261
271
 
262
272
  ## Rails quickstart
263
273
 
264
- Requires Ruby ≥ 3.2.
274
+ Requires Ruby ≥ 3.2 and Rails ≥ 8.0.
265
275
 
266
276
  Add the Rails engine gem to your `Gemfile`:
267
277
 
@@ -356,6 +366,13 @@ config.on_paid = lambda do |settlement|
356
366
  end
357
367
  ```
358
368
 
369
+ **Unlocking a download works the same way.** If what the payer bought is a
370
+ file, do not unlock it in the browser: gate the download route on the paid
371
+ order row — `Order.find_by(id: params[:id], user: current_user, state: "paid")`
372
+ or a 404 — and serve the file only then. The `state: "paid"` written above is
373
+ the unlock; the client never decides an order was fulfilled, it re-reads the
374
+ row. Buy a Button's `ShopController#download` is this in twenty lines.
375
+
359
376
  Both shapes are idempotent, and both are correct. They differ only in whether
360
377
  your model layer gets to run: `update_all` skips it and is the right default;
361
378
  the row lock holds the row for the duration of the block and is what you want
@@ -450,10 +467,32 @@ end
450
467
  settlement transaction, only for the first settled attempt for a reference.
451
468
  → [OpenReceive.configure](https://openreceive.org/guides/api-reference.md#openreceiveconfigure)
452
469
 
453
- The engine inherits your application's `protect_from_forgery`. Keep
470
+ The engine's controllers inherit from `config.parent_controller` — the
471
+ generated initializer sets it to `"ApplicationController"`. That is how the
472
+ engine picks up your application's `protect_from_forgery`. Keep
454
473
  `csrf_meta_tags` in the layout that renders the checkout; the checkout client
455
474
  sends `X-CSRF-Token` from it automatically.
456
475
 
476
+ The same inheritance brings every global `before_action` your
477
+ `ApplicationController` declares. A filter that redirects signed-out users to
478
+ a login page will redirect the engine's JSON routes too, and a guest checkout
479
+ then never gets an invoice. The engine reads nothing from the parent except
480
+ that forgery protection — `config.authorize` receives the request and your
481
+ policy reads its own session from it — so if your `ApplicationController`
482
+ carries such filters, either point `config.parent_controller` at a slimmer
483
+ controller that still calls `protect_from_forgery`, or skip the filter for
484
+ the engine only:
485
+
486
+ ```ruby
487
+ # config/initializers/openreceive.rb (after OpenReceive.configure)
488
+ Rails.application.config.to_prepare do
489
+ OpenReceive::ApplicationController.skip_before_action :require_login
490
+ end
491
+ ```
492
+
493
+ Filters your authorize policy depends on (a tenant resolver, `Current`
494
+ attributes) should stay: they run before `config.authorize`.
495
+
457
496
  The generated initializer ships
458
497
  `config.on_paid = OpenReceive::LOGGING_ON_PAID` — a placeholder that only logs
459
498
  the settlement and fulfills nothing. Replace it with your real fulfillment (as
@@ -506,27 +545,33 @@ import "@openreceive/elements/styles.css"; // or link the compiled styles.css
506
545
  defineElements();
507
546
  ```
508
547
 
509
- Bundling with esbuild (jsbundling-rails)? Two things:
510
-
511
- 1. Build ESM and load it as a module. esbuild's default IIFE output evaluates
512
- a dependency's Node fallback in the browser and throws
513
- `ReferenceError: __filename is not defined`:
548
+ Bundling with esbuild (jsbundling-rails)? Build ESM and load it as a module.
549
+ esbuild's default IIFE output evaluates a dependency's Node fallback in the
550
+ browser and throws `ReferenceError: __filename is not defined`:
514
551
 
515
- ```sh
516
- esbuild app/javascript/application.js --bundle --format=esm --outdir=app/assets/builds
517
- ```
552
+ ```sh
553
+ esbuild app/javascript/application.js --bundle --format=esm --outdir=app/assets/builds
554
+ ```
518
555
 
519
- ```erb
520
- <%= javascript_include_tag "application", type: "module" %>
521
- ```
556
+ ```erb
557
+ <%= javascript_include_tag "application", type: "module" %>
558
+ ```
522
559
 
523
- 2. Serve the provider images. The payment-method icons are compiled into
524
- `@openreceive/browser` and need nothing, but the wallet logos and pay
525
- tutorials are files shipped in `@openreceive/provider-data`, and only
526
- Vite-style bundlers resolve them from the import. Copy that package's
527
- `dist/assets` tree to `public/openreceive-assets/assets/` and set
528
- `asset-base-url="/openreceive-assets"` on the element
529
- ([Provider registry](https://openreceive.org/guides/provider-registry.md#assets)).
560
+ Everything the checkout draws ships inside the JavaScript: the payment-method
561
+ icons, the wallet logos and the pay tutorials. There is no image file to copy
562
+ or serve and no asset option to set. Deploy your normal JavaScript and CSS
563
+ build output, including any generated JavaScript chunks. Bundlers with code
564
+ splitting can defer tutorial screenshots until first open; single-file builds
565
+ (including the standalone checkout) include them upfront. If your
566
+ Content-Security-Policy has a strict `img-src`, allow `data:`
567
+ ([Provider registry](https://openreceive.org/guides/provider-registry.md#assets)).
568
+
569
+ Then open the checkout in a browser, confirm the payment-method icons and
570
+ wallet logos render, and open a wallet's pay tutorial to check its screenshots.
571
+ If an image is missing, inspect the console for CSP violations and the Network
572
+ panel for failed JavaScript chunks. Allow `data:` in `img-src` and deploy the
573
+ complete build output. Do not add image routes, copy package source images, or
574
+ use registry `icon_path` / tutorial `path` keys as browser URLs.
530
575
 
531
576
  The element creates the checkout for `reference`, then renders and polls
532
577
  itself. React/Vue/Svelte/Angular apps use the matching wrapper package
@@ -0,0 +1,153 @@
1
+ # OpenReceive agent directions (WordPress + WooCommerce)
2
+
3
+ These directions describe OpenReceive 0.4.5.
4
+
5
+ Install and configure the OpenReceive gateway in the existing WooCommerce
6
+ store. Preserve its theme, checkout, customer accounts, order model and prices.
7
+ The plugin bundles the PHP engine and checkout assets; the merchant does not
8
+ install npm or Composer packages on the WordPress server.
9
+
10
+ ## Step 0 — inspect configuration
11
+
12
+ Check WordPress, WooCommerce and PHP versions, GMP and sodium availability,
13
+ whether the plugin is installed, and whether the Doctor panel reports the
14
+ receive-only NWC credential as set. Never display its value. For a real store,
15
+ ask the merchant to configure a receive-only wallet if none is available.
16
+ For repository development, use the Docker demo's explicit testkit override.
17
+
18
+ Upload a built plugin archive, not a zip of the source directory. The plugin
19
+ has not yet been accepted into the WordPress.org directory. Configuration and
20
+ the complete quickstart follow below.
21
+
22
+ The plugin owns only its payment-attempt tables in the WordPress database.
23
+ WooCommerce owns orders, totals, stock and email. Do not add an external
24
+ idempotency store, payment database, browser wallet credentials or custom
25
+ fulfillment implementation. Guest return links use WooCommerce's order key;
26
+ the plugin verifies it before issuing an expiring order-bound cookie.
27
+
28
+ Run `wp openreceive doctor` after configuration. Use the documented scheduled
29
+ reconciliation or optional notifications command for offline settlement.
30
+ Manual merchant refunds and provider-managed payer swap refunds are separate
31
+ flows; a receive-only NWC wallet cannot send payments.
32
+
33
+ ## Further reading
34
+
35
+ - [Express Quickstart (Node)](https://openreceive.org/guides/quickstart-node.md)
36
+ - [Fastify Quickstart](https://openreceive.org/guides/quickstart-fastify.md)
37
+ - [FastAPI Quickstart](https://openreceive.org/guides/quickstart-fastapi.md)
38
+ - [Django Quickstart](https://openreceive.org/guides/quickstart-django.md)
39
+ - [Next.js Quickstart](https://openreceive.org/guides/quickstart-next.md)
40
+ - [Rails Quickstart](https://openreceive.org/guides/quickstart-rails.md)
41
+ - [PHP Quickstart (plain PHP)](https://openreceive.org/guides/quickstart-php.md)
42
+ - [Laravel Quickstart](https://openreceive.org/guides/quickstart-laravel.md)
43
+ - [BTCPay Server Quickstart](https://openreceive.org/guides/quickstart-btcpay.md)
44
+ - [BTCPay Plugin Reference](https://openreceive.org/guides/btcpay-reference.md)
45
+ - [Node ORM Recipes](https://openreceive.org/guides/node-orms.md)
46
+ - [Authorization](https://openreceive.org/guides/authorization.md)
47
+ - [Rate Limiting](https://openreceive.org/guides/rate-limiting.md)
48
+ - [Frontend Checkout](https://openreceive.org/guides/frontend-checkout.md)
49
+ - [Checkout UX](https://openreceive.org/guides/checkout-ux.md)
50
+ - [Headless Checkout](https://openreceive.org/guides/headless-checkout.md)
51
+ - [Automated Swaps](https://openreceive.org/guides/automated-swaps.md)
52
+ - [Swap Refunds](https://openreceive.org/guides/swap-refunds.md)
53
+ - [Lightning Swap Connect URI](https://openreceive.org/guides/lightning-swap-connect.md)
54
+ - [Environment Variables](https://openreceive.org/guides/environment-variables.md)
55
+ - [Payment Storage](https://openreceive.org/guides/storage.md)
56
+ - [Deploying OpenReceive](https://openreceive.org/guides/deploying.md)
57
+ - [Testing Your OpenReceive Integration](https://openreceive.org/guides/host-testing.md)
58
+ - [API Reference](https://openreceive.org/guides/api-reference.md)
59
+ - [Security](https://openreceive.org/guides/security.md)
60
+ - [Provider Registry](https://openreceive.org/guides/provider-registry.md)
61
+ - [Price Feeds](https://openreceive.org/guides/price-feeds.md)
62
+ - [React Material UI Recipe](https://openreceive.org/guides/react-material-ui-recipe.md)
63
+ - [Flask Recipe](https://openreceive.org/guides/flask-recipe.md)
64
+ - [Writing Your Own Checkout Route](https://openreceive.org/guides/custom-checkout-route.md)
65
+ - [Agent Directions: Node.js](https://openreceive.org/guides/agent-directions-node.md)
66
+ - [Agent Directions: Fastify](https://openreceive.org/guides/agent-directions-fastify.md)
67
+ - [Agent Directions: FastAPI](https://openreceive.org/guides/agent-directions-fastapi.md)
68
+ - [Agent Directions: Django](https://openreceive.org/guides/agent-directions-django.md)
69
+ - [Agent Directions: Next.js](https://openreceive.org/guides/agent-directions-next.md)
70
+ - [Agent Directions: Rails](https://openreceive.org/guides/agent-directions-rails.md)
71
+ - [Agent Directions: PHP](https://openreceive.org/guides/agent-directions-php.md)
72
+ - [Agent Directions: Laravel](https://openreceive.org/guides/agent-directions-laravel.md)
73
+ - [Agent Directions: BTCPay Server](https://openreceive.org/guides/agent-directions-btcpay.md)
74
+ - [WordPress + WooCommerce Quickstart](https://openreceive.org/guides/quickstart-woocommerce.md)
75
+
76
+ ---
77
+
78
+ ## The quickstart, in full
79
+
80
+ Inlined verbatim so this file needs no network access — follow it once Step 0
81
+ passes. The page it comes from is https://openreceive.org/guides/quickstart-woocommerce.
82
+
83
+ ## WordPress + WooCommerce quickstart
84
+
85
+ Install the built OpenReceive plugin zip through **Plugins → Add New → Upload
86
+ Plugin**, with WooCommerce already active. The source directory needs a build;
87
+ it cannot be uploaded as-is. WordPress.org submission is still pending.
88
+
89
+ Requirements: WordPress 6.6+, WooCommerce 9+, 64-bit PHP 8.2+ with GMP and sodium,
90
+ and MySQL 8 or MariaDB 10.5+. Activation creates payment-attempt tables in the
91
+ existing WordPress database. No separate database or application is required.
92
+
93
+ ### Configure the wallet
94
+
95
+ Open **WooCommerce → Settings → Payments → OpenReceive**. Enter a receive-only
96
+ NWC code, save, then enable the gateway. Saving verifies receive permissions
97
+ and fails closed on a spend-capable wallet unless the explicit override is set.
98
+ The password fields never show saved credentials. Values are encrypted using
99
+ keys derived from WordPress's authentication keys; re-enter them after rotating
100
+ those keys.
101
+
102
+ For managed deployments, configure `OPENRECEIVE_NWC_URI` in `wp-config.php` from
103
+ your server's secret environment. It takes precedence over the settings field.
104
+ Optional `OPENRECEIVE_LSC_URI_PRIMARY` and `OPENRECEIVE_LSC_URI_BACKUP` constants
105
+ configure swap providers. Never put these values in browser code or logs.
106
+
107
+ ### Checkout and settlement
108
+
109
+ Both WooCommerce checkout blocks and classic checkout redirect to the order-pay
110
+ page. The plugin reads the amount from `WC_Order`, serves the bundled checkout,
111
+ and authorizes the customer through their account, checkout session or an
112
+ expiring signed cookie issued after verifying the order-pay key. Keep that
113
+ order-pay URL available to customers returning to a pending payment or swap
114
+ refund. The plugin verifies that each requested payment hash belongs to the order.
115
+
116
+ Payment attempts persist before invoice instructions appear. Settlement commits
117
+ once in the payment transaction. WooCommerce's `payment_complete` then handles
118
+ status, stock and emails. A durable order marker lets subsequent requests and
119
+ scheduled passes repair an interruption between settlement and order completion.
120
+
121
+ The checkout polling drives opportunistic reconciliation through the PHP
122
+ engine's shared database gate. Action Scheduler adds a recurring one-minute
123
+ safety net. Configure a system cron to run WordPress scheduled work on stores
124
+ with little traffic; no page visits means WP-Cron alone cannot guarantee prompt
125
+ settlement. Optional process-manager commands:
126
+
127
+ ```sh
128
+ wp openreceive doctor
129
+ wp openreceive reconcile
130
+ wp openreceive notifications
131
+ ```
132
+
133
+ The notifications command runs as a separate process. The Doctor panel in the
134
+ gateway settings reports schema, credential presence, scheduling and attention
135
+ orders. A currency without a usable price feed makes the gateway unavailable.
136
+
137
+ ### Refunds and removal
138
+
139
+ The receive-only wallet cannot send merchant refunds. Make those manually from
140
+ your wallet. Payer swap refunds use the configured provider through the same
141
+ authorized order-pay page; enabling LSC payments commits the shop to keeping
142
+ that recovery path available. See [swap refunds](https://openreceive.org/guides/swap-refunds.md).
143
+
144
+ Deactivation preserves payment records. Deleting the plugin drops its two
145
+ tables only if **Remove data on uninstall** was enabled. WooCommerce orders are
146
+ retained.
147
+
148
+ ### Local example
149
+
150
+ The repository's `examples/wordpress` Docker stack builds the plugin and seeds
151
+ WooCommerce from the shared button catalog. Run `npm run demo wordpress` for
152
+ the real-wallet mode, or use its documented `compose.testkit.yml` override for
153
+ a disposable fake-wallet shop. No testkit routes are registered by default.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openreceive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenReceive
@@ -35,6 +35,7 @@ files:
35
35
  - README.md
36
36
  - lib/openreceive.rb
37
37
  - lib/openreceive/core.rb
38
+ - lib/openreceive/generated/tables.rb
38
39
  - lib/openreceive/keccak256.rb
39
40
  - lib/openreceive/nwc_ruby.rb
40
41
  - lib/openreceive/rates.rb
@@ -42,8 +43,16 @@ files:
42
43
  - lib/openreceive/version.rb
43
44
  - skills/debug-openreceive-payment/SKILL.md
44
45
  - skills/integrate-openreceive/SKILL.md
46
+ - skills/integrate-openreceive/references/btcpay.md
47
+ - skills/integrate-openreceive/references/django.md
48
+ - skills/integrate-openreceive/references/fastapi.md
49
+ - skills/integrate-openreceive/references/fastify.md
50
+ - skills/integrate-openreceive/references/laravel.md
51
+ - skills/integrate-openreceive/references/next.md
45
52
  - skills/integrate-openreceive/references/node.md
53
+ - skills/integrate-openreceive/references/php.md
46
54
  - skills/integrate-openreceive/references/rails.md
55
+ - skills/integrate-openreceive/references/woocommerce.md
47
56
  homepage: https://openreceive.org
48
57
  licenses:
49
58
  - MIT