Class: PaymentKit::Client

Inherits:
Object
  • Object
show all
Includes:
Resources::Catalog, Resources::Customers, Resources::Invoices, Resources::Payments, Resources::Subscriptions
Defined in:
lib/payment_kit/client.rb

Overview

HTTP client for the PaymentKit API.

Authenticates with a Bearer secret key, scopes requests to an account base URL, encodes JSON bodies, auto-paginates list endpoints, maps RFC 7807 errors, and retries transient failures with exponential backoff.

Endpoint methods live in the PaymentKit::Resources::* modules.

Constant Summary collapse

Error =

Backwards-compatible aliases: applications written against a nested error namespace (+PaymentKit::Client::AuthenticationError+) keep working.

PaymentKit::Error
AuthenticationError =
PaymentKit::AuthenticationError
PermissionError =
PaymentKit::PermissionError
SignatureVerificationError =
PaymentKit::SignatureVerificationError
InvalidRequestError =
PaymentKit::InvalidRequestError
ConflictError =
PaymentKit::ConflictError
CardError =
PaymentKit::CardError
RateLimitError =
PaymentKit::RateLimitError
APIError =
PaymentKit::APIError
ApiError =
PaymentKit::APIError
APIConnectionError =
PaymentKit::APIConnectionError
ConnectionError =
PaymentKit::APIConnectionError
MAX_REDIRECTS =

Redirects followed before giving up.

3
RETRYABLE_STATUSES =

Statuses that are always safe to replay. 409 is deliberately excluded: PaymentKit marks only some conflicts retryable via error_code.

[408, 429, 500, 502, 503, 504].freeze
RETRYABLE_ERROR_CODES =

409 error_code values documented as retry-safe with no side effects.

%w[invoice_locked].freeze
REDIRECT_STATUSES =

Redirects PaymentKit uses for path canonicalization; both preserve the verb.

[307, 308].freeze
IDEMPOTENT_METHODS =

Methods that receive an auto-generated Idempotency-Key when the caller does not supply one, so internal retries cannot double-charge.

%i[post put patch].freeze
MAX_RETRY_DELAY =

Ceiling for a server-supplied Retry-After, so a hostile or mistaken header cannot park a request for hours.

32
RAW_BODY_LIMIT =

Characters of raw response body appended to a 4xx message for context.

800

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Resources::Catalog

#create_price, #create_product, #list_prices, #list_product_prices, #list_products, #retrieve_price, #retrieve_product, #update_product

Methods included from Resources::Payments

#create_checkout_session, #create_payment_intent, #create_payment_method, #deactivate_payment_method, #detach_payment_method, #list_attempts_by_intent, #list_payment_intents, #list_refunds_by_intent, #retrieve_checkout_session, #retrieve_payment_intent, #retrieve_payment_method, #update_payment_method

Methods included from Resources::Invoices

#bill_pending_items, #create_invoice, #create_invoice_item, #finalize_invoice, #list_invoice_items, #list_invoices, #mark_invoice_uncollectible, #pay_invoice, #retrieve_invoice, #retrieve_invoice_item, #retrieve_invoice_pdf, #update_invoice_item, #void_invoice

Methods included from Resources::Subscriptions

#active_change_request, #add_change_request_changes, #apply_change_request, #apply_subscription_changes, #cancel_change_request, #cancel_pending_change, #cancel_scheduled_cancellation, #cancel_scheduled_pause, #cancel_subscription, #change_plan, #create_change_request, #create_subscription, #list_subscriptions, #pause_subscription, #preview_change_request, #renew_subscription, #reschedule_billing, #resume_subscription, #retrieve_change_request, #retrieve_subscription, #schedule_cancellation, #update_subscription, #update_subscription_items

Methods included from Resources::Customers

#create_balance_transaction, #create_credit_note, #create_customer, #list_credit_notes, #list_customers, #retrieve_customer, #set_credit_balance, #update_customer

Constructor Details

#initialize(secret_key: nil, account_id: nil, base_url: nil, api_host: nil, open_timeout: nil, read_timeout: nil, max_retries: nil, signing_secret: nil, configuration: nil) ⇒ Client

Builds a client. Every keyword falls back to PaymentKit.configuration (or to configuration: when given), so a bare Client.new uses the global settings.

Raises AuthenticationError when secret_key is missing or contains whitespace, and InvalidRequestError when neither base_url nor account_id is configured.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/payment_kit/client.rb', line 69

def initialize(secret_key: nil, account_id: nil, base_url: nil, api_host: nil,
               open_timeout: nil, read_timeout: nil, max_retries: nil,
               signing_secret: nil, configuration: nil)
  base = configuration || PaymentKit.configuration
  @config = base.merge(
    secret_key: secret_key,
    account_id: ,
    base_url: base_url,
    api_host: api_host,
    open_timeout: open_timeout,
    read_timeout: read_timeout,
    max_retries: max_retries,
    signing_secret: signing_secret
  )

  raise AuthenticationError, "PaymentKit secret_key is not configured" if blank?(@config.secret_key)
  if @config.secret_key.to_s.match?(/\s/)
    raise AuthenticationError, "PaymentKit secret_key cannot contain whitespace"
  end

  @base_url = @config.resolved_base_url
end

Instance Attribute Details

#base_urlObject (readonly)

Resolved base URL every account-scoped request is sent to.



93
94
95
# File 'lib/payment_kit/client.rb', line 93

def base_url
  @base_url
end

Instance Method Details

#raw_request(method, path, params: nil, idempotency_key: nil, account_scoped: true) ⇒ Object

--- Escape hatch ------------------------------------------------------- Calls any PaymentKit endpoint, including ones this SDK does not wrap yet (payment links, refunds, webhook endpoint management, …). Goes through the same auth, retry, idempotency and error mapping as the typed methods.

client.raw_request(:get, "/payment-links", params: { limit: 10 })
client.raw_request(:post, "/webhook-endpoints/we_1/roll-secret",
                 params: { ttl_seconds: 3600 })

Endpoints that are not account-scoped (for example the customer portal surface at /billing-portal/token/...) opt out of the account prefix:

client.raw_request(:get, "/billing-portal/token/#{token}/payment-methods",
                 account_scoped: false)


117
118
119
120
121
122
123
124
125
# File 'lib/payment_kit/client.rb', line 117

def raw_request(method, path, params: nil, idempotency_key: nil, account_scoped: true)
  query = method == :get ? params : nil
  body = method == :get ? nil : params
  request(
    method, path,
    query: query, body: body,
    idempotency_key: idempotency_key, account_scoped: 
  )
end

#verify_webhook(payload, signature, secret: nil) ⇒ Object

--- Webhooks ----------------------------------------------------------- Verifies HMAC-SHA256 over the raw payload (X-Webhook-Signature: sha256=<hex>). Delegates to PaymentKit::Webhook.construct_event (supports one or many secrets).



98
99
100
101
# File 'lib/payment_kit/client.rb', line 98

def verify_webhook(payload, signature, secret: nil)
  secrets = secret.nil? ? @config.signing_secrets : secret
  Webhook.construct_event(payload, signature, secrets)
end