Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@
# rspec failure tracking
.rspec_status
.idea
.claude/rules/*
.cursor/rules/*
.cursor/skills/*
16 changes: 15 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,21 @@ Metrics/ModuleLength:

Metrics/MethodLength:
Max: 25
Exclude:
# Aggregator that wires up every product client; grows with each new product.
- "**/checkout_api.rb"

Metrics/ParameterLists:
Max: 10

Metrics/ClassLength:
Max: 120
# Raised from 120: SDK classes (e.g. ApiClient, response DTOs) grow as new
# API conventions and fields are adopted upstream.
Max: 150
Exclude:
# Endpoint-collection clients: one method per REST endpoint, grow with the API.
- "**/issuing_client.rb"
- "**/accounts_client.rb"

Metrics/CyclomaticComplexity:
Max: 10
Expand All @@ -37,6 +46,11 @@ Style/Documentation:
Style/OpenStructUse:
Enabled: false

Naming/AccessorMethodName:
# The SDK consistently prefixes read endpoints with get_ to mirror the REST API
# (e.g. get_cardholder, get_card_details). Zero-arg variants would otherwise flag.
Enabled: false

Naming/MethodName:
Exclude:
- "**/google_pay_token_data*"
Expand Down
7 changes: 7 additions & 0 deletions lib/checkout_sdk.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@
require 'checkout_sdk/financial/financial'
require 'checkout_sdk/issuing/issuing'
require 'checkout_sdk/forward/forward'
require 'checkout_sdk/onboarding_simulator/onboarding_simulator'
require 'checkout_sdk/agentic_commerce/agentic_commerce'
require 'checkout_sdk/compliance_requests/compliance_requests'
require 'checkout_sdk/standalone_account_updater/standalone_account_updater'
require 'checkout_sdk/network_tokens/network_tokens'
require 'checkout_sdk/payment_methods/payment_methods'
require 'checkout_sdk/identities/identities'

# Checkout modules (previous)
require 'checkout_sdk/sources/sources'
Expand Down
11 changes: 10 additions & 1 deletion lib/checkout_sdk/accounts/accounts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
require 'checkout_sdk/accounts/instrument_details_card_token'
require 'checkout_sdk/accounts/payment_instrument_request'
require 'checkout_sdk/accounts/payment_instruments_query'
require 'checkout_sdk/accounts/headers'
require 'checkout_sdk/accounts/update_payment_instrument_request'
require 'checkout_sdk/accounts/additional_document'
require 'checkout_sdk/accounts/additional_info'
Expand All @@ -59,3 +58,13 @@
require 'checkout_sdk/accounts/shareholder_structure_type'
require 'checkout_sdk/accounts/tax_verification'
require 'checkout_sdk/accounts/tax_verification_type'
require 'checkout_sdk/accounts/submitter'
require 'checkout_sdk/accounts/entity_requirement_reason'
require 'checkout_sdk/accounts/entity_requirement_priority'
require 'checkout_sdk/accounts/entity_requirement_update_status'
require 'checkout_sdk/accounts/entity_requirement_update_request'
require 'checkout_sdk/accounts/reserve_rule_holding_duration'
require 'checkout_sdk/accounts/rolling_reserve_rule'
require 'checkout_sdk/accounts/reserve_rule_update_request'
require 'checkout_sdk/accounts/reserve_rule_create_request'
require 'checkout_sdk/accounts/entity_files_request'
135 changes: 134 additions & 1 deletion lib/checkout_sdk/accounts/accounts_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ class AccountsClient < Client
PAYOUT_SCHEDULE = 'payout-schedules'
FILES = 'files'
PAYMENT_INSTRUMENTS = 'payment-instruments'
private_constant :ACCOUNTS, :ENTITIES, :INSTRUMENT, :PAYOUT_SCHEDULE, :FILES, :PAYMENT_INSTRUMENTS
REQUIREMENTS = 'requirements'
RESERVE_RULES = 'reserve-rules'
MEMBERS = 'members'
private_constant :ACCOUNTS, :ENTITIES, :INSTRUMENT, :PAYOUT_SCHEDULE, :FILES, :PAYMENT_INSTRUMENTS,
:REQUIREMENTS, :RESERVE_RULES, :MEMBERS

# @param [ApiClient] api_client
# @param [ApiClient] files_client
Expand Down Expand Up @@ -93,6 +97,135 @@ def retrieve_payout_schedule(entity_id)
def upload_file(file_request)
files_client.submit_file(FILES, sdk_authorization, file_request)
end

