Here's how we did this type of thing. The site uses the following checkout sequence, but using EE custom member fields and freemember rather than Profile Edit.
View Basket > Add customer details > Checkout confirm > Payment Gateway > Confirmation - with option to register
We've setup the member fields, giving them the same short names as the customer fields we've used in the orders channel. So our customer-details page looks like this:
{exp:cartthrob:save_customer_info_form
id="customer-details-form"
name="customer-details"
class="form-stacked"
required="first_name|last_name|address|city|state|zip|phone"
return="checkout/confirmation"
}
<input type="hidden" name="country_code" value="GBR">
<input type="hidden" name="currency_code" value="GBP">
<div class="billing-details-fields">
<fieldset class="customer-details">
<h3>Your details</h3>
<p class="form-left-left">
<label for="first_name">First name</label><br>
<input type="text" name="first_name" id="first_name" placeholder="eg. John" {if logged_in}value="{first_name}"{/if}>
</p>
<p class="form-left-right">
<label for="last_name">Last name</label><br>
<input type="text" name="last_name" id="last_name" placeholder="eg. Smith" {if logged_in}value="{last_name}"{/if}>
</p>
[...]
{/exp:cartthrob:save_customer_info_form}
The confirmation page literally outputs the cart table again with final totals for shipping, tax etc. The customer then goes off to pay off-site and returns to a success/fail page with the result of the transaction. Having collected all the customer details, we then ask them if they want to register (assuming they're not registered/logged out) - all they need to do is choose a password. We then use freemember to add their details into the member fields using hidden form fields with the values from the values saved to Cart Throb's cookies in the previous page.
{if logged_out}
{exp:low_variables:parse var="lv_create_account"}
<h2>{register_title}</h2>
{content}
{/exp:low_variables:parse}
{exp:freemember:register return="checkout/complete" error_handling="inline" error_delimiters='<span class="error">|</span>'}
<input type="hidden" name="country_code" value="GBR">
<input type="hidden" name="currency_code" value="GBP">
<input type="hidden" name="first_name" id="first_name" value="{first_name}">
<input type="hidden" name="last_name" id="last_name" value="{last_name}">
<input type="hidden" name="address" id="address" value="{address}">
<input type="hidden" name="company" id="company" value="{company}">
<input type="hidden" name="address2" id="address2" value="{address2}">
<input type="hidden" name="city" id="city" value="{city}">
<input type="hidden" name="state" id="state" value="{state}">
<input type="hidden" name="zip" id="zip" value="{zip}">
<input type="hidden" name="shipping_company" id="shipping_company" value="{shipping_company}">
<input type="hidden" name="phone" id="phone" value="{phone}">
<input type="hidden" name="order_customer_mobile" id="order_customer_mobile" value="{custom_data:order_customer_mobile}">
<input type="hidden" name="email" id="email" value="{email_address}">
<input type="hidden" name="use_billing_info" value="{use_billing_info}">
<input type="hidden" name="shipping_first_name" id="shipping_first_name" value="{shipping_first_name}">
<input type="hidden" name="shipping_last_name" id="shipping_last_name" value="{shipping_last_name}">
<input type="hidden" name="shipping_address" id="shipping_address" value="{shipping_address}">
<input type="hidden" name="shipping_address2" id="shipping_address2" value="{shipping_address2}">
<input type="hidden" name="shipping_city" id="shipping_city" value="{shipping_city}">
<input type="hidden" name="shipping_state" id="shipping_state" value="{shipping_state}">
<input type="hidden" name="shipping_zip" id="shipping_zip" value="{shipping_zip}">
<input type="hidden" name="shipping_phone" id="shipping_phone" value="{custom_data:shipping_phone}">
<input type="hidden" name="shipping_customer_mobile" id="shipping_customer_mobile" value="{custom_data:shipping_customer_mobile}">
<p>Choose a password to create your account.</p>
<p>
<label for="password">Password</label><br />
{field:password}<br />
{error:password}
</p>
<p>
<label for="password_confirm">Confirm Password</label><br />
{field:password_confirm}<br />
{error:password_confirm}
</p>
<p>
<input type="submit" value="Submit" class="big-btn">
</p>
{/exp:freemember:register}
{/if}
I liked this approach because it took away the registration question from the checkout process, and invited it once the transaction was complete.
Hope this helps!