From b9442c35bb6f19c21406c85cb45f4e67a8a1b774 Mon Sep 17 00:00:00 2001 From: Julien Bourdeau Date: Mon, 27 Jan 2025 16:37:07 +0100 Subject: [PATCH 1/3] feat(boleto): Introduce Boleto as a valid Stripe Payment Method --- app/models/payment_provider_customers/stripe_customer.rb | 2 +- spec/graphql/types/customers/customer_type_enum_spec.rb | 2 +- .../provider_payment_methods_enum_spec.rb | 9 +++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 spec/graphql/types/payment_provider_customers/provider_payment_methods_enum_spec.rb diff --git a/app/models/payment_provider_customers/stripe_customer.rb b/app/models/payment_provider_customers/stripe_customer.rb index 11578ae64ac..89048fa2cc6 100644 --- a/app/models/payment_provider_customers/stripe_customer.rb +++ b/app/models/payment_provider_customers/stripe_customer.rb @@ -2,7 +2,7 @@ module PaymentProviderCustomers class StripeCustomer < BaseCustomer - PAYMENT_METHODS = %w[card sepa_debit us_bank_account bacs_debit link].freeze + PAYMENT_METHODS = %w[card sepa_debit us_bank_account bacs_debit link boleto].freeze validates :provider_payment_methods, presence: true validate :allowed_provider_payment_methods diff --git a/spec/graphql/types/customers/customer_type_enum_spec.rb b/spec/graphql/types/customers/customer_type_enum_spec.rb index 06758846262..11feac2161f 100644 --- a/spec/graphql/types/customers/customer_type_enum_spec.rb +++ b/spec/graphql/types/customers/customer_type_enum_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe Types::Customers::CustomerTypeEnum do - it 'enumerizes the correct values' do + it 'enumerates the correct values' do expect(described_class.values.keys).to match_array(%w[company individual]) end end diff --git a/spec/graphql/types/payment_provider_customers/provider_payment_methods_enum_spec.rb b/spec/graphql/types/payment_provider_customers/provider_payment_methods_enum_spec.rb new file mode 100644 index 00000000000..21c476a2bc3 --- /dev/null +++ b/spec/graphql/types/payment_provider_customers/provider_payment_methods_enum_spec.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Types::PaymentProviderCustomers::ProviderPaymentMethodsEnum do + it 'enumerates the correct values' do + expect(described_class.values.keys).to match_array(%w[card sepa_debit us_bank_account bacs_debit link boleto]) + end +end From 50326710c21e6a5ba20f49c60e29a78820ceb631 Mon Sep 17 00:00:00 2001 From: Julien Bourdeau Date: Wed, 29 Jan 2025 11:39:14 +0100 Subject: [PATCH 2/3] spec spec/services/payment_providers/stripe/payments/create_service_spec.rb --- .../stripe/payments/create_service_spec.rb | 72 ++++++++++++++++--- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/spec/services/payment_providers/stripe/payments/create_service_spec.rb b/spec/services/payment_providers/stripe/payments/create_service_spec.rb index c26a4cb73e5..2892917f4f2 100644 --- a/spec/services/payment_providers/stripe/payments/create_service_spec.rb +++ b/spec/services/payment_providers/stripe/payments/create_service_spec.rb @@ -56,13 +56,13 @@ File.read(Rails.root.join("spec/fixtures/stripe/customer_retrieve_response.json")) end - let(:stripe_payment_intent) do - Stripe::PaymentIntent.construct_from( - id: "ch_123456", + let(:stripe_payment_intent_data) do + { + id: "pi_123456", status: payment_status, amount: invoice.total_amount_cents, currency: invoice.currency - ) + } end let(:payment_status) { "succeeded" } @@ -71,8 +71,10 @@ stripe_payment_provider stripe_customer - allow(Stripe::PaymentIntent).to receive(:create) - .and_return(stripe_payment_intent) + allow(Stripe::PaymentIntent).to receive(:create).and_call_original + stub_request(:post, "https://api.stripe.com/v1/payment_intents") + .to_return(body: stripe_payment_intent_data.to_json) + allow(SegmentTrackJob).to receive(:perform_later) allow(Invoices::PrepaidCreditJob).to receive(:perform_later) @@ -206,6 +208,9 @@ expect(result.error_message).to eq("error") expect(result.error_code).to be_nil + + expect(result.payment.status).to eq("failed") + expect(result.payment.payable_payment_status).to eq("failed") end end @@ -247,6 +252,53 @@ end end + context 'when invoice amount is too big to pay with Boleto' do + let(:organization) { create(:organization) } + let(:customer) { create(:customer, organization:) } + let(:subscription) { create(:subscription, organization:, customer:) } + + let(:invoice) do + create( + :invoice, + organization:, + customer:, + total_amount_cents: 100_000_00, + currency: "BRL", + ready_for_payment_processing: true + ) + end + + before do + subscription + + WebMock.stub_request(:post, "https://api.stripe.com/v1/payment_intents") + .to_return(status: 400, body: { + error: { + code: "amount_too_large", + doc_url: "https://stripe.com/docs/error-codes/amount-too-large", + message: "Amount must be no more than R$ 49,999.99 brl", + param: "amount", + request_log_url: "https://dashboard.stripe.com/test/logs/req_WAmkqXs7ajMNAU?t=1738144303", + type: "invalid_request_error" + } + }.to_json) + end + + it "returns an empty result" do + result = create_service.call + + expect(result).not_to be_success + expect(result.error).to be_a(BaseService::ServiceFailure) + expect(result.error.code).to eq("stripe_error") + expect(result.error.error_message).to eq("Amount must be no more than R$ 49,999.99 brl") + + expect(result.error_message).to eq("Amount must be no more than R$ 49,999.99 brl") + expect(result.error_code).to eq("amount_too_large") + expect(result.payment.status).to eq("failed") + expect(result.payment.payable_payment_status).to eq("failed") + end + end + context "when payment status is processing" do let(:payment_status) { "processing" } @@ -271,16 +323,16 @@ context "when customers country is IN" do let(:payment_status) { "requires_action" } - let(:stripe_payment_intent) do - Stripe::PaymentIntent.construct_from( - id: "ch_123456", + let(:stripe_payment_intent_data) do + { + id: "pi_123456", status: payment_status, amount: invoice.total_amount_cents, currency: invoice.currency, next_action: { redirect_to_url: {url: "https://foo.bar"} } - ) + } end before do From 0075b67a4cfec7d50a6820bc69b7eff0e47402a4 Mon Sep 17 00:00:00 2001 From: Julien Bourdeau Date: Wed, 29 Jan 2025 13:49:59 +0100 Subject: [PATCH 3/3] update gql schema dump --- schema.graphql | 1 + schema.json | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/schema.graphql b/schema.graphql index f0a4ebe7c9a..389a0939e2b 100644 --- a/schema.graphql +++ b/schema.graphql @@ -6491,6 +6491,7 @@ input ProviderCustomerInput { enum ProviderPaymentMethodsEnum { bacs_debit + boleto card link sepa_debit diff --git a/schema.json b/schema.json index 6b8ffd74503..c1a5fd8da27 100644 --- a/schema.json +++ b/schema.json @@ -31199,6 +31199,12 @@ "description": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "boleto", + "description": null, + "isDeprecated": false, + "deprecationReason": null } ] },