# Retrieve the list of pending requirements that a sub-entity must resolve.
# @param [String] entity_id
def get_entity_requirements(entity_id)
api_client.invoke_get(
build_path(ACCOUNTS, ENTITIES, entity_id, REQUIREMENTS),
sdk_authorization
)
end

# Retrieve detailed information for a single requirement.
# @param [String] entity_id
# @param [String] requirement_id
def get_entity_requirement_details(entity_id, requirement_id)
api_client.invoke_get(
build_path(ACCOUNTS, ENTITIES, entity_id, REQUIREMENTS, requirement_id),
sdk_authorization
)
end

# Submit a response to resolve a requirement.
# @param [String] entity_id
# @param [String] requirement_id
# @param [Hash, EntityRequirementUpdateRequest] update_request
def resolve_entity_requirement(entity_id, requirement_id, update_request)
api_client.invoke_put(
build_path(ACCOUNTS, ENTITIES, entity_id, REQUIREMENTS, requirement_id),
sdk_authorization,
update_request
)
end

# Add a reserve rule for a sub-entity.
# @param [String] entity_id
# @param [Hash, ReserveRuleCreateRequest] reserve_rule_request
def add_reserve_rule(entity_id, reserve_rule_request)
api_client.invoke_post(
build_path(ACCOUNTS, ENTITIES, entity_id, RESERVE_RULES),
sdk_authorization,
reserve_rule_request
)
end

# Query reserve rules for a sub-entity.
# @param [String] entity_id
def query_reserve_rules(entity_id)
api_client.invoke_get(
build_path(ACCOUNTS, ENTITIES, entity_id, RESERVE_RULES),
sdk_authorization
)
end

# Retrieve a reserve rule by id.
# @param [String] entity_id
# @param [String] reserve_rule_id
def get_reserve_rule(entity_id, reserve_rule_id)
api_client.invoke_get(
build_path(ACCOUNTS, ENTITIES, entity_id, RESERVE_RULES, reserve_rule_id),
sdk_authorization
)
end

# Update a reserve rule.
# The API enforces optimistic concurrency: the ETag returned by GET must be
# echoed back via {CheckoutSdk::Common::Headers#if_match}, otherwise the
# API responds 428 Precondition Required.
# @param [String] entity_id
# @param [String] reserve_rule_id
# @param [String] etag ETag value to forward as the `If-Match` HTTP header.
# @param [Hash, ReserveRuleUpdateRequest] reserve_rule_request
def update_reserve_rule(entity_id, reserve_rule_id, etag, reserve_rule_request)
headers = nil
if !etag.nil? && !etag.empty?
headers = CheckoutSdk::Common::Headers.new
headers.if_match = etag
end

api_client.invoke_put(
build_path(ACCOUNTS, ENTITIES, entity_id, RESERVE_RULES, reserve_rule_id),
sdk_authorization,
reserve_rule_request,
headers
)
end

# List sub-entity members.
# @param [String] entity_id
def get_sub_entity_members(entity_id)
api_client.invoke_get(
build_path(ACCOUNTS, ENTITIES, entity_id, MEMBERS),
sdk_authorization
)
end

# Reinvite a sub-entity member.
# The API marks the request body as required; callers must provide a Hash
# (or `PlatformsHostedOnboardReinviteRequest`-shaped object), even if it
# is empty `{}` per the current swagger contract.
# @param [String] entity_id
# @param [String] user_id
# @param [Hash] reinvite_request Required body per swagger; pass `{}` if no fields are needed.
def reinvite_sub_entity_member(entity_id, user_id, reinvite_request)
api_client.invoke_put(
build_path(ACCOUNTS, ENTITIES, entity_id, MEMBERS, user_id),
sdk_authorization,
reinvite_request
)
end

# Upload a file scoped to a sub-entity. Hits POST /entities/{entityId}/files.
# @param [String] entity_id
# @param [Hash, EntityFilesRequest] file_request
def upload_entity_file(entity_id, file_request)
files_client.submit_file(
build_path(ENTITIES, entity_id, FILES),
sdk_authorization,
file_request
)
end

# Retrieve a file scoped to a sub-entity. Hits GET /entities/{entityId}/files/{fileId}.
# @param [String] entity_id
# @param [String] file_id
def get_entity_file(entity_id, file_id)
files_client.invoke_get(
build_path(ENTITIES, entity_id, FILES, file_id),
sdk_authorization
)
end
end
end
end
13 changes: 13 additions & 0 deletions lib/checkout_sdk/accounts/entity_files_request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

module CheckoutSdk
module Accounts
# Request body for POST /entities/{entityId}/files.
#
# @!attribute purpose
# @return [String] Purpose of the file (e.g. "bank_verification").
class EntityFilesRequest
attr_accessor :purpose
end
end
end
12 changes: 12 additions & 0 deletions lib/checkout_sdk/accounts/entity_requirement_priority.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

module CheckoutSdk
module Accounts
# Priority of a sub-entity requirement. "critical" if the deadline is within 7 days,
# otherwise "high" by default.
module EntityRequirementPriority
HIGH = 'high'
CRITICAL = 'critical'
end
end
end
11 changes: 11 additions & 0 deletions lib/checkout_sdk/accounts/entity_requirement_reason.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

module CheckoutSdk
module Accounts
# Reasons why a requirement was raised on a sub-entity.
module EntityRequirementReason
PERIODIC_REVIEW = 'periodic_review'
ATTESTATION = 'attestation'
end
end
end
22 changes: 22 additions & 0 deletions lib/checkout_sdk/accounts/entity_requirement_update_request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module CheckoutSdk
module Accounts
# Request body for PUT /accounts/entities/{id}/requirements/{requirementId}.
#
# The expected shape of `value` is defined by the JSON Schema returned in
# the requirement details response. Common shapes include a file reference
# (e.g. { "file_id": "file_..." }), a primitive value, or a structured object.
#
# @!attribute value
# The response to the requirement. Polymorphic per swagger
# (`oneOf [object, array, string, number, boolean]`), so the only valid
# Ruby annotation is `Object`. The concrete shape is dictated at runtime
# by the requirement's `_schema` returned from
# `GET /accounts/entities/{id}/requirements/{requirementId}`.
# @return [Object]
class EntityRequirementUpdateRequest
attr_accessor :value
end
end
end
12 changes: 12 additions & 0 deletions lib/checkout_sdk/accounts/entity_requirement_update_status.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

module CheckoutSdk
module Accounts
# Status returned after submitting a requirement response.
# While processing, the requirement is no longer retrievable via GET endpoints;
# if validation fails downstream the requirement may reappear.
module EntityRequirementUpdateStatus
PROCESSING = 'processing'
end
end
end
11 changes: 0 additions & 11 deletions lib/checkout_sdk/accounts/headers.rb

This file was deleted.

10 changes: 9 additions & 1 deletion lib/checkout_sdk/accounts/onboard_entity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ module Accounts
# @return [OnboardSubEntityDocuments]
# @!attribute additional_info
# @return [AdditionalInfo]
# @!attribute seller_category
# @return [String] Identifier of a seller category configured on the platform
# during onboarding. Used for US ISV onboarding variants.
# @!attribute submitter
# @return [Submitter] Captures evidence of the end-user's consent to onboarding.
# Used for US ISV onboarding variants.
class OnboardEntity
attr_accessor :reference,
:is_draft,
Expand All @@ -29,7 +35,9 @@ class OnboardEntity
:processing_details,
:individual,
:documents,
:additional_info
:additional_info,
:seller_category,
:submitter
end
end
end
14 changes: 14 additions & 0 deletions lib/checkout_sdk/accounts/reserve_rule_create_request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module CheckoutSdk
module Accounts
# Request body for POST /accounts/entities/{id}/reserve-rules.
# Extends {ReserveRuleUpdateRequest} with `valid_from`.
#
# @!attribute valid_from
# @return [String] ISO-8601 timestamp; must be at least 15 minutes in the future.
class ReserveRuleCreateRequest < ReserveRuleUpdateRequest
attr_accessor :valid_from
end
end
end
13 changes: 13 additions & 0 deletions lib/checkout_sdk/accounts/reserve_rule_holding_duration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

module CheckoutSdk
module Accounts
# The length of time a rolling reserve collateral balance is held for.
#
# @!attribute weeks
# @return [Integer] Min 2, max 104.
class ReserveRuleHoldingDuration
attr_accessor :weeks
end
end
end
15 changes: 15 additions & 0 deletions lib/checkout_sdk/accounts/reserve_rule_update_request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module CheckoutSdk
module Accounts
# Request body for PUT /accounts/entities/{entityId}/reserve-rules/{id}.
#
# @!attribute type
# @return [String] Reserve rule type (e.g. "rolling").
# @!attribute rolling
# @return [RollingReserveRule]
class ReserveRuleUpdateRequest
attr_accessor :type, :rolling
end
end
end
15 changes: 15 additions & 0 deletions lib/checkout_sdk/accounts/rolling_reserve_rule.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module CheckoutSdk
module Accounts
# Rolling reserve rule parameters.
#
# @!attribute percentage
# @return [Float] Min 0, max 100.
# @!attribute holding_duration
# @return [ReserveRuleHoldingDuration]
class RollingReserveRule
attr_accessor :percentage, :holding_duration
end
end
end
Loading
Loading