[SOLVED] Moralis.Cloud.Http nested body with application/x-www-form-urlencoded

Hello guys,
I am making http request from cloud functions to an API which only accepts application/x-www-form-urlencoded as content-type, I am trying to have a nested body object but seems like the Moralis’ http wrapper is not parsing that, tried to manually parse a new FromData but it’s not defined, any solution for that scenario?

1 Like

what else is needed besides that content-type?

Bearer auth token, it’s stripe’s api

If you mean as content-type it’s only application/x-www-form-urlencoded … That’s how the API responds if I change/add any other type

I don’t understand the problem yet, how should a valid request look, in http format? for example, can you make that request with CURL?

The problem is that on a payment intent request, I am creating an object/array on the request body, example in curl:

> curl https://api.stripe.com/v1/payment_intents \
>   -u sk_test_51J5ajwBFO6vKMbiJYg3BE9or5kTroyZPoALMSAav6TquLJhFKOGf9i4jw9nL3tkctDaGkoFW0P9qhNkChSTyuBDk009FxqH3dp: \
>   -d amount=2000 \
>   -d currency=usd \
>   -d "payment_method_types[]"=card

If I try to build the http body as {…otherkeys, payment_method_types: [‘card’]} … the payment_method_types keys is not parsed and I get back with a response that it is empty value… Same happens if the body has an object, like {…otherkeys, metadata:{…meta}} … Objects on the body are not parsed when the content-type is application/x-www-form-urlencoded (the required content-type for stripe api)

What is the object you’re passing in exactly? Or are you talking about the response from the API?

Looking at the docs for that API, the example says you just pass in “card”. Also usd and card should be a string.

This is exactly what I am doing.
Sending

payment_method_types: ['card']

Gets back with “payment_method_types is empty”, as well as adding:

metadata:{...}

Again gets back with “metadata can’t be empty”

For any other string value it’s fine

This test works:

curl https://api.stripe.com/v1/payment_intents \
  -H "Authorization: Bearer sk_test_51J5ajwBFO6vKMbiJYg3BE9or5kTroyZPoALMSAav6TquLJhFKOGf9i4jw9nL3tkctDaGkoFW0P9qhNkChSTyuBDk009FxqH3dp" \
  -d "amount"=1099 \
  -d "currency"="usd" \
  -d "payment_method_types[]"="card"

What does your metadata object look like? It looks like Stripe expects metadata[order_id] or metadata[key] for each separate metadata key/value.

How is this one implemented in Moralis.Cloud.Http body?

You can add the header and params as outlined here: httpRequest - Moralis

Man that’s exactly what I am doing and what my original question is about, I do that and if the body has objects they are not parsed… For this code:

const _pi = await Moralis.Cloud.httpRequest({
method: ‘POST’,
url : ‘https://api.stripe.com/v1/payment_intents’,
headers: stripeHeaders,
{
body:{
amount: amount * 100,
currency: currency.toLowerCase(),
customer: stripeId,
description: ‘description’,
payment_method_types:[‘card’],
metadata:{
userId: userId
}
}
})
Metadata and payment_method_types are received at stripe as empty values hence throw exception on stripe API

maybe stripe doesn’t expect json data, maybe you can send it a string directly

I tried that as well… Responded with type exception

Like the working example above it probably should be:

payment_method_types[]: "card"
metadata[userId]: userId 
// not sure where userId is meant to come from in your cloud function

Try just using static values for each property.

This can’t be attached on json body:

Moralis.Cloud.httpRequest({
method: ‘POST’,
url : ‘https://api.stripe.com/v1/payment_intents’,
headers: stripeHeaders,
{
body:{
     amount: amount * 100,
     currency: currency.toLowerCase(),
     customer: stripeId,
     description: ‘description’,
     payment_method_types:[‘card’],
     metadata:{
         userId: userId
      }
  }
})

The shown body schema doesn’t get parsed man. This request throws exception that metadata and pyment_method_types are empty

Do you have an example of raw http request that works? With raw header and raw body?

This gets a valid response:

const logger = Moralis.Cloud.getLogger();

Moralis.Cloud.httpRequest({
  url: 'https://api.stripe.com/v1/payment_intents',
  method: 'POST',
  headers: {
    'Authorization': 'Bearer sk_test_51J5ajwBFO6vKMbiJYg3BE9or5kTroyZPoALMSAav6TquLJhFKOGf9i4jw9nL3tkctDaGkoFW0P9qhNkChSTyuBDk009FxqH3dp'
  },
  body: {
    "amount": "1099",
    "currency": "usd", 
    "payment_method_types[]": "card",
  }
}).then(function(httpResponse) {
  // success
  logger.info(httpResponse.text);
},function(httpResponse) {
  // error
  logger.info('Response: ' + JSON.stringify(httpResponse));
});
1 Like

Yes … Just to complete the answer for future visitors: if you’re adding more than value into the array it should go like:

"payment_method_types[0]": "card",
"payment_method_types[1]": "klarna",
...etc

Thank you… The issue is resolved

1 Like