From 8ea596a8828dd47d5fc6d65120533ba0e383b39d Mon Sep 17 00:00:00 2001 From: jillingk <93914435+jillingk@users.noreply.github.com> Date: Mon, 20 Feb 2023 14:55:12 +0100 Subject: [PATCH 1/2] added new/missing endpoints --- lib/adyen/client.rb | 20 +++++-- lib/adyen/services/checkout.rb | 60 ++++++++++++++----- lib/adyen/services/service.rb | 5 ++ spec/checkout_spec.rb | 50 ++++++++++++++++ spec/client_spec.rb | 2 +- .../Checkout/stored_payment_methods.json | 1 + 6 files changed, 118 insertions(+), 20 deletions(-) create mode 100644 spec/mocks/responses/Checkout/stored_payment_methods.json diff --git a/lib/adyen/client.rb b/lib/adyen/client.rb index 1365242b..78676a24 100644 --- a/lib/adyen/client.rb +++ b/lib/adyen/client.rb @@ -144,6 +144,13 @@ def call_adyen_api(service, action, request_data, headers, version, with_applica raise connection_error, "Connection to #{url} failed" end end + if action.fetch(:method) == "delete" + begin + response = conn.delete + rescue Faraday::ConnectionFailed => connection_error + raise connection_error, "Connection to #{url} failed" + end + end if action.fetch(:method) == "patch" begin response = conn.patch do |req| @@ -169,11 +176,16 @@ def call_adyen_api(service, action, request_data, headers, version, with_applica when 401 raise Adyen::AuthenticationError.new("Invalid API authentication; https://docs.adyen.com/user-management/how-to-get-the-api-key", request_data) when 403 - raise Adyen::PermissionError.new("Missing user permissions; https://docs.adyen.com/user-management/user-roles", request_data, response.response_body) + raise Adyen::PermissionError.new("Missing user permissions; https://docs.adyen.com/user-management/user-roles", request_data, response.body) end - - formatted_response = AdyenResult.new(response.body, response.headers, response.status) - + + # delete has no response.body (unless it throws an error) + if response.body == nil + formatted_response = AdyenResult.new("{}", response.headers, response.status) + else + formatted_response = AdyenResult.new(response.body, response.headers, response.status) + end + formatted_response end diff --git a/lib/adyen/services/checkout.rb b/lib/adyen/services/checkout.rb index 0f6f4e65..689aed6c 100644 --- a/lib/adyen/services/checkout.rb +++ b/lib/adyen/services/checkout.rb @@ -2,7 +2,7 @@ module Adyen class Checkout < Service - DEFAULT_VERSION = 68 + DEFAULT_VERSION = 70 def initialize(client, version = DEFAULT_VERSION) service = "Checkout" @@ -12,9 +12,7 @@ def initialize(client, version = DEFAULT_VERSION) :sessions ] - with_application_info = [ - :payment_session, - ] + with_application_info = [] super(client, version, service, method_names, with_application_info) end @@ -31,7 +29,7 @@ def payments(*args) else action = "payments" args[1] ||= {} # optional headers arg - @client.call_adyen_api(@service, action, args[0], args[1], @version, true) + @client.call_adyen_api(@service, action, args[0], args[1], @version) end end @@ -42,7 +40,7 @@ def payment_links(*args) else action = "paymentLinks" args[1] ||= {} # optional headers arg - @client.call_adyen_api(@service, action, args[0], args[1], @version, true) + @client.call_adyen_api(@service, action, args[0], args[1], @version) end end @@ -75,6 +73,10 @@ def apple_pay def modifications @modifications ||= Adyen::Modifications.new(@client, @version) end + + def stored_payment_methods + @stored_payment_methods ||= Adyen::StoredPaymentMethods.new(@client, @version) + end end class CheckoutDetail < Service @@ -93,6 +95,16 @@ def result(request, headers = {}) action = "payments/result" @client.call_adyen_api(@service, action, request, headers, @version) end + + def donations(request, headers = {}) + action = "donations" + @client.call_adyen_api(@service, action, request, headers, @version) + end + + def card_details(request, headers = {}) + action = "cardDetails" + @client.call_adyen_api(@service, action, request, headers, @version) + end end class CheckoutLink < Service @@ -104,12 +116,12 @@ def initialize(client, version = DEFAULT_VERSION) def get(linkId, headers = {}) action = { method: 'get', url: "paymentLinks/" + linkId } - @client.call_adyen_api(@service, action, {}, headers, @version, true) + @client.call_adyen_api(@service, action, {}, headers, @version) end def update(linkId, request, headers = {}) action = { method: 'patch', url: "paymentLinks/" + linkId } - @client.call_adyen_api(@service, action, request, headers, @version, false) + @client.call_adyen_api(@service, action, request, headers, @version) end end @@ -122,7 +134,7 @@ def initialize(client, version = DEFAULT_VERSION) def balance(request, headers = {}) action = "paymentMethods/balance" - @client.call_adyen_api(@service, action, request, headers, @version, true) + @client.call_adyen_api(@service, action, request, headers, @version, false) end end @@ -161,12 +173,12 @@ def initialize(client, version = DEFAULT_VERSION) def capture(linkId, request, headers = {}) action = "payments/" + linkId + "/captures" - @client.call_adyen_api(@service, action, request, headers, @version, false) + @client.call_adyen_api(@service, action, request, headers, @version) end def cancel(linkId, request, headers = {}) action = "payments/" + linkId + "/cancels" - @client.call_adyen_api(@service, action, request, headers, @version, false) + @client.call_adyen_api(@service, action, request, headers, @version) end def genericCancel(request, headers = {}) @@ -176,17 +188,35 @@ def genericCancel(request, headers = {}) def refund(linkId, request, headers = {}) action = "payments/" + linkId + "/refunds" - @client.call_adyen_api(@service, action, request, headers, @version, false) + @client.call_adyen_api(@service, action, request, headers, @version) end def reversal(linkId, request, headers = {}) action = "payments/" + linkId + "/reversals" - @client.call_adyen_api(@service, action, request, headers, @version, false) + @client.call_adyen_api(@service, action, request, headers, @version) end def amountUpdate(linkId, request, headers = {}) action = "payments/" + linkId + "/amountUpdates" - @client.call_adyen_api(@service, action, request, headers, @version, false) + @client.call_adyen_api(@service, action, request, headers, @version) + end + end + + class StoredPaymentMethods < Service + def initialize(client, version = DEFAULT_VERSION) + @service = "Checkout" + @client = client + @version = version + end + + def get(query_array={}, headers = {}) + action = { method: 'get', url: "storedPaymentMethods" + create_query_string(query_array)} + @client.call_adyen_api(@service, action, {}, headers, @version) + end + + def delete(recurringId, query_array={}, headers = {}) + action = { method: 'delete', url: "storedPaymentMethods/%s" % recurringId + create_query_string(query_array)} + @client.call_adyen_api(@service, action, {}, headers, @version) end end -end +end \ No newline at end of file diff --git a/lib/adyen/services/service.rb b/lib/adyen/services/service.rb index 746d754b..be1981c2 100644 --- a/lib/adyen/services/service.rb +++ b/lib/adyen/services/service.rb @@ -24,5 +24,10 @@ def initialize(client, version, service, method_names, with_application_info = [ end end end + + # create query parameter from an array + def create_query_string(arr) + "?" + URI.encode_www_form(arr) + end end end diff --git a/spec/checkout_spec.rb b/spec/checkout_spec.rb index 412fd7b9..36e592c2 100644 --- a/spec/checkout_spec.rb +++ b/spec/checkout_spec.rb @@ -597,6 +597,56 @@ to eq("12345") end + it "makes a get storedPaymentMethods call" do + response_body = json_from_file("mocks/responses/Checkout/stored_payment_methods.json") + + url = @shared_values[:client].service_url(@shared_values[:service], "storedPaymentMethods?merchantAccount=TestMerchantAccount&shopperReference=test-1234", @shared_values[:client].checkout.version) + WebMock.stub_request(:get, url). + with( + headers: { + "x-api-key" => @shared_values[:client].api_key + } + ). + to_return( + body: response_body + ) + + result = @shared_values[:client].checkout.stored_payment_methods.get({"merchantAccount" => "TestMerchantAccount", "shopperReference" => "test-1234"}) + response_hash = result.response + + expect(result.status). + to eq(200) + expect(response_hash). + to eq(JSON.parse(response_body)) + expect(response_hash). + to be_a Adyen::HashWithAccessors + expect(response_hash). + to be_a_kind_of Hash + expect(response_hash["shopperReference"]). + to eq("test-1234") + end + + it "makes a delete storedPaymentMethods call" do + response_body = json_from_file("mocks/responses/Checkout/stored_payment_methods.json") + + url = @shared_values[:client].service_url(@shared_values[:service], "storedPaymentMethods/RL8FW7WZM6KXWD82?merchantAccount=TestMerchantAccount&shopperReference=test-1234", @shared_values[:client].checkout.version) + WebMock.stub_request(:delete, url). + with( + headers: { + "x-api-key" => @shared_values[:client].api_key + } + ). + to_return( + body: response_body + ) + + result = @shared_values[:client].checkout.stored_payment_methods.delete("RL8FW7WZM6KXWD82", {"merchantAccount" => "TestMerchantAccount", "shopperReference" => "test-1234"}) + response_hash = result.response + + expect(result.status). + to eq(200) + end + # create client for automated tests client = create_client(:api_key) diff --git a/spec/client_spec.rb b/spec/client_spec.rb index e2c72349..591bbb77 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -106,7 +106,7 @@ mock_response = Faraday::Response.new(status: 200) expect(Adyen::AdyenResult).to receive(:new) - expect(Faraday).to receive(:new).with("http://localhost:3001/v68/payments/details", connection_options).and_return(mock_faraday_connection) + expect(Faraday).to receive(:new).with("http://localhost:3001/v70/payments/details", connection_options).and_return(mock_faraday_connection) expect(mock_faraday_connection).to receive(:post).and_return(mock_response) client.checkout.payments.details(request_body) end diff --git a/spec/mocks/responses/Checkout/stored_payment_methods.json b/spec/mocks/responses/Checkout/stored_payment_methods.json new file mode 100644 index 00000000..a6df9a3f --- /dev/null +++ b/spec/mocks/responses/Checkout/stored_payment_methods.json @@ -0,0 +1 @@ +{"merchantAccount":"TestMerchantAccount", "shopperReference":"test-1234"} \ No newline at end of file From 493f7deca3d38523f0ecdcd7ab00f07261e1fcd2 Mon Sep 17 00:00:00 2001 From: jillingk <93914435+jillingk@users.noreply.github.com> Date: Tue, 21 Feb 2023 13:14:10 +0100 Subject: [PATCH 2/2] leave application info --- lib/adyen/services/checkout.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/adyen/services/checkout.rb b/lib/adyen/services/checkout.rb index 689aed6c..3fa21456 100644 --- a/lib/adyen/services/checkout.rb +++ b/lib/adyen/services/checkout.rb @@ -12,7 +12,9 @@ def initialize(client, version = DEFAULT_VERSION) :sessions ] - with_application_info = [] + with_application_info = [ + :payment_session + ] super(client, version, service, method_names, with_application_info) end @@ -29,7 +31,7 @@ def payments(*args) else action = "payments" args[1] ||= {} # optional headers arg - @client.call_adyen_api(@service, action, args[0], args[1], @version) + @client.call_adyen_api(@service, action, args[0], args[1], @version, true) end end @@ -134,7 +136,7 @@ def initialize(client, version = DEFAULT_VERSION) def balance(request, headers = {}) action = "paymentMethods/balance" - @client.call_adyen_api(@service, action, request, headers, @version, false) + @client.call_adyen_api(@service, action, request, headers, @version, true) end end