Class: OpenReceive::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/openreceive/configuration.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeConfiguration

Returns a new instance of Configuration.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/openreceive/configuration.rb', line 49

def initialize
  @parent_controller = "ActionController::Base"
  @nwc = nil
  @nwc_client = nil
  @authorize = nil
  @amount_for = nil
  @on_paid = nil
  @resolve_checkout = nil
  @on_checkout_created = nil
  @rate_limit = nil
  # Built-in per-IP invoice rate limiting (mirrors the JS `rateLimiting`
  # option): OFF by default — shared-IP deployments (POS terminals,
  # kiosks) must never be throttled by accident. `true` caps invoice
  # creation at 60 per client IP per rolling hour, counted from the
  # engine-owned openreceive_payments rows; or a Hash with
  # limit_per_hour / limit_per_day. Mutually exclusive with rate_limit.
  @rate_limiting = false
  # Client IP attribution: a proc receiving the framework request.
  # Defaults to ActionDispatch::Request#ip (which honors the app's
  # trusted-proxy configuration).
  @client_ip = nil
  # nil (the default) mirrors the JS createOpenReceive defaults: the
  # price provider becomes the built-in cached live price feed (with
  # OPENRECEIVE_PRICE_FEED_*_URL overrides), and swap providers are
  # auto-built from LSC_URI_PRIMARY / LSC_URI_BACKUP. Set an explicit
  # value (e.g. swap_providers = []) to override.
  @price_provider = nil
  @swap_providers = nil
  @price_currencies = ["USD"]
  @allow_spend_capable_wallet = false
  # Opportunistic settlement discovery, ON by default (mirrors the JS
  # handler's opportunisticReconcile): every engine request first runs one
  # durably gated reconcile pass when attempts are pending, so abandoned
  # checkouts settle on any later OpenReceive call with no scheduled job.
  # The openreceive_meta gate row is shared by every Puma worker/process on
  # the host database (min 2s between real wallet scans, stretched by
  # invoice age). Set false to disable (e.g. when the optional
  # `bin/rails openreceive:notifications` worker owns scanning), or a Hash
  # with min_interval_seconds to tune.
  @opportunistic_reconcile = true
  # The production boot preflight (Engine's after_initialize): build the
  # service, and with it the wallet check, so a missing NWC_URI or a
  # spend-capable wallet stops a deploy instead of the first customer. ON by
  # default. Asset builds are detected and skipped automatically (see
  # OpenReceive.eager_preflight?); set false for any other boot that must
  # come up without wallet secrets.
  @eager_preflight = true
end

Instance Attribute Details

#allow_spend_capable_walletObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def allow_spend_capable_wallet
  @allow_spend_capable_wallet
end

#amount_forObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def amount_for
  @amount_for
end

#authorizeObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def authorize
  @authorize
end

#client_ipObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def client_ip
  @client_ip
end

#eager_preflightObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def eager_preflight
  @eager_preflight
end

#nwcObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def nwc
  @nwc
end

#nwc_clientObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def nwc_client
  @nwc_client
end

#on_checkout_createdObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def on_checkout_created
  @on_checkout_created
end

#on_paidObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def on_paid
  @on_paid
end

#opportunistic_reconcileObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def opportunistic_reconcile
  @opportunistic_reconcile
end

#parent_controllerObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def parent_controller
  @parent_controller
end

#price_currenciesObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def price_currencies
  @price_currencies
end

#price_providerObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def price_provider
  @price_provider
end

#rate_limitObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def rate_limit
  @rate_limit
end

#rate_limitingObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def rate_limiting
  @rate_limiting
end

#resolve_checkoutObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def resolve_checkout
  @resolve_checkout
end

#swap_providersObject

Quickstart contract: authorize + amount_for + on_paid. The engine derives checkout resolution, attempt commit, and settlement write-once from the engine-owned OpenReceivePayment model.

Advanced escape hatch: hosts with a custom payment repository configure resolve_checkout and on_checkout_created together; on_paid then receives the raw settlement event and owns replay safety itself.



42
43
44
# File 'lib/openreceive/configuration.rb', line 42

