Problem/Motivation
The problem is that when Stripe is trying to create a payment method Drupal checks in DB (in user__commerce_remote_id table) if the user has a customer_id from Stripe and when it is found in DB it tries to attach that customer to a payment method, but at that point, the customer_id does not exist in Stripe (it was deleted for some reason) and the remaining execution of script was stopped.
/modules/contrib/commerce_stripe/src/Plugin/Commerce/PaymentGateway/Stripe.php
protected function doCreatePaymentMethod(PaymentMethodInterface $payment_method, array $payment_details) {
  $stripe_payment_method_id = $payment_details['stripe_payment_method_id'];
  $owner = $payment_method->getOwner();
  $customer_id = NULL;
  if ($owner && $owner->isAuthenticated()) {
    $customer_id = $this->getRemoteCustomerId($owner); // Here it checks for commerce_remote_id, see the 'getRemoteCustomerId' function below.
  }
  try {
    $stripe_payment_method = PaymentMethod::retrieve($stripe_payment_method_id);
    if ($customer_id) {
      $stripe_payment_method->attach(['customer' => $customer_id]);
      $email = $owner->getEmail();
    }
    // If the user is authenticated, created a Stripe customer to attach the
    // payment method to.
    elseif ($owner && $owner->isAuthenticated()) {
      $email = $owner->getEmail();
      $customer = Customer::create([
        'email' => $email,
        'description' => $this->t('Customer for :mail', [':mail' => $email]),
        'payment_method' => $stripe_payment_method_id,
      ]);
      $customer_id = $customer->id;
      $this->setRemoteCustomerId($owner, $customer_id);
      $owner->save();
    }
    else {
      $email = NULL;
    }
    if ($customer_id && $email) {
      $payment_method_data = [
        'email' => $email,
      ];
      if ($billing_profile = $payment_method->getBillingProfile()) {
        $billing_address = $billing_profile->get('address')->first()->toArray();
        $payment_method_data['address'] = [
          'city' => $billing_address['locality'],
          'country' => $billing_address['country_code'],
          'line1' => $billing_address['address_line1'],
          'line2' => $billing_address['address_line2'],
          'postal_code' => $billing_address['postal_code'],
          'state' => $billing_address['administrative_area'],
        ];
        $payment_method_data['name'] = $billing_address['given_name'] . ' ' . $billing_address['family_name'];
      }
      PaymentMethod::update($stripe_payment_method_id, ['billing_details' => $payment_method_data]);
    }
  }
  catch (ApiErrorException $e) {
    ErrorHelper::handleException($e);
  }
  return $stripe_payment_method->card;
}
/modules/contrib/commerce/modules/payment/src/Plugin/Commerce/PaymentGateway/PaymentGatewayBase.php
public function getRemoteCustomerId(UserInterface $account) {
  $remote_id = NULL;
  if ($account->isAuthenticated()) {
    $provider = $this->parentEntity->id() . '|' . $this->getMode();
    /** @var \Drupal\commerce\Plugin\Field\FieldType\RemoteIdFieldItemListInterface $remote_ids */
    $remote_ids = $account->get('commerce_remote_id');
    $remote_id = $remote_ids->getByProvider($provider);
    // Gateways used to key customer IDs by module name, migrate that data.
    if (!$remote_id) {
      $remote_id = $remote_ids->getByProvider($this->pluginDefinition['provider']);
      if ($remote_id) {
        $remote_ids->setByProvider($this->pluginDefinition['provider'], NULL);
        $remote_ids->setByProvider($provider, $remote_id);
        $account->save();
      }
    }
  }
  return $remote_id;
}
Steps to reproduce
- To have wrong Stripe customer id in db table user__commerce_remote_idon columncommerce_remote_id_remote_id
- Try to make payment
- Observe result
Proposed solution
The solution will be to check if the customer exists in Stripe, if not create a new customer and then continue further.