diff --git a/.gitignore b/.gitignore index 4bcbc48..6ae28b6 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,7 @@ # rspec failure tracking .rspec_status .idea + +.claude/ +.cursor/ +CLAUDE.md diff --git a/lib/checkout_sdk/api_client.rb b/lib/checkout_sdk/api_client.rb index ca44567..3c51dc3 100644 --- a/lib/checkout_sdk/api_client.rb +++ b/lib/checkout_sdk/api_client.rb @@ -92,17 +92,14 @@ def build_multipart_request(file_request, file) def upload(path, authorization, file_request) headers = default_headers(authorization) - file = File.open(file_request.file) - - form = build_multipart_request(file_request, file) - - begin - @log.info "post: /#{path}" - response = @multipart_client.run_request(:post, path, form, headers) - rescue Faraday::ClientError => e - raise CheckoutApiException, e.response - ensure - file.close + response = File.open(file_request.file) do |file| + form = build_multipart_request(file_request, file) + begin + @log.info "post: /#{path}" + @multipart_client.run_request(:post, path, form, headers) + rescue Faraday::ClientError => e + raise CheckoutApiException, e.response + end end parse_response(response) diff --git a/lib/checkout_sdk/checkout_api.rb b/lib/checkout_sdk/checkout_api.rb index ad2fef7..eae5634 100644 --- a/lib/checkout_sdk/checkout_api.rb +++ b/lib/checkout_sdk/checkout_api.rb @@ -101,7 +101,7 @@ def initialize(configuration) @payment_sessions = CheckoutSdk::Payments::PaymentSessionsClient.new api_client, configuration @payments_setups = CheckoutSdk::Payments::PaymentSetupsClient.new api_client, configuration @flow = CheckoutSdk::Payments::FlowClient.new api_client, configuration - @forward = CheckoutSdk::Forward::ForwardClient.new(api_client, configuration) + @forward = CheckoutSdk::Forward::ForwardClient.new(forward_client(configuration), configuration) end private @@ -134,5 +134,11 @@ def balances_client(configuration) def transfers_client(configuration) ApiClient.new(configuration, configuration.environment.transfers_uri) end + + # @param [CheckoutConfiguration] configuration + # @return [ApiClient] + def forward_client(configuration) + ApiClient.new(configuration, configuration.environment.forward_uri) + end end end diff --git a/lib/checkout_sdk/environment.rb b/lib/checkout_sdk/environment.rb index ec18d36..d4b58c3 100644 --- a/lib/checkout_sdk/environment.rb +++ b/lib/checkout_sdk/environment.rb @@ -11,6 +11,8 @@ module CheckoutSdk # @return [String] # @!attribute balances_uri # @return [String] + # @!attribute forward_uri + # @return [String] # @!attribute is_sandbox # @return [String] class Environment @@ -19,6 +21,7 @@ class Environment :files_uri, :transfers_uri, :balances_uri, + :forward_uri, :is_sandbox # @param [String] base_uri @@ -26,13 +29,15 @@ class Environment # @param [String] files_uri # @param [String] transfers_uri # @param [String] balances_uri + # @param [String] forward_uri # @param [TrueClass, FalseClass] is_sandbox - def initialize(base_uri, authorization_uri, files_uri, transfers_uri, balances_uri, is_sandbox) + def initialize(base_uri, authorization_uri, files_uri, transfers_uri, balances_uri, forward_uri, is_sandbox) @base_uri = base_uri @authorization_uri = authorization_uri @files_uri = files_uri @transfers_uri = transfers_uri @balances_uri = balances_uri + @forward_uri = forward_uri @is_sandbox = is_sandbox end @@ -43,6 +48,7 @@ def self.sandbox 'https://files.sandbox.checkout.com/', 'https://transfers.sandbox.checkout.com/', 'https://balances.sandbox.checkout.com/', + 'https://forward.sandbox.checkout.com/', true) end @@ -53,6 +59,7 @@ def self.production 'https://files.checkout.com/', 'https://transfers.checkout.com/', 'https://balances.checkout.com/', + 'https://forward.checkout.com/', false) end end diff --git a/lib/checkout_sdk/environment_subdomain.rb b/lib/checkout_sdk/environment_subdomain.rb index c0fd190..f5dab5f 100644 --- a/lib/checkout_sdk/environment_subdomain.rb +++ b/lib/checkout_sdk/environment_subdomain.rb @@ -33,7 +33,7 @@ def initialize(environment, subdomain) def create_url_with_subdomain(original_url, subdomain) new_environment = original_url - if subdomain =~ /^[0-9a-z]+$/ + if subdomain =~ /^(?:pl-)?[a-z0-9]+$/ url_parts = URI.parse(original_url) new_host = "#{subdomain}.#{url_parts.host}" diff --git a/lib/checkout_sdk/oauth_scopes.rb b/lib/checkout_sdk/oauth_scopes.rb index c7ff65c..01d4798 100644 --- a/lib/checkout_sdk/oauth_scopes.rb +++ b/lib/checkout_sdk/oauth_scopes.rb @@ -48,5 +48,7 @@ module OAuthScopes ISSUING_CONTROLS_READ = 'issuing:controls-read' ISSUING_CONTROLS_WRITE = 'issuing:controls-write' FORWARD = 'forward' + FORWARD_SECRETS = 'forward:secrets' + IDENTITY_VERIFICATION = 'identity-verification' end end diff --git a/spec/checkout_sdk/configuration/configuration_spec.rb b/spec/checkout_sdk/configuration/configuration_spec.rb index 38721e1..314375c 100644 --- a/spec/checkout_sdk/configuration/configuration_spec.rb +++ b/spec/checkout_sdk/configuration/configuration_spec.rb @@ -26,16 +26,31 @@ class FakeLogger expect(configuration.credentials).to eq(@credentials) expect(configuration.environment.base_uri).to eq(CheckoutSdk::Environment.sandbox.base_uri) expect(configuration.environment.base_uri).to eq("https://api.sandbox.checkout.com/") + expect(configuration.environment.forward_uri).to eq("https://forward.sandbox.checkout.com/") expect(configuration.http_client).to eq(@http_client) expect(configuration.environment_subdomain).to be_nil end + it 'should have correct forward URL for production' do + configuration = CheckoutSdk::CheckoutConfiguration.new( + @credentials, + CheckoutSdk::Environment.production, + @http_client, + @multipart_http_client, + @logger + ) + + expect(configuration.environment.forward_uri).to eq("https://forward.checkout.com/") + end + [ %w[a https://a.api.sandbox.checkout.com/], %w[ab https://ab.api.sandbox.checkout.com/], %w[abc https://abc.api.sandbox.checkout.com/], %w[abc1 https://abc1.api.sandbox.checkout.com/], - %w[12345domain https://12345domain.api.sandbox.checkout.com/] + %w[12345domain https://12345domain.api.sandbox.checkout.com/], + %w[pl-vkuhvk4v https://pl-vkuhvk4v.api.sandbox.checkout.com/], + %w[pl-abc123 https://pl-abc123.api.sandbox.checkout.com/] ].each do |subdomain, expected_url| it "should create configuration with subdomain #{subdomain}" do environment_subdomain = CheckoutSdk::EnvironmentSubdomain.new(CheckoutSdk::Environment.sandbox, subdomain) @@ -63,7 +78,14 @@ class FakeLogger [' ', 'https://api.sandbox.checkout.com/'], [' - ', 'https://api.sandbox.checkout.com/'], ['a b', 'https://api.sandbox.checkout.com/'], - ['ab bc1', 'https://api.sandbox.checkout.com/'] + ['ab bc1', 'https://api.sandbox.checkout.com/'], + ['foo-', 'https://api.sandbox.checkout.com/'], + ['-foo', 'https://api.sandbox.checkout.com/'], + ['FOO', 'https://api.sandbox.checkout.com/'], + ['Foo-Bar', 'https://api.sandbox.checkout.com/'], + ['test-123', 'https://api.sandbox.checkout.com/'], + ['foo-bar', 'https://api.sandbox.checkout.com/'], + ['pl-', 'https://api.sandbox.checkout.com/'] ].each do |subdomain, expected_url| it "should create configuration with bad subdomain #{subdomain}" do environment_subdomain = CheckoutSdk::EnvironmentSubdomain.new(CheckoutSdk::Environment.sandbox, subdomain)