diff --git a/lib/yoomoney/models/payment_create_params.rb b/lib/yoomoney/models/payment_create_params.rb index f709572..81c1407 100644 --- a/lib/yoomoney/models/payment_create_params.rb +++ b/lib/yoomoney/models/payment_create_params.rb @@ -181,17 +181,25 @@ class PaymentCreateParams < Yoomoney::Internal::Type::BaseModel module Confirmation extend Yoomoney::Internal::Type::Union - variant -> { Yoomoney::PaymentCreateParams::Confirmation::ConfirmationDataRedirect } + discriminator :type - variant -> { Yoomoney::PaymentCreateParams::Confirmation::ConfirmationDataExternal } + variant :redirect, -> { Yoomoney::PaymentCreateParams::Confirmation::ConfirmationDataRedirect } - variant -> { Yoomoney::ConfirmationData } + variant :external, -> { Yoomoney::PaymentCreateParams::Confirmation::ConfirmationDataExternal } - variant -> { Yoomoney::PaymentCreateParams::Confirmation::ConfirmationDataEmbedded } + variant :qr, -> { Yoomoney::ConfirmationData } - variant -> { Yoomoney::PaymentCreateParams::Confirmation::ConfirmationDataMobileApplication } + variant :embedded, -> { Yoomoney::PaymentCreateParams::Confirmation::ConfirmationDataEmbedded } + + variant :mobile_application, -> { Yoomoney::PaymentCreateParams::Confirmation::ConfirmationDataMobileApplication } class ConfirmationDataRedirect < Yoomoney::Models::ConfirmationData + # @!attribute type + # Код сценария подтверждения. + # + # @return [Symbol, :redirect] + required :type, const: :redirect + # @!attribute return_url # URL, на который необходимо перенаправить пользователя после оплаты. # @@ -204,43 +212,73 @@ class ConfirmationDataRedirect < Yoomoney::Models::ConfirmationData # @return [Boolean, nil] optional :enforce, Yoomoney::Internal::Type::Boolean - # @!method initialize(return_url:, enforce: nil) + # @!method initialize(return_url:, enforce: nil, locale: nil, type: :redirect) # @param return_url [String] URL, на который необходимо перенаправить пользователя после оплаты. # # @param enforce [Boolean] Требование пройти аутентификацию при оплате банковской картой по 3-D Secure. + # + # @param locale [Symbol, Yoomoney::Models::Locale] Язык интерфейса, писем и смс. + # + # @param type [Symbol, :redirect] Код сценария подтверждения. end class ConfirmationDataExternal < Yoomoney::Models::ConfirmationData + # @!attribute type + # Код сценария подтверждения. + # + # @return [Symbol, :external] + required :type, const: :external + # @!attribute locale # Язык интерфейса. # # @return [Symbol, Yoomoney::Models::Locale, nil] optional :locale, enum: -> { Yoomoney::Locale } - # @!method initialize(locale: nil) + # @!method initialize(locale: nil, type: :external) # @param locale [Symbol, Yoomoney::Models::Locale] Язык интерфейса. + # + # @param type [Symbol, :external] Код сценария подтверждения. end class ConfirmationDataEmbedded < Yoomoney::Models::ConfirmationData + # @!attribute type + # Код сценария подтверждения. + # + # @return [Symbol, :embedded] + required :type, const: :embedded + # @!attribute locale # Язык интерфейса. # # @return [Symbol, Yoomoney::Models::Locale, nil] optional :locale, enum: -> { Yoomoney::Locale } - # @!method initialize(locale: nil) + # @!method initialize(locale: nil, type: :embedded) # @param locale [Symbol, Yoomoney::Models::Locale] Язык интерфейса. + # + # @param type [Symbol, :embedded] Код сценария подтверждения. end class ConfirmationDataMobileApplication < Yoomoney::Models::ConfirmationData + # @!attribute type + # Код сценария подтверждения. + # + # @return [Symbol, :mobile_application] + required :type, const: :mobile_application + # @!attribute return_url # URL, на который необходимо перенаправить пользователя после оплаты. # # @return [String] required :return_url, String - # @!method initialize(return_url:) + # @!method initialize(return_url:, locale: nil, type: :mobile_application) # @param return_url [String] URL, на который необходимо перенаправить пользователя после оплаты. + # + # @param locale [Symbol, Yoomoney::Models::Locale] Язык интерфейса, писем и смс. + # + # @param type [Symbol, :mobile_application] Код сценария подтверждения. end # @!method self.variants diff --git a/rbi/yoomoney/models/payment_create_params.rbi b/rbi/yoomoney/models/payment_create_params.rbi index 5e17b85..14391c1 100644 --- a/rbi/yoomoney/models/payment_create_params.rbi +++ b/rbi/yoomoney/models/payment_create_params.rbi @@ -407,6 +407,17 @@ module Yoomoney ) end + # Код сценария подтверждения. + sig { returns(Symbol) } + attr_accessor :type + + # Язык интерфейса, писем и смс. + sig { returns(T.nilable(Yoomoney::Locale::OrSymbol)) } + attr_reader :locale + + sig { params(locale: Yoomoney::Locale::OrSymbol).void } + attr_writer :locale + # URL, на который необходимо перенаправить пользователя после оплаты. sig { returns(String) } attr_accessor :return_url @@ -419,19 +430,35 @@ module Yoomoney attr_writer :enforce sig do - params(return_url: String, enforce: T::Boolean).returns( - T.attached_class - ) + params( + return_url: String, + enforce: T::Boolean, + locale: Yoomoney::Locale::OrSymbol, + type: Symbol + ).returns(T.attached_class) end def self.new( # URL, на который необходимо перенаправить пользователя после оплаты. return_url:, # Требование пройти аутентификацию при оплате банковской картой по 3-D Secure. - enforce: nil + enforce: nil, + # Язык интерфейса, писем и смс. + locale: nil, + # Код сценария подтверждения. + type: :redirect ) end - sig { override.returns({ return_url: String, enforce: T::Boolean }) } + sig do + override.returns( + { + return_url: String, + enforce: T::Boolean, + locale: Yoomoney::Locale::OrSymbol, + type: Symbol + } + ) + end def to_hash end end @@ -445,6 +472,10 @@ module Yoomoney ) end + # Код сценария подтверждения. + sig { returns(Symbol) } + attr_accessor :type + # Язык интерфейса. sig { returns(T.nilable(Yoomoney::Locale::OrSymbol)) } attr_reader :locale @@ -453,15 +484,23 @@ module Yoomoney attr_writer :locale sig do - params(locale: Yoomoney::Locale::OrSymbol).returns(T.attached_class) + params(locale: Yoomoney::Locale::OrSymbol, type: Symbol).returns( + T.attached_class + ) end def self.new( # Язык интерфейса. - locale: nil + locale: nil, + # Код сценария подтверждения. + type: :external ) end - sig { override.returns({ locale: Yoomoney::Locale::OrSymbol }) } + sig do + override.returns( + { locale: Yoomoney::Locale::OrSymbol, type: Symbol } + ) + end def to_hash end end @@ -475,6 +514,10 @@ module Yoomoney ) end + # Код сценария подтверждения. + sig { returns(Symbol) } + attr_accessor :type + # Язык интерфейса. sig { returns(T.nilable(Yoomoney::Locale::OrSymbol)) } attr_reader :locale @@ -483,15 +526,23 @@ module Yoomoney attr_writer :locale sig do - params(locale: Yoomoney::Locale::OrSymbol).returns(T.attached_class) + params(locale: Yoomoney::Locale::OrSymbol, type: Symbol).returns( + T.attached_class + ) end def self.new( # Язык интерфейса. - locale: nil + locale: nil, + # Код сценария подтверждения. + type: :embedded ) end - sig { override.returns({ locale: Yoomoney::Locale::OrSymbol }) } + sig do + override.returns( + { locale: Yoomoney::Locale::OrSymbol, type: Symbol } + ) + end def to_hash end end @@ -505,18 +556,47 @@ module Yoomoney ) end + # Код сценария подтверждения. + sig { returns(Symbol) } + attr_accessor :type + + # Язык интерфейса, писем и смс. + sig { returns(T.nilable(Yoomoney::Locale::OrSymbol)) } + attr_reader :locale + + sig { params(locale: Yoomoney::Locale::OrSymbol).void } + attr_writer :locale + # URL, на который необходимо перенаправить пользователя после оплаты. sig { returns(String) } attr_accessor :return_url - sig { params(return_url: String).returns(T.attached_class) } + sig do + params( + return_url: String, + locale: Yoomoney::Locale::OrSymbol, + type: Symbol + ).returns(T.attached_class) + end def self.new( # URL, на который необходимо перенаправить пользователя после оплаты. - return_url: + return_url:, + # Язык интерфейса, писем и смс. + locale: nil, + # Код сценария подтверждения. + type: :mobile_application ) end - sig { override.returns({ return_url: String }) } + sig do + override.returns( + { + return_url: String, + locale: Yoomoney::Locale::OrSymbol, + type: Symbol + } + ) + end def to_hash end end diff --git a/sig/yoomoney/models/payment_create_params.rbs b/sig/yoomoney/models/payment_create_params.rbs index 019b3fa..8ea4e79 100644 --- a/sig/yoomoney/models/payment_create_params.rbs +++ b/sig/yoomoney/models/payment_create_params.rbs @@ -175,9 +175,23 @@ module Yoomoney module Confirmation extend Yoomoney::Internal::Type::Union - type confirmation_data_redirect = { return_url: String, enforce: bool } + type confirmation_data_redirect = + { + return_url: String, + enforce: bool, + locale: Yoomoney::Models::locale, + type: :redirect + } class ConfirmationDataRedirect < Yoomoney::Models::ConfirmationData + def type: -> :redirect + + def type=: (:redirect _) -> :redirect + + def locale: -> Yoomoney::Models::locale? + + def locale=: (Yoomoney::Models::locale _) -> Yoomoney::Models::locale + def return_url: -> String def return_url=: (String _) -> String @@ -186,45 +200,86 @@ module Yoomoney def enforce=: (bool _) -> bool - def initialize: (return_url: String, ?enforce: bool) -> void + def initialize: ( + return_url: String, + ?enforce: bool, + ?locale: Yoomoney::Models::locale, + ?type: :redirect + ) -> void - def to_hash: -> { return_url: String, enforce: bool } + def to_hash: -> { + return_url: String, + enforce: bool, + locale: Yoomoney::Models::locale, + type: :redirect + } end - type confirmation_data_external = { locale: Yoomoney::Models::locale } + type confirmation_data_external = + { locale: Yoomoney::Models::locale, type: :external } class ConfirmationDataExternal < Yoomoney::Models::ConfirmationData + def type: -> :external + + def type=: (:external _) -> :external + def locale: -> Yoomoney::Models::locale? def locale=: (Yoomoney::Models::locale _) -> Yoomoney::Models::locale - def initialize: (?locale: Yoomoney::Models::locale) -> void + def initialize: (?locale: Yoomoney::Models::locale, ?type: :external) -> void - def to_hash: -> { locale: Yoomoney::Models::locale } + def to_hash: -> { locale: Yoomoney::Models::locale, type: :external } end - type confirmation_data_embedded = { locale: Yoomoney::Models::locale } + type confirmation_data_embedded = + { locale: Yoomoney::Models::locale, type: :embedded } class ConfirmationDataEmbedded < Yoomoney::Models::ConfirmationData + def type: -> :embedded + + def type=: (:embedded _) -> :embedded + def locale: -> Yoomoney::Models::locale? def locale=: (Yoomoney::Models::locale _) -> Yoomoney::Models::locale - def initialize: (?locale: Yoomoney::Models::locale) -> void + def initialize: (?locale: Yoomoney::Models::locale, ?type: :embedded) -> void - def to_hash: -> { locale: Yoomoney::Models::locale } + def to_hash: -> { locale: Yoomoney::Models::locale, type: :embedded } end - type confirmation_data_mobile_application = { return_url: String } + type confirmation_data_mobile_application = + { + return_url: String, + locale: Yoomoney::Models::locale, + type: :mobile_application + } class ConfirmationDataMobileApplication < Yoomoney::Models::ConfirmationData + def type: -> :mobile_application + + def type=: (:mobile_application _) -> :mobile_application + + def locale: -> Yoomoney::Models::locale? + + def locale=: (Yoomoney::Models::locale _) -> Yoomoney::Models::locale + def return_url: -> String def return_url=: (String _) -> String - def initialize: (return_url: String) -> void + def initialize: ( + return_url: String, + ?locale: Yoomoney::Models::locale, + ?type: :mobile_application + ) -> void - def to_hash: -> { return_url: String } + def to_hash: -> { + return_url: String, + locale: Yoomoney::Models::locale, + type: :mobile_application + } end def self?.variants: -> ::Array[Yoomoney::Models::PaymentCreateParams::confirmation] diff --git a/test/yoomoney/models/payment_create_params_test.rb b/test/yoomoney/models/payment_create_params_test.rb new file mode 100644 index 0000000..4d5da93 --- /dev/null +++ b/test/yoomoney/models/payment_create_params_test.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require_relative "../test_helper" + +class Yoomoney::Test::PaymentCreateParamsModelTest < Minitest::Test + extend Minitest::Serial + include WebMock::API + + Confirmation = Yoomoney::PaymentCreateParams::Confirmation + + def before_all + super + WebMock.enable! + end + + def teardown + WebMock.reset! + super + end + + def after_all + WebMock.disable! + super + end + + def test_confirmation_models_send_their_type + { + Confirmation::ConfirmationDataRedirect.new(return_url: "https://example.com", locale: :ru_RU) => + {"type" => "redirect", "return_url" => "https://example.com", "locale" => "ru_RU"}, + Confirmation::ConfirmationDataExternal.new => {"type" => "external"}, + Confirmation::ConfirmationDataEmbedded.new(locale: :en_US) => {"type" => "embedded", "locale" => "en_US"}, + Confirmation::ConfirmationDataMobileApplication.new(return_url: "app://return") => + {"type" => "mobile_application", "return_url" => "app://return"} + }.each do |confirmation, expected| + assert_equal(expected, sent_confirmation(confirmation)) + end + end + + def test_confirmation_hash_picks_variant_by_type + confirmation = Confirmation.coerce({type: "redirect", return_url: "https://example.com"}, state: coerce_state) + + assert_kind_of(Confirmation::ConfirmationDataRedirect, confirmation) + end + + private + + def sent_confirmation(confirmation) + body = nil + stub_request(:post, "http://localhost/payments").to_return_json(status: 500, body: {}) + .with { body = JSON.parse(_1.body) } + client = Yoomoney::Client.new(base_url: "http://localhost", username: "u", password: "p", max_retries: 0) + + assert_raises(Yoomoney::Errors::InternalServerError) do + client.payments.create(amount: {currency: :RUB, value: "1.00"}, idempotence_key: "key", confirmation:) + end + body.fetch("confirmation") + end + + def coerce_state = {translate_names: false, strictness: true, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0} +end