Storing ajax callback variables in PrivateTempStore
PrivateTempStore is not the right fit for this. You want to store the value in the $form_state, but you do not store it in the AJAX callback, you store it in the submit handler, then set the form to rebuild (which will persist the values in the storage. You can set a custom #submit handler on your ajax submit button that is only called when that button is clicked:

$form['wrapper_amount']['value'] = [
  '#type' =&gt; 'number',
  '#prefix' =&gt; '&lt;div class="d-flex align-items-end form-element"&gt;',
  '#suffix' =&gt; '&lt;span class="form-element-unit"&gt;pcs&lt;/span&gt;&lt;/div&gt;',
  // note - #name is commented out, as you should never
  // need to change it in Drupal, and doing so will have
  // unexpected consequences. 
  // '#name' =&gt; "amount--product-1",
  '#ajax' =&gt; [
    'callback' =&gt; '::calculatePricePerUnit',
    'event' =&gt; 'change',
    'disable-refocus' =&gt; TRUE,
    'progress' =&gt; [
      'type' =&gt; 'fade',
      'message' =&gt; NULL,
    ],
  ],
  '#submit' =&gt; ['::customSubmit'],
];


Then your custom submit will look like this:

public function customSubmit(array &amp;$form, FormStateInterface $form_state) {
  $total_price = (float)$form_state-&gt;get('total_price_with_vat') + $new_price;
  $form_state-&gt;set('total_price', total_price);
  $form_state-&gt;setRebuild(TRUE);
}


After playing around with this a little, I can see that a submit button is required to be able to call a submit handler where rebuildForm() can be recalled. If you set the #ajax on a non-submit button, ajax is called, but rebuildForm() is not able to be called.

As such, I'd say the hack for this is to create an #ajax submit button as I've shown above, but hide it. Then add some custom JS on the number field, that on blur triggers a click of the hidden submit button.