diff --git a/scrapy/mail.py b/scrapy/mail.py
index c11f3898d..237327451 100644
--- a/scrapy/mail.py
+++ b/scrapy/mail.py
@@ -96,10 +96,9 @@ class MailSender:
             rcpts.extend(cc)
             msg["Cc"] = COMMASPACE.join(cc)
 
-        if charset:
-            msg.set_charset(charset)
-
         if attachs:
+            if charset:
+                msg.set_charset(charset)
             msg.attach(MIMEText(body, "plain", charset or "us-ascii"))
             for attach_name, mimetype, f in attachs:
                 part = MIMEBase(*mimetype.split("/"))
@@ -110,7 +109,7 @@ class MailSender:
                 )
                 msg.attach(part)
         else:
-            msg.set_payload(body)
+            msg.set_payload(body, charset)
 
         if _callback:
             _callback(to=to, subject=subject, body=body, cc=cc, attach=attachs, msg=msg)

diff --git a/tests/test_mail.py b/tests/test_mail.py
index 504c78486..2535e58db 100644
--- a/tests/test_mail.py
+++ b/tests/test_mail.py
@@ -111,7 +111,7 @@ class MailSenderTest(unittest.TestCase):
 
         msg = self.catched_msg["msg"]
         self.assertEqual(msg["subject"], subject)
-        self.assertEqual(msg.get_payload(), body)
+        self.assertEqual(msg.get_payload(decode=True).decode("utf-8"), body)
         self.assertEqual(msg.get_charset(), Charset("utf-8"))
         self.assertEqual(msg.get("Content-Type"), 'text/plain; charset="utf-8"')
 

Wrong charset handling in MailSender
Looks like passing `charset='utf-8'` makes a plain text message with `Content-Transfer-Encoding: base64` which then can't be read.

At https://github.com/scrapy/scrapy/blob/5a75b14a5fbbbd37c14aa7317761655ac7706b70/scrapy/mail.py#L81 `set_charset` is called but as the payload is not set yet, the underlying class just sets the headers. When later `set_payload` is called, it doesn't do any encoding, but the `Content-Transfer-Encoding` is already set. Looks like the fix should be passing the encoding to `set_payload` too, like was proposed in #3722 (and `set_charset` may be safe to be removed, not sure about this). Note that we have tests but they don't catch this.

Note also, that all of this seems to be compat code according to the Python docs.
tests/test_mail.py::MailSenderTest::test_send_utf8
tests/test_mail.py::MailSenderTest::test_create_sender_factory_with_host tests/test_mail.py::MailSenderTest::test_send tests/test_mail.py::MailSenderTest::test_send_attach tests/test_mail.py::MailSenderTest::test_send_attach_utf8 tests/test_mail.py::MailSenderTest::test_send_html tests/test_mail.py::MailSenderTest::test_send_single_values_to_and_cc