in reply to HTTP::Tiny losing headers for Stripe

When you are sending the $subscription back to Stripe I imagine it needs to be encoded as JSON - from your script it looks like you are sending a perl data structure.

You will also need to set the "content-type" header to "application/json" and use the request() method instead of post_form() as the latter only sends "application/x-www-form-urlencoded" (at least that what the docs seem to be saying)

my $subscription = { 'items[0][id]' => 'x', 'items[0][price]' => 'some price', }; my $options = { 'headers' => { 'Authorization' => 'Bearer ' . $Site::Variables::stripe_secret +, 'content-type' => 'application/json', }, 'content' => encode_json($subscription), }; my $response = $http->request('POST', "https://api.stripe.com/v1/subsc +riptions/$sub_id", $options);

Replies are listed 'Best First'.
Re^2: HTTP::Tiny losing headers for Stripe
by Bod (Parson) on Jun 25, 2022 at 22:27 UTC
    I imagine it needs to be encoded as JSON

    No - Stripe takes key/value pairs.

    To quote the documentation:
    accepts form-encoded request bodies, returns JSON-encoded responses

    For a form-encoded request, application/x-www-form-urlencoded is required hence the use of post_form().

    The syntax of the call to Stripe works elsewhere in my code. Indeed, the call I am making works provided I don't make another call before it - it is this problem I want help resolving.

    I'm unsure if it is an issue with HTTP::Tiny not being able to reuse the header information or an issue with Stripe or something else...

    Out of interest, I have tried using the request() method as you suggested.
    With the first call still in the code I continue to get a 401 error and the message that I have not supplied an API Key.
    If I comment out the first call to Stripe, it accepts the API Key but returns the entire subscription object because it is not accepting the JSON encoded payload.

      No - Stripe takes key/value pairs.
      Ah, I see. Still might be an issue sending a perl hash which is not the same as key-value pairs coming from a form. You could try:
      'content' => $http->www_form_urlencode( $subscription ), # or just to try getting it to work 'content' => q|"items[0][id]"="x","items[0][price]"="some price"|,

      Update: I think you can strike the above as looking at the source for the module post_form does call www_form_urlencode on the content. I'm stumped for the moment.

        The reason I'm stumped is that it works providing I don't make a call to the Stripe API followed by another. One call works - two calls don't.

        I've eliminated rate limiting by trying a 5 second delay between calls.