Class: RideBuilder::Affiliate::Client
- Inherits:
-
Object
- Object
- RideBuilder::Affiliate::Client
- Defined in:
- lib/ridebuilder/affiliate/client.rb
Overview
Server-side client for RideBuilder's FirstParty affiliate program: report checkout/return postbacks and prove integration liveness. Handles auth, per-attempt timeout, retry with exponential backoff + jitter, and idempotency. Port of the Node RideBuilderClient — same wire contract, verified by sdk/conformance.
Instance Method Summary collapse
-
#health_check ⇒ Object
Authenticated liveness ping (legacy alias).
-
#heartbeat ⇒ Object
Periodic liveness.
-
#initialize(api_key:, base_url: nil, max_retries: 3, timeout_ms: 10_000, environment: "production", transport: nil) ⇒ Client
constructor
A new instance of Client.
-
#register(capabilities: nil) ⇒ Object
Announce this integration on install/startup — the handshake.
-
#report_checkout(order_id:, subtotal:, currency:, click_id:) ⇒ Object
order_id is the server-side idempotency key, so a retried checkout never double-counts.
-
#report_return(return_id:, order_id:, refund_amount:, currency:) ⇒ Object
return_id is the server-side idempotency key, so a retried refund never double-counts.
-
#verify ⇒ Object
Self-test: verifies the API key is valid + active.
Constructor Details
#initialize(api_key:, base_url: nil, max_retries: 3, timeout_ms: 10_000, environment: "production", transport: nil) ⇒ Client
Returns a new instance of Client.
9 10 11 12 13 14 15 16 17 |
# File 'lib/ridebuilder/affiliate/client.rb', line 9 def initialize(api_key:, base_url: nil, max_retries: 3, timeout_ms: 10_000, environment: "production", transport: nil) raise Error.new("api_key must be a non-empty string", retryable: false) if api_key.nil? || api_key.strip.empty? @api_key = api_key @base_url = (base_url || DEFAULT_BASE_URL).sub(%r{/+\z}, "") @max_retries = max_retries @environment = environment == "sandbox" ? "sandbox" : "production" @transport = transport || NetHttpTransport.new(timeout_ms) end |
Instance Method Details
#health_check ⇒ Object
Authenticated liveness ping (legacy alias). Raises a terminal Error on a bad key.
49 50 51 |
# File 'lib/ridebuilder/affiliate/client.rb', line 49 def health_check HealthResult.new(true, send_request("POST", "/postback/health").status) end |
#heartbeat ⇒ Object
Periodic liveness. Call on a schedule so RideBuilder can tell "alive" from "went dark".
69 70 71 72 73 74 |
# File 'lib/ridebuilder/affiliate/client.rb', line 69 def heartbeat res = send_request("POST", "/integration/heartbeat", { "type" => SDK_TYPE, "environment" => @environment, "version" => VERSION }) HealthResult.new(true, res.status) end |
#register(capabilities: nil) ⇒ Object
Announce this integration on install/startup — the handshake. Idempotent; returns the integration id.
54 55 56 57 58 59 60 61 |
# File 'lib/ridebuilder/affiliate/client.rb', line 54 def register(capabilities: nil) res = send_request("POST", "/integration/register", { "type" => SDK_TYPE, "environment" => @environment, "version" => VERSION, "capabilities" => capabilities || DEFAULT_CAPABILITIES }) body = res.json.is_a?(Hash) ? res.json : {} RegisterResult.new(body["integrationId"] || "", body["status"] || "connected") end |
#report_checkout(order_id:, subtotal:, currency:, click_id:) ⇒ Object
order_id is the server-side idempotency key, so a retried checkout never double-counts.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/ridebuilder/affiliate/client.rb', line 20 def report_checkout(order_id:, subtotal:, currency:, click_id:) assert_non_empty(order_id, "order_id") amount = normalize_amount(subtotal, "subtotal") assert_currency(currency) unless ClickId.valid?(click_id) raise Error.new("click_id must be a valid RideBuilder click_id (UUID v4)", retryable: false) end res = send_request("POST", "/postback/checkout", { "order_id" => order_id, "order_subtotal" => amount, "currency" => currency, "ref" => ClickId::REF, "click_id" => click_id }) PostbackResult.new(true, res.status) end |
#report_return(return_id:, order_id:, refund_amount:, currency:) ⇒ Object
return_id is the server-side idempotency key, so a retried refund never double-counts.
36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/ridebuilder/affiliate/client.rb', line 36 def report_return(return_id:, order_id:, refund_amount:, currency:) assert_non_empty(return_id, "return_id") assert_non_empty(order_id, "order_id") amount = normalize_amount(refund_amount, "refund_amount") assert_currency(currency) res = send_request("POST", "/postback/return", { "return_id" => return_id, "order_id" => order_id, "refund_amount" => amount, "currency" => currency }) PostbackResult.new(true, res.status) end |
#verify ⇒ Object
Self-test: verifies the API key is valid + active. Raises a terminal Error on a bad/rotated key.
64 65 66 |
# File 'lib/ridebuilder/affiliate/client.rb', line 64 def verify HealthResult.new(true, send_request("GET", "/integration/verify").status) end |