To handle the case where the connection is lost between your server and Stripe's server you'd want to implement idempotency key's this allows you to retry api calls and get the same response back from Stripe as the last time you sent the request with that key.
For the cases where a customer resubmits a form again, you may want to check to see if the customer already exists in your database before retrying the charge / customer creation step, this could more be seen as how to do idempotency between your server and your client as opposed to Stripe.
Personally I like to actually reverse steps 2 and 3, I'll create a customer's account in my database first and then depending on if the charge goes through or not flag it as active or inactive.
Matt