Solution:
Put the SSL/non-SSL redirects before your wordpress rules. You also need rules to not only redirect to HTTPS, but redirect from HTTPS to HTTP:
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/cart/
RewriteCond %{REQUEST_URI} !^/checkout/
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} off
RewriteRule ^(cart|checkout)/ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress