From 8ad8c23e13709e41f7afe949854edf6c50f9b86b Mon Sep 17 00:00:00 2001 From: Kevin Kaniaburka Date: Wed, 11 Dec 2024 12:06:56 +0100 Subject: [PATCH] Add OrderBasedPaymentMethodsResolver --- .../services/pay_by_link_payment/checker.php | 20 +++ config/services/payment.php | 9 ++ .../PaymentMethodSupportedForOrderChecker.php | 46 ++++++ ...ethodSupportedForOrderCheckerInterface.php | 13 ++ .../OrderBasedPaymentMethodsResolver.php | 48 +++++++ .../fixtures/common/payment_method.yaml | 44 ++++++ .../Checkout/TpayPayByLinkCheckoutTest.php | 9 ++ ...mentMethodSupportedForOrderCheckerTest.php | 124 +++++++++++++++++ .../OrderBasedPaymentMethodsResolverTest.php | 131 ++++++++++++++++++ tests/mockoon_tpay.json | 2 +- 10 files changed, 445 insertions(+), 1 deletion(-) create mode 100644 config/services/pay_by_link_payment/checker.php create mode 100644 src/PayByLinkPayment/Checker/PaymentMethodSupportedForOrderChecker.php create mode 100644 src/PayByLinkPayment/Checker/PaymentMethodSupportedForOrderCheckerInterface.php create mode 100644 src/Payment/Resolver/OrderBasedPaymentMethodsResolver.php create mode 100644 tests/Unit/PayByLinkPayment/Checker/PaymentMethodSupportedForOrderCheckerTest.php create mode 100644 tests/Unit/Payment/Resolver/OrderBasedPaymentMethodsResolverTest.php diff --git a/config/services/pay_by_link_payment/checker.php b/config/services/pay_by_link_payment/checker.php new file mode 100644 index 00000000..eb561ff4 --- /dev/null +++ b/config/services/pay_by_link_payment/checker.php @@ -0,0 +1,20 @@ +services(); + + $services->set('commerce_weavers_sylius_tpay.pay_by_link_payment.checker.payment_method_supported_for_order', PaymentMethodSupportedForOrderChecker::class) + ->args([ + service('payum.dynamic_gateways.cypher'), + service('commerce_weavers_sylius_tpay.tpay.provider.order_aware_validated_tpay_api_bank_list'), + ]) + ->alias(PaymentMethodSupportedForOrderCheckerInterface::class, 'commerce_weavers_sylius_tpay.pay_by_link_payment.checker.payment_method_supported_for_order') + ; +}; diff --git a/config/services/payment.php b/config/services/payment.php index 942336f7..be59413c 100644 --- a/config/services/payment.php +++ b/config/services/payment.php @@ -8,6 +8,7 @@ use CommerceWeavers\SyliusTpayPlugin\Payment\Canceller\PaymentCancellerInterface; use CommerceWeavers\SyliusTpayPlugin\Payment\Checker\PaymentCancellationPossibilityChecker; use CommerceWeavers\SyliusTpayPlugin\Payment\Checker\PaymentCancellationPossibilityCheckerInterface; +use CommerceWeavers\SyliusTpayPlugin\Payment\Resolver\OrderBasedPaymentMethodsResolver; return static function(ContainerConfigurator $container): void { $services = $container->services(); @@ -27,4 +28,12 @@ ]) ->alias(PaymentCancellationPossibilityCheckerInterface::class, 'commerce_weavers_sylius_tpay.payment.checker.payment_cancellation_possibility') ; + + $services->set('commerce_weavers_sylius_tpay.payment.resolver.order_based_payment_methods', OrderBasedPaymentMethodsResolver::class) + ->args([ + service('sylius.payment_methods_resolver.channel_based'), + service('commerce_weavers_sylius_tpay.pay_by_link_payment.checker.payment_method_supported_for_order'), + ]) + ->tag('sylius.payment_method_resolver', ['type' => 'tpay_order_based', 'label' => 'commerce_weavers_sylius_tpay.payment_methods_resolver.order_based', 'priority' => 2]) + ; }; diff --git a/src/PayByLinkPayment/Checker/PaymentMethodSupportedForOrderChecker.php b/src/PayByLinkPayment/Checker/PaymentMethodSupportedForOrderChecker.php new file mode 100644 index 00000000..f4eff174 --- /dev/null +++ b/src/PayByLinkPayment/Checker/PaymentMethodSupportedForOrderChecker.php @@ -0,0 +1,46 @@ +getGatewayConfig(); + + if (null === $gatewayConfig || GatewayName::PAY_BY_LINK !== $gatewayConfig->getFactoryName()) { + return true; + } + + if ($gatewayConfig instanceof CryptedInterface) { + $gatewayConfig->decrypt($this->cypher); + } + + $tpayChannelId = $gatewayConfig->getConfig()['tpay_channel_id'] ?? null; + + if (null === $tpayChannelId) { + return true; + } + + $validTpayChannelList = $this->orderAwareValidTpayChannelListProvider->provide($order); + + return isset($validTpayChannelList[$tpayChannelId]); + } +} diff --git a/src/PayByLinkPayment/Checker/PaymentMethodSupportedForOrderCheckerInterface.php b/src/PayByLinkPayment/Checker/PaymentMethodSupportedForOrderCheckerInterface.php new file mode 100644 index 00000000..151a9bfa --- /dev/null +++ b/src/PayByLinkPayment/Checker/PaymentMethodSupportedForOrderCheckerInterface.php @@ -0,0 +1,13 @@ +supports($subject), 'This payment method is not support by resolver'); + + /** @var PaymentMethodInterface[] $supportedMethods */ + $supportedMethods = $this->paymentMethodsResolver->getSupportedMethods($subject); + + foreach ($supportedMethods as $key => $supportedMethod) { + $order = $subject->getOrder(); + Assert::notNull($order); + + if ($this->paymentMethodSupportedForOrderChecker->isSupportedForOrder($supportedMethod, $order)) { + continue; + } + + unset($supportedMethods[$key]); + } + + return array_values($supportedMethods); + } + + public function supports(PaymentInterface $subject): bool + { + return $this->paymentMethodsResolver->supports($subject); + } +} diff --git a/tests/E2E/Resources/fixtures/common/payment_method.yaml b/tests/E2E/Resources/fixtures/common/payment_method.yaml index a2851b8b..8a9886e0 100644 --- a/tests/E2E/Resources/fixtures/common/payment_method.yaml +++ b/tests/E2E/Resources/fixtures/common/payment_method.yaml @@ -41,6 +41,20 @@ Sylius\Component\Core\Model\PaymentMethod: translations: - '@tpay_pbl_one_channel_payment_method_translation' channels: [ '@channel_web' ] + tpay_pbl_one_channel_with_amount_min_20_constraint: + code: 'tpay_pbl_one_channel_with_amount_min_20_constraint' + enabled: true + gatewayConfig: '@gateway_tpay_pbl_one_channel_with_amount_min_20_constraint' + translations: + - '@tpay_pbl_one_channel_with_amount_min_20_constraint_payment_method_translation' + channels: [ '@channel_web' ] + tpay_pbl_one_channel_with_amount_min_30_constraint: + code: 'tpay_pbl_one_channel_with_amount_min_30_constraint' + enabled: true + gatewayConfig: '@gateway_tpay_pbl_one_channel_with_amount_min_30_constraint' + translations: + - '@tpay_pbl_one_channel_with_amount_min_30_constraint_payment_method_translation' + channels: [ '@channel_web' ] tpay_visa_mobile: code: 'tpay_visa_mobile' enabled: true @@ -101,6 +115,26 @@ Sylius\Bundle\PayumBundle\Model\GatewayConfig: type: 'pay_by_link' production_mode: false encrypted: true + gateway_tpay_pbl_one_channel_with_amount_min_20_constraint: + gatewayName: 'tpay_pbl' + factoryName: 'tpay_pbl' + config: + client_id: 'encrypted_' + client_secret: 'encrypted_' + tpay_channel_id: '4' + type: 'pay_by_link' + production_mode: false + encrypted: true + gateway_tpay_pbl_one_channel_with_amount_min_30_constraint: + gatewayName: 'tpay_pbl' + factoryName: 'tpay_pbl' + config: + client_id: 'encrypted_' + client_secret: 'encrypted_' + tpay_channel_id: '5' + type: 'pay_by_link' + production_mode: false + encrypted: true gateway_tpay_visa_mobile: gatewayName: 'tpay_visa_mobile' factoryName: 'tpay_visa_mobile' @@ -141,6 +175,16 @@ Sylius\Component\Payment\Model\PaymentMethodTranslation: locale: 'en_US' description: '' translatable: '@tpay_pbl_one_channel' + tpay_pbl_one_channel_with_amount_min_20_constraint_payment_method_translation: + name: 'One Bank With Amount Min 20 Constraint (Tpay)' + locale: 'en_US' + description: '' + translatable: '@tpay_pbl_one_channel_with_amount_min_20_constraint' + tpay_pbl_one_channel_with_amount_min_30_constraint_payment_method_translation: + name: 'One Bank With Amount Min 30 Constraint (Tpay)' + locale: 'en_US' + description: '' + translatable: '@tpay_pbl_one_channel_with_amount_min_20_constraint' tpay_visa_mobile_payment_method_translation: name: 'Visa mobile (Tpay)' locale: 'en_US' diff --git a/tests/E2E/Shop/Checkout/TpayPayByLinkCheckoutTest.php b/tests/E2E/Shop/Checkout/TpayPayByLinkCheckoutTest.php index 27cd7773..625d2a60 100644 --- a/tests/E2E/Shop/Checkout/TpayPayByLinkCheckoutTest.php +++ b/tests/E2E/Shop/Checkout/TpayPayByLinkCheckoutTest.php @@ -45,4 +45,13 @@ public function test_it_completes_the_checkout_using_pay_by_link_channel_presele $this->assertPageTitleContains('Thank you!'); } + + public function test_it_cannot_complete_the_checkout_using_not_supported_pay_by_link(): void + { + $element = $this->client->findElement(WebDriverBy::xpath('//*[@id="sylius-payment-methods"]/form/div[1]/div/div[2]')); + + $this->assertStringContainsString('One Bank (Tpay)', $element->getText()); + $this->assertStringContainsString('One Bank With Amount Min 20 Constraint (Tpay)', $element->getText()); + $this->assertStringNotContainsString('One Bank With Amount Min 30 Constraint (Tpay)', $element->getText()); + } } diff --git a/tests/Unit/PayByLinkPayment/Checker/PaymentMethodSupportedForOrderCheckerTest.php b/tests/Unit/PayByLinkPayment/Checker/PaymentMethodSupportedForOrderCheckerTest.php new file mode 100644 index 00000000..aefcf16a --- /dev/null +++ b/tests/Unit/PayByLinkPayment/Checker/PaymentMethodSupportedForOrderCheckerTest.php @@ -0,0 +1,124 @@ +cypher = $this->prophesize(CypherInterface::class); + $this->orderAwareValidTpayChannelListProvider = $this->prophesize(OrderAwareValidTpayChannelListProviderInterface::class); + $this->paymentMethod = $this->prophesize(PaymentMethodInterface::class); + $this->order = $this->prophesize(OrderInterface::class); + } + + public function test_it_returns_true_if_gateway_config_is_null(): void + { + $this->paymentMethod->getGatewayConfig()->willReturn(null); + + $result = $this + ->createTestSubject() + ->isSupportedForOrder($this->paymentMethod->reveal(), $this->order->reveal()) + ; + + $this->assertTrue($result); + } + + public function test_it_returns_true_if_gateway_config_factory_name_is_not_pay_by_link(): void + { + $gatewayConfig = $this->prophesize(GatewayConfigInterface::class); + $this->paymentMethod->getGatewayConfig()->willReturn($gatewayConfig->reveal()); + $gatewayConfig->getFactoryName()->willReturn('i_am_not_pay_by_link'); + + $result = $this + ->createTestSubject() + ->isSupportedForOrder($this->paymentMethod->reveal(), $this->order->reveal()) + ; + + $this->assertTrue($result); + } + + public function test_it_returns_true_if_gateway_config_does_not_have_tpay_channel_id(): void + { + $gatewayConfig = $this->prophesize(GatewayConfigInterface::class); + $this->paymentMethod->getGatewayConfig()->willReturn($gatewayConfig->reveal()); + $gatewayConfig->getFactoryName()->willReturn(GatewayName::PAY_BY_LINK); + $gatewayConfig->getConfig()->willReturn([]); + + $result = $this + ->createTestSubject() + ->isSupportedForOrder($this->paymentMethod->reveal(), $this->order->reveal()) + ; + + $this->assertTrue($result); + } + + public function test_it_returns_true_if_tpay_channel_id_is_valid(): void + { + $gatewayConfig = $this->prophesize(GatewayConfigInterface::class); + $this->paymentMethod->getGatewayConfig()->willReturn($gatewayConfig); + $gatewayConfig->getFactoryName()->willReturn(GatewayName::PAY_BY_LINK); + $gatewayConfig->getConfig()->willReturn(['tpay_channel_id' => 21]); + $this->orderAwareValidTpayChannelListProvider + ->provide($this->order) + ->willReturn([19 => [], 21 => [], 22 => []]) + ; + + $result = $this + ->createTestSubject() + ->isSupportedForOrder($this->paymentMethod->reveal(), $this->order->reveal()) + ; + + $this->assertTrue($result); + } + + public function test_it_returns_false_if_tpay_channel_id_is_not_valid(): void + { + $gatewayConfig = $this->prophesize(GatewayConfigInterface::class); + $this->paymentMethod->getGatewayConfig()->willReturn($gatewayConfig->reveal()); + $gatewayConfig->getFactoryName()->willReturn(GatewayName::PAY_BY_LINK); + $gatewayConfig->getConfig()->willReturn(['tpay_channel_id' => 21]); + $this->orderAwareValidTpayChannelListProvider + ->provide($this->order) + ->willReturn([19 => [], 22 => []]) + ; + + $result = $this + ->createTestSubject() + ->isSupportedForOrder($this->paymentMethod->reveal(), $this->order->reveal()) + ; + + $this->assertFalse($result); + } + + private function createTestSubject(): PaymentMethodSupportedForOrderChecker + { + return new PaymentMethodSupportedForOrderChecker( + $this->cypher->reveal(), + $this->orderAwareValidTpayChannelListProvider->reveal(), + ); + } +} diff --git a/tests/Unit/Payment/Resolver/OrderBasedPaymentMethodsResolverTest.php b/tests/Unit/Payment/Resolver/OrderBasedPaymentMethodsResolverTest.php new file mode 100644 index 00000000..e8f9b2ef --- /dev/null +++ b/tests/Unit/Payment/Resolver/OrderBasedPaymentMethodsResolverTest.php @@ -0,0 +1,131 @@ +paymentMethodResolver = $this->prophesize(PaymentMethodsResolverInterface::class); + $this->paymentMethodSupportedForOrderChecker = $this->prophesize(PaymentMethodSupportedForOrderCheckerInterface::class); + $this->subject = $this->prophesize(CorePaymentInterface::class); + } + + public function test_it_gets_order_based_supported_methods(): void + { + $firstPaymentMethod = $this->prophesize(PaymentMethodInterface::class); + $secondPaymentMethod = $this->prophesize(PaymentMethodInterface::class); + $thirdPaymentMethod = $this->prophesize(PaymentMethodInterface::class); + $order = $this->prophesize(OrderInterface::class); + $this->paymentMethodResolver + ->getSupportedMethods($this->subject) + ->willReturn([ + $firstPaymentMethod->reveal(), + $secondPaymentMethod->reveal(), + $thirdPaymentMethod->reveal(), + ]) + ; + $this->paymentMethodResolver->supports($this->subject)->willReturn(true); + $this->subject->getOrder()->willReturn($order); + $this->paymentMethodSupportedForOrderChecker + ->isSupportedForOrder($firstPaymentMethod, $order) + ->willReturn(true) + ; + $this->paymentMethodSupportedForOrderChecker + ->isSupportedForOrder($secondPaymentMethod, $order) + ->willReturn(false) + ; + $this->paymentMethodSupportedForOrderChecker + ->isSupportedForOrder($thirdPaymentMethod, $order) + ->willReturn(true) + ; + + $result = $this + ->createTestSubject() + ->getSupportedMethods($this->subject->reveal()) + ; + + $this->assertCount(2, $result); + $this->assertSame($firstPaymentMethod->reveal(), $result[0]); + $this->assertSame($thirdPaymentMethod->reveal(), $result[1]); + } + + public function test_it_throws_exception_if_subject_order_is_null(): void + { + $firstPaymentMethod = $this->prophesize(PaymentMethodInterface::class); + $secondPaymentMethod = $this->prophesize(PaymentMethodInterface::class); + $thirdPaymentMethod = $this->prophesize(PaymentMethodInterface::class); + $this->paymentMethodResolver + ->getSupportedMethods($this->subject) + ->willReturn([ + $firstPaymentMethod->reveal(), + $secondPaymentMethod->reveal(), + $thirdPaymentMethod->reveal(), + ]) + ; + $this->paymentMethodResolver->supports($this->subject)->willReturn(true); + $this->subject->getOrder()->willReturn(null); + + $this->expectException(InvalidArgumentException::class); + + $this + ->createTestSubject() + ->getSupportedMethods($this->subject->reveal()) + ; + } + + public function test_it_throws_exception_if_resolver_is_not_supported(): void + { + $this->paymentMethodResolver->supports($this->subject)->willReturn(false); + + $this->expectException(InvalidArgumentException::class); + + $this + ->createTestSubject() + ->getSupportedMethods($this->subject->reveal()) + ; + } + + public function test_it_throws_exception_if_subject_is_not_core_payment(): void + { + $subject = $this->prophesize(PaymentInterface::class); + + $this->expectException(InvalidArgumentException::class); + + $this + ->createTestSubject() + ->getSupportedMethods($subject->reveal()) + ; + } + + private function createTestSubject(): OrderBasedPaymentMethodsResolver + { + return new OrderBasedPaymentMethodsResolver( + $this->paymentMethodResolver->reveal(), + $this->paymentMethodSupportedForOrderChecker->reveal() + ); + } +} diff --git a/tests/mockoon_tpay.json b/tests/mockoon_tpay.json index 6430147d..38ab3f04 100644 --- a/tests/mockoon_tpay.json +++ b/tests/mockoon_tpay.json @@ -732,7 +732,7 @@ "responses": [ { "uuid": "924f9fab-d6ab-4365-b84b-e8ab13514143", - "body": "{\n \"result\":\"success\",\n \"requestId\":\"c36e286ceb64a95b8858\",\n \"language\":\"pl\",\n \"currency\":\"PLN\",\n \"channels\":[\n {\n \"id\":\"1\",\n \"name\":\"BNP Paribas\",\n \"fullName\":\"BNP Paribas Bank Polska SA\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/channels/1/normal-white-bg-e.png\"\n },\n \"available\":true,\n \"onlinePayment\":true,\n \"instantRedirection\":true,\n \"groups\":[\n {\n \"id\":\"133\",\n \"name\":\"BNP Paribas Bank Polska SA\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/groups/133/normal-white-bg.png\"\n }\n }\n ],\n \"constraints\":[\n \n ]\n },\n {\n \"id\":\"2\",\n \"name\":\"Not a bank\",\n \"fullName\":\"Not a bank\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/channels/2/normal-white-bg-e.png\"\n },\n \"available\":true,\n \"onlinePayment\":true,\n \"instantRedirection\":false,\n \"groups\":[\n {\n \"id\":\"114\",\n \"name\":\"Bank Millennium SA\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/groups/114/normal-white-bg.png\"\n }\n }\n ],\n \"constraints\":[\n \n ]\n },\n {\n \"id\":\"3\",\n \"name\":\"Unavailable\",\n \"fullName\":\"Unavailable\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/channels/4/normal-white-bg-e.png\"\n },\n \"available\":false,\n \"onlinePayment\":true,\n \"instantRedirection\":true,\n \"groups\":[\n {\n \"id\":\"102\",\n \"name\":\"Bank Pekao SA\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/groups/102/normal-white-bg.png\"\n }\n }\n ],\n \"constraints\":[\n \n ]\n },\n {\n \"id\":\"991\",\n \"name\":\"FAIL bank\",\n \"fullName\":\"FAIL bank SA\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/channels/1/normal-white-bg-e.png\"\n },\n \"available\":true,\n \"onlinePayment\":true,\n \"instantRedirection\":true,\n \"groups\":[\n {\n \"id\":\"991\",\n \"name\":\"FAIL BANK\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/groups/133/normal-white-bg.png\"\n }\n }\n ],\n \"constraints\":[\n \n ]\n }\n ]\n}", + "body": "{\n \"result\":\"success\",\n \"requestId\":\"c36e286ceb64a95b8858\",\n \"language\":\"pl\",\n \"currency\":\"PLN\",\n \"channels\":[\n {\n \"id\":\"1\",\n \"name\":\"BNP Paribas\",\n \"fullName\":\"BNP Paribas Bank Polska SA\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/channels/1/normal-white-bg-e.png\"\n },\n \"available\":true,\n \"onlinePayment\":true,\n \"instantRedirection\":true,\n \"groups\":[\n {\n \"id\":\"133\",\n \"name\":\"BNP Paribas Bank Polska SA\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/groups/133/normal-white-bg.png\"\n }\n }\n ],\n \"constraints\":[\n \n ]\n },\n {\n \"id\":\"2\",\n \"name\":\"Not a bank\",\n \"fullName\":\"Not a bank\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/channels/2/normal-white-bg-e.png\"\n },\n \"available\":true,\n \"onlinePayment\":true,\n \"instantRedirection\":false,\n \"groups\":[\n {\n \"id\":\"114\",\n \"name\":\"Bank Millennium SA\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/groups/114/normal-white-bg.png\"\n }\n }\n ],\n \"constraints\":[\n \n ]\n },\n {\n \"id\":\"3\",\n \"name\":\"Unavailable\",\n \"fullName\":\"Unavailable\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/channels/4/normal-white-bg-e.png\"\n },\n \"available\":false,\n \"onlinePayment\":true,\n \"instantRedirection\":true,\n \"groups\":[\n {\n \"id\":\"102\",\n \"name\":\"Bank Pekao SA\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/groups/102/normal-white-bg.png\"\n }\n }\n ],\n \"constraints\":[\n \n ]\n },\n {\n \"id\":\"4\",\n \"name\":\"Restricted 1\",\n \"fullName\":\"Restricted 1\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/channels/5/normal-white-bg-e.png\"\n },\n \"available\":true,\n \"onlinePayment\":true,\n \"instantRedirection\":true,\n \"groups\":[\n {\n \"id\":\"102\",\n \"name\":\"Bank Pekao SA\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/groups/102/normal-white-bg.png\"\n }\n }\n ],\n \"constraints\":[\n {\n \"field\": \"amount\",\n \"type\": \"min\",\n \"value\": \"20.00\"\n },\n {\n \"field\": \"amount\",\n \"type\": \"max\",\n \"value\": \"20000.00\"\n }\n ]\n },\n {\n \"id\":\"5\",\n \"name\":\"Restricted 2\",\n \"fullName\":\"Restricted 2\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/channels/5/normal-white-bg-e.png\"\n },\n \"available\":true,\n \"onlinePayment\":true,\n \"instantRedirection\":true,\n \"groups\":[\n {\n \"id\":\"102\",\n \"name\":\"Bank Pekao SA\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/groups/102/normal-white-bg.png\"\n }\n }\n ],\n \"constraints\":[\n {\n \"field\": \"amount\",\n \"type\": \"min\",\n \"value\": \"30.00\"\n },\n {\n \"field\": \"amount\",\n \"type\": \"max\",\n \"value\": \"20000.00\"\n }\n ]\n },\n {\n \"id\":\"991\",\n \"name\":\"FAIL bank\",\n \"fullName\":\"FAIL bank SA\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/channels/1/normal-white-bg-e.png\"\n },\n \"available\":true,\n \"onlinePayment\":true,\n \"instantRedirection\":true,\n \"groups\":[\n {\n \"id\":\"991\",\n \"name\":\"FAIL BANK\",\n \"image\":{\n \"url\":\"https://secure.sandbox.tpay.com/tpay/web/groups/133/normal-white-bg.png\"\n }\n }\n ],\n \"constraints\":[\n \n ]\n }\n ]\n}", "latency": 0, "statusCode": 200, "label": "",