Magento订单邮件添加客户自定义属性CC地址失败求助
Let’s walk through resolving this issue step by step, since you’ve already made progress but hit a roadblock. First, a quick recap of what you’re trying to do and where you’re stuck:
- Goal: Send shipment (and related order) emails to a CC email address stored in a customer custom attribute
- What you’ve done: Rewrote
\Magento\Sales\Model\Order\Email\SenderBuilder,\Magento\Sales\Model\Order\Email\Sender\ShipmentSender, and addedgetOrderCustomerId()/setOrderCustomerId()methods to\Magento\Sales\Model\Order\Email\Container\ShipmentIdentityvia rewrite - Current problem: Even after fixing the fatal error about the undefined method, CC emails still aren’t being sent
Common Issues to Check & Fixes
1. Confirm Your ShipmentIdentity Rewrite is Active
First, double-check that Magento is actually using your rewritten ShipmentIdentity class. Rewrites often fail to load due to:
- Misconfigured
di.xml - Uncleared cache
- Missing module dependencies
In your module’s etc/frontend/di.xml (or etc/di.xml if it applies to all areas), verify the preference is correctly set:
<preference for="Magento\Sales\Model\Order\Email\Container\ShipmentIdentity" type="YourVendor\YourModule\Model\Order\Email\Container\ShipmentIdentity" />
Then run these commands to refresh cache and regenerate classes:
bin/magento cache:clean bin/magento setup:di:compile
You can also verify the rewrite is active by running bin/magento info:modules:rewrites and checking for your class.
2. Ensure ShipmentSender Properly Passes Data to Identity & SenderBuilder
In your custom ShipmentSender, you need to:
- Set the order’s customer ID on the
ShipmentIdentitycontainer - Fetch the CC email from the customer’s custom attribute
- Pass that CC email to the
SenderBuilder
Here’s a snippet of how that should look (make sure to inject Magento\Customer\Api\CustomerRepositoryInterface into your class):
public function send(ShipmentInterface $shipment, $forceSyncMode = false) { // ... existing code ... $order = $shipment->getOrder(); // Set customer ID on the identity container $this->shipmentIdentity->setOrderCustomerId($order->getCustomerId()); // Fetch the customer's custom CC attribute try { $customer = $this->customerRepository->getById($order->getCustomerId()); $ccEmail = $customer->getCustomAttribute('your_cc_attribute_code')?->getValue(); if ($ccEmail && filter_var($ccEmail, FILTER_VALIDATE_EMAIL)) { // Pass CC to SenderBuilder $this->senderBuilder->addCc($ccEmail); } } catch (\Exception $e) { $this->logger->error('Failed to fetch customer CC email: ' . $e->getMessage()); } // ... existing send logic ... }
3. Update SenderBuilder to Handle CC Addresses
Your rewritten SenderBuilder needs to actually include the CC addresses when building the email transport. Add a property to store CCs, a method to add them, then use them in the send() method:
class SenderBuilder extends \Magento\Sales\Model\Order\Email\SenderBuilder { private array $ccAddresses = []; public function addCc(string $email, string $name = ''): void { $this->ccAddresses[] = ['email' => $email, 'name' => $name]; } public function send() { $this->configureEmailTemplate(); $transportBuilder = $this->transportBuilder ->setTemplateIdentifier($this->templateContainer->getTemplateId()) ->setTemplateOptions($this->templateContainer->getTemplateOptions()) ->setTemplateVars($this->templateContainer->getTemplateVars()) ->setFrom($this->identityContainer->getEmailIdentity()) ->addTo($this->identityContainer->getCustomerEmail(), $this->identityContainer->getCustomerName()); // Add all CC addresses foreach ($this->ccAddresses as $cc) { $transportBuilder->addCc($cc['email'], $cc['name']); } $transport = $transportBuilder->getTransport(); $transport->sendMessage(); } }
4. Debug the Flow to Find Breakpoints
If it’s still not working, add debug logs to trace where the process fails:
- In
ShipmentIdentity’ssetOrderCustomerId()andgetOrderCustomerId()to confirm they’re being called - In
ShipmentSenderto check if the CC email is being fetched correctly - In
SenderBuilderto verify the CC addresses are added to the transport
Example log line (inject Psr\Log\LoggerInterface into your classes):
$this->logger->debug('Fetched CC email for customer ' . $order->getCustomerId() . ': ' . $ccEmail);
Check var/log/debug.log after triggering a shipment email to see what’s happening.
5. Verify the Customer Custom Attribute is Configured Correctly
Make sure your customer attribute:
- Has a valid email value for the test customer you’re using
- Is set to Visible (in the attribute settings) so it’s accessible via the API
- Is assigned to the correct customer attribute set
内容的提问来源于stack exchange,提问作者Rahul