def swap_providers
  @swap_providers
end

Instance Method Details

#advanced_hooks?Boolean

Returns:

  • (Boolean)


138
139
140
# File 'lib/openreceive/configuration.rb', line 138

def advanced_hooks?
  !@resolve_checkout.nil? && !@on_checkout_created.nil?
end

#request_handlerObject



114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/openreceive/configuration.rb', line 114

def request_handler
  validate!
  @request_handler ||= OpenReceive::Server::RequestHandler.new(
    service: service,
    authorize: @authorize,
    resolve_checkout: @resolve_checkout || engine_resolve_checkout,
    on_checkout_created: @on_checkout_created || engine_on_checkout_created,
    on_paid: settlement_hook,
    rate_limit: resolved_rate_limit,
    client_ip: resolved_client_ip
  )
end

#reset_runtime!Object



142
143
144
145
146
147
# File 'lib/openreceive/configuration.rb', line 142

def reset_runtime!
  %i[@service @request_handler @settlement_hook @resolved_nwc_client].each do |name|
    remove_instance_variable(name) if instance_variable_defined?(name)
  end
  self
end

#serviceObject



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/openreceive/configuration.rb', line 98

def service
  validate!
  # The Rails logger, so the service's operator diagnostics actually land:
  # the detailed invoice-expiry rejection ("requested Xs, got Ys…") and the
  # spend-capable override warning are logged, never sent, so without this
  # a Rails operator saw only the short 502 wire message.
  @service ||= OpenReceive::Server::Service.new(
    nwc_client: resolved_nwc_client,
    price_provider: @price_provider,
    swap_providers: @swap_providers,
    price_currencies: @price_currencies,
    allow_spend_capable_wallet: @allow_spend_capable_wallet,
    logger: rails_logger
  )
end

#settlement_hookObject

The settlement-event hook shared by payments/check and OpenReceive.reconcile!. In quickstart mode it delivers through OpenReceivePayment.mark_paid_once!, so config.on_paid fires only for the order's FIRST settled attempt, inside the settlement transaction; a later duplicate settlement is recorded (status_reason "duplicate_settlement") but never fulfilled again.



132
133
134
135
136
# File 'lib/openreceive/configuration.rb', line 132

def settlement_hook
  return @on_paid if advanced_hooks?

  @settlement_hook ||= engine_settlement_hook
end

#validate!Object

Raises:



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/openreceive/configuration.rb', line 149

def validate!
  raise ConfigurationError, "OpenReceive.config.authorize is required." if @authorize.nil?
  if @rate_limiting && @rate_limit
    raise ConfigurationError,
          "Set either OpenReceive.config.rate_limiting or a custom rate_limit hook, not both."
  end
  if @rate_limiting && advanced_hooks?
    raise ConfigurationError,
          "config.rate_limiting counts engine-owned OpenReceivePayment rows; with a custom " \
          "repository (resolve_checkout/on_checkout_created), pass a custom rate_limit hook " \
          "backed by your own store instead."
  end
  if @opportunistic_reconcile && advanced_hooks?
    # Same fail-at-construction idiom as the JS handler: the default
    # settlement path needs the engine-owned durable gate and payment rows;
    # a custom repository must opt out explicitly, never degrade silently.
    raise ConfigurationError,
          "config.opportunistic_reconcile (on by default) scans engine-owned " \
          "OpenReceivePayment rows through the shared openreceive_meta gate; with a custom " \
          "repository (resolve_checkout/on_checkout_created), set " \
          "config.opportunistic_reconcile = false and run your own settlement worker."
  end
  if @on_paid.nil?
    raise ConfigurationError, "OpenReceive.config.on_paid is required to durably record settlement."
  end
  if @resolve_checkout.nil? != @on_checkout_created.nil?
    raise ConfigurationError,
          "OpenReceive.config.resolve_checkout and on_checkout_created must be configured together (advanced mode)."
  end
  if !advanced_hooks? && @amount_for.nil?
    raise ConfigurationError,
          "Set OpenReceive.config.amount_for (quickstart), " \
          "or resolve_checkout and on_checkout_created (advanced)."
  end
  resolved_nwc_client
  true
end