Class: NakoPay::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/nakopay/client.rb

Overview

Low-level HTTP client. Most callers use the resource modules (NakoPay::Invoice, etc.) instead of touching this directly.

Constant Summary collapse

DEFAULT_BASE_URL =
"https://api.nakopay.com/v1"
DEFAULT_API_VERSION =
"2025-04-20"
DEFAULT_TIMEOUT =
30
DEFAULT_MAX_RETRIES =
3

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(api_key: nil, base_url: nil, api_version: nil, timeout: nil, max_retries: nil, faraday: nil) ⇒ Client

Returns a new instance of Client.

Parameters:

  • faraday (Faraday::Connection, nil) (defaults to: nil)

    optional Faraday connection for custom middleware stacks. When provided, Net::HTTP is not used.

Raises:

  • (ArgumentError)


19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/nakopay/client.rb', line 19

def initialize(api_key: nil, base_url: nil, api_version: nil, timeout: nil, max_retries: nil, faraday: nil)
  @api_key     = api_key     || NakoPay.api_key
  @base_url    = (base_url   || NakoPay.base_url    || DEFAULT_BASE_URL).chomp("/")
  @api_version = api_version || NakoPay.api_version || DEFAULT_API_VERSION
  @timeout     = timeout     || NakoPay.timeout     || DEFAULT_TIMEOUT
  @max_retries = max_retries || NakoPay.max_retries || DEFAULT_MAX_RETRIES
  @faraday     = faraday

  raise ArgumentError, "NakoPay: api_key is required" if @api_key.nil? || @api_key.empty?
  if @api_key.start_with?("pk_")
    raise ArgumentError, "NakoPay: a publishable key (pk_*) was passed to the server SDK; use a secret key (sk_live_* or sk_test_*)"
  end
end

Instance Attribute Details

#api_keyObject (readonly)

Returns the value of attribute api_key.



15
16
17
# File 'lib/nakopay/client.rb', line 15

def api_key
  @api_key
end

#api_versionObject (readonly)

Returns the value of attribute api_version.



15
16
17
# File 'lib/nakopay/client.rb', line 15

def api_version
  @api_version
end

#base_urlObject (readonly)

Returns the value of attribute base_url.



15
16
17
# File 'lib/nakopay/client.rb', line 15

def base_url
  @base_url
end

#max_retriesObject (readonly)

Returns the value of attribute max_retries.



15
16
17
# File 'lib/nakopay/client.rb', line 15

def max_retries
  @max_retries
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



15
16
17
# File 'lib/nakopay/client.rb', line 15

def timeout
  @timeout
end

Instance Method Details

#request(method, path, body: nil, query: nil, idempotency_key: nil, headers: {}) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/nakopay/client.rb', line 33

def request(method, path, body: nil, query: nil, idempotency_key: nil, headers: {})
  attempt = 0
  loop do
    begin
      code, raw, resp_headers = execute_request(method, path, body: body, query: query, idempotency_key: idempotency_key, headers: headers)
    rescue StandardError => e
      if attempt < @max_retries
        sleep_with_backoff(attempt, nil)
        attempt += 1
        next
      end
      raise NakoPay::ConnectionError, "network error: #{e.message}"
    end

    if code >= 200 && code < 300
      return raw.empty? ? nil : JSON.parse(raw)
    end

    env = (JSON.parse(raw) rescue {})
    api_err_payload = env.is_a?(Hash) ? env["error"] : nil
    api_err_payload ||= { "code" => "http_#{code}", "message" => raw.empty? ? "HTTP #{code}" : raw }
    if api_err_payload.is_a?(Hash) && api_err_payload["request_id"].nil?
      api_err_payload["request_id"] = resp_headers && resp_headers["x-request-id"]
    end

    if (code == 429 || code >= 500) && attempt < @max_retries
      sleep_with_backoff(attempt, nil)
      attempt += 1
      next
    end

    raise NakoPay.build_api_error(api_err_payload, status_code: code)
  end
end