Re: Get Response output is randomized, not Form field names
Hopefully this is what you're looking for.
For this example, I'm using the following Microsoft Form.

See full flow below. I'll go into each of the actions.

When a new response is submitted and Get response details is what you already have.

Compose builds up our object containing the values we want from our Microsoft Form (the quantities). I've also converted them to numbers (int) since they always come back from Microsoft Forms as strings. The expressions used are below. Note that you would just need to use your names and dynamic Ids here.
{
"BizCardQuantity": @{int(outputs('Get_response_details')?['body/r744b46f0008349129dff96dc2d43a0e6'])},
"LetterheadQuantity": @{int(outputs('Get_response_details')?['body/r96d7c4c0b75d4beabc102f16dbf97279'])},
"CustomEnvQuantity": @{int(outputs('Get_response_details')?['body/r89a8124c44d94d3a9a016b786b5b73e1'])},
"RegEnvQuantity": @{int(outputs('Get_response_details')?['body/r8e1bf2568b1143d581047d44d54a722b'])}
}

IMPORTANT: At this point you should save and run your flow and copy the output from the Compose. You will use this to build your schema in the Parse JSON step next.
Parse JSON uses the output from Compose. And for the schema, click on Generate from sample, and paste in the output you copied in the last step. This will generate the schema based on your data.

Compose Test is just showing how you can now get your data via the Parse JSON dynamic properties to use in your calculations, etc.

----------------------------------------------------------------------
If I've answered your question, please mark the post as Solved.
If you like my response, please consider giving it a Thumbs Up.