stripe-ruby icon indicating copy to clipboard operation
stripe-ruby copied to clipboard

Multiple query parameters with same key get de-duped

Open ryanseys opened this issue 3 years ago • 3 comments

Describe the bug

Bug

If you pass in multiple query parameters with the same key e.g. /v1/transactions?expand[]=data.flow_details&expand[]=data.entries , the resulting URL that is requested by the Stripe gem will only contain the last one i.e. /v1/transactions?expand[]=data.entries

Culprit

The culprit line is here where the query parameters are being converted into a Hash where the key of the Hash is the query parameter key, so only the last value is used.

https://github.com/stripe/stripe-ruby/blob/0aca5d2cdce1c734521ab16afe600278a8f1c6f0/lib/stripe/stripe_client.rb#L731

Workaround

Workaround in the case of expand[] parameters is to provide an index i.e. /v1/transactions?expand[0]=data.flow_details&expand[1]=data.entries so they don't get de-duped when converting to a Hash.

To Reproduce

stripe_client = Stripe::StripeClient.new
stripe_client.execute_request(
  :get, 
  "/v1/transactions?expand[]=data.flow_details&expand[]=data.entries",  # multiple expand[] parameters
  api_key: @api_key, 
  headers: request_options
)

Expected behavior

The resulting URL requested to Stripe contain all of the query parameters even if they have the same name.

Code snippets

No response

OS

macOS

Language version

Ruby 3.1.2

Library version

stripe-ruby 6.0.0

API version

2020-08-27

Additional context

No response

ryanseys avatar Jun 30 '22 20:06 ryanseys

Thanks for the detailed bug report, this is definitely not supposed to happen. A quick fix would be to use expand[0] and expand[1] in your query params to get unblocked but we'll look into how we can approach a fix without breaking any potential developer relying on this

remi-stripe avatar Jun 30 '22 22:06 remi-stripe

@remi-stripe Thanks for the quick response! Also to note that if the expand it passed in as an Array via the opts on the higher-level objects, it does not suffer from this issue.

i.e. this works and expands both fields:

Stripe::Treasury::Transaction.retrieve({
  id: id,
  expand: ["flow_details", "entries"],
}, request_options)

Also this works and expands both fields in the listed objects:

Stripe::Treasury::Transaction.list({
  financial_account: financial_account_id,
  expand: ["data.flow_details", "data.entries"],
}, request_options)

But when making the request directly with execute_request it suffers from this bug.

ryanseys avatar Jul 01 '22 00:07 ryanseys

Yeah it's some really specific logic where we didn't imagine someone would pass query parameters in that url. Definitely a quirk, but fixing it as a patch could cause issues for some integrations that never realized this and relied on the behaviour. We'll see if it's safe enough to release as a patch or in the next major (one is coming soon anyways)

remi-stripe avatar Jul 01 '22 00:07 remi-stripe