Amazon SES for SAP Commerce Email: Setup, Deliverability, and Closing the Bounce Loop
Running Amazon SES behind SAP Commerce: the IAM, SNS, and SQS wiring, the SPF/DKIM/DMARC trinity, bounce handling, and testing with the mailbox simulator.
Marcus Lindholm
SAP Commerce Integration Specialist
OCC and Integration APIs, SAP Integration Suite, S/4HANA and ERP integration, and asynchronous messaging.
SAP Commerce does not ship a mail server. As the architecture guide notes, the platform is an SMTP client: it composes emails through the WCMS module and Apache Commons Email, then hands them to a transport you provide. Amazon SES is one of the most common transports teams choose, and this guide is the concrete build: the AWS-side plumbing, the deliverability configuration that separates the inbox from the spam folder, and the feedback loop that turns bounces and complaints from silent failures into managed data. The transactional email guide covers the Commerce-side integration and templating in general; this guide is the SES specifics that make that integration actually reach customers.
The Architecture: More Than "Send an Email"#
A production SES integration is not a single API call; it is a send path plus a feedback path, and the feedback path is the half teams forget until their sender reputation collapses:
- Send: Commerce (or the middleware/service fronting it) calls SES over HTTPS to send the message; SES accepts it and returns a message ID you should log against the send event, because that ID is your correlation key for everything that follows.
- Delivery: SES relays to the recipient's ISP. Success is silent (no news is good news). Failure bounces.
- Bounce/complaint capture: SES publishes bounce and complaint events to an SNS topic.
- Queue: SNS pushes those notifications to an SQS queue for asynchronous, durable consumption.
- Feedback processing: a consumer (a scheduled job in Commerce, or a small service) pulls from SQS and acts: suppress hard-bounced addresses, record complaints, update send-eligibility.
The send path is easy; the SNS-to-SQS-to-consumer feedback path is what keeps you off blocklists, because ignoring bounces and complaints is exactly how a sending domain gets throttled or banned.
AWS-Side Setup, Step by Step#
IAM user (or role) for the API caller. Create a dedicated principal with programmatic access, scoped to SES send and SQS read. The managed policies AmazonSESFullAccess and AmazonSQSFullAccess get you running, but least privilege (a custom policy granting only ses:SendEmail/ses:SendRawEmail and the specific queue's sqs:ReceiveMessage/sqs:DeleteMessage) is the right production posture, per the security hardening guide. One correction worth making before it costs you a day: if Commerce reaches SES over SMTP, the IAM Access Key ID and Secret are not the credentials you configure. SES SMTP credentials are a separate pair, generated per Region, and the SMTP password is derived from the secret access key by an HMAC algorithm rather than equal to it. Generate them in the SES console and treat them as their own secret.
SNS topic for bounce and complaint notifications: create it with a meaningful name before touching SES, because you will attach it to the sender identity.
SQS queue subscribed to that topic. A standard queue via quick-create is fine; the important part is the subscription (Queue Actions → Subscribe to SNS Topic) so notifications flow topic → queue. Record the queue path (the tail of the queue URL, e.g. /NNNNNNNNNNNN/queue-name), which the consumer needs.
Sender identity verification in SES: verify either a domain (then any address on it can send, via a DNS TXT verification record) or a single email address (SES sends a confirmation mail). Domain verification is the production choice; address verification suits early testing. Attach the SNS topic to the identity so bounces and complaints for its mail become notifications.
Leave the SES sandbox. New SES accounts are sandboxed: they can only send to verified addresses, and the default quotas are 200 messages per 24 hours at 1 message per second. Request production access before you need it, and request a sending quota sized to your peak (the high-traffic guide's order-confirmation surge is a real number: a Black Friday's worth of confirmations can dwarf your daily average). The sandbox rate limit in particular is below what a single order-confirmation batch produces.
The Commerce Side: Four Properties, Not an SDK#
Here is where teams over-build. SAP Commerce is already an SMTP client: DefaultEmailService in acceleratorservices hands the rendered message down to the platform's MailUtils, which wraps Apache Commons Email over the Java Mail API. SES exposes an SMTP interface. So the send path needs no AWS SDK and no code at all: it needs the same properties any other transport needs, pointed at the Region's SES SMTP endpoint.
mail.smtp.server=email-smtp.eu-central-1.amazonaws.com
mail.smtp.port=587
mail.smtp.user=<ses-smtp-username>
mail.smtp.password=<ses-smtp-password>
mail.from=orders@shop.acme.com
mail.replyto=support@acme.com
Three facts govern that block:
- Port 587 is the STARTTLS port. SES refuses unencrypted connections entirely. STARTTLS is offered on 25, 587, and 2587; TLS Wrapper on 465 and 2465. Port 25 is throttled on EC2 by default, so 587 is the sane default.
- The endpoint is Region-specific, and so are the credentials. Sending from two Regions means two credential pairs, which is one more reason the per-environment separation below is not optional.
- These properties belong in Cloud Portal service configuration, per environment, not in the repository. The password is a secret, and CCv2 property personas are the mechanism that keeps the staging value out of production (the first-deployment guide covers the wiring).
Switching to the SES HTTPS API later is a real option, and it is what buys you message tagging and configuration sets. It is also a custom send strategy plus an SDK dependency in the platform. Start on SMTP, go live, and let a concrete requirement pull you to the API. The transactional email guide covers that swap.
Deliverability: The Trinity That Decides the Inbox#
Getting SES to send is trivial; getting mail delivered to the inbox is the actual work, and it lives almost entirely in DNS. Three records, all mandatory for a serious sender:
- SPF (Sender Policy Framework): a DNS record authorizing SES to send for your domain. Without it, receivers treat your mail as potentially forged, and reputation suffers.
- DKIM (DomainKeys Identified Mail): cryptographic signing of your messages via DNS-published keys (SES generates them; you add the records, or use Easy DKIM). DKIM proves the mail was not tampered with and is authorized, and it is the strongest single deliverability signal.
- DMARC (Domain-based Message Authentication, Reporting and Conformance): a policy record built on SPF and DKIM that tells receivers what to do with mail that fails authentication (none/quarantine/reject) and where to send aggregate reports. Start at
p=nonewith reporting to observe, then tighten toquarantineandrejectas you confirm all legitimate mail authenticates. DMARC is increasingly a requirement, not a nicety: major mailbox providers now demand authenticated mail from bulk senders, and unauthenticated commerce mail is quietly filtered.
The commerce-specific trap: transactional mail (order confirmations, password resets, shipping notices) is high-stakes deliverability. A promotional email in spam is a lost impression; a password reset in spam is a support ticket and an abandoned account. Authenticate ruthlessly, and monitor the DMARC reports.
Bounce and Complaint Processing: The Half Nobody Builds#
The feedback consumer is what separates a durable sender from a doomed one:
- Hard bounces (address does not exist): suppress the address immediately. Continuing to send to known-dead addresses is the fastest way to tank your reputation, and SES will start penalizing you for a high bounce rate.
- Soft bounces (temporary: mailbox full, server down): retryable, but with limits; repeated soft bounces become effective hard bounces.
- Complaints (recipient marked it spam): the most damaging signal. Suppress the address from non-transactional mail immediately, and investigate a complaint-rate spike as a content or consent problem (are you mailing people who did not opt in? the data protection and unified profile guides' consent discipline is deliverability infrastructure, not just compliance).
- Correlate to the send: using the SES message ID logged at send time, tie each feedback event back to the campaign, template, or transactional flow that produced it, so you can see which mail generates bounces and complaints.
In SAP Commerce this consumer is naturally a cronjob (the cronjobs guide) polling SQS, or a small side-by-side service (the side-by-side guide) if you prefer to keep the AWS SDK out of the platform. Inside the platform it is the standard three items: a ServicelayerJob pointing at your performable bean, a CronJob holding the configuration, and a Trigger carrying the schedule.
INSERT_UPDATE ServicelayerJob; code[unique=true] ; springId
; sesFeedbackJob ; sesFeedbackJobPerformable
INSERT_UPDATE CronJob; code[unique=true] ; job(code) ; nodeGroup ; sessionLanguage(isocode)
; sesFeedbackCronJob ; sesFeedbackJob ; integration ; en
INSERT_UPDATE Trigger; cronJob(code)[unique=true]; cronExpression
; sesFeedbackCronJob ; 0 */5 * * * ?
The nodeGroup matters more than the schedule. Pin the job to the integration group so it runs on backgroundProcessing nodes and never competes with storefront request threads. Either way the consumer needs the freshness monitoring of the integration alerting guide: a feedback consumer that silently stops means bounces accumulate unseen, which is a reputation incident in slow motion. Alert on the job's result state and on the age of the last processed message, not on whether the job exists.
Environments: Do Not Share a Queue#
The one architecture mistake with lasting consequences: connecting quality and production to the same SQS queue. Queues are destructive reads (a message picked up by one consumer is gone), so two environments on one queue steal each other's feedback, and you get non-deterministic bounce processing. The clean setup is separate SES accounts (or at least separate SNS topics and SQS queues) per environment. If you must share an SES account, give each environment its own queue and accept that non-production will not receive the shared feedback, rather than letting environments interfere.
Testing Without Burning Your Reputation#
SES provides the mailbox simulator: special recipient addresses that deterministically produce a successful delivery, a hard bounce, a complaint, or a soft bounce, without touching real inboxes or counting against your reputation and quota. Use it to prove the whole path before real mail flows. Minimum test matrix:
- Successful send: mail arrives, the send event and message ID are logged.
- Hard bounce: the simulator's bounce address produces an SNS notification, the SQS consumer processes it, the address is suppressed.
- Complaint: the complaint address flows through to suppression.
- Soft bounce: retry behavior is correct and bounded.
Testing the feedback path is the point; anyone can verify a happy-path send, and almost nobody verifies that a hard bounce actually results in suppression until a reputation problem forces the investigation.
Checklist#
- Dedicated IAM principal, least-privilege; SES SMTP credentials generated separately from the IAM access key
-
mail.smtp.*pointed at the Region's SES SMTP endpoint on port 587, set per environment in Cloud Portal, never committed - SNS topic + SQS queue created and subscribed; queue path recorded for the consumer
- Sender domain verified; SNS topic attached to the identity; out of the SES sandbox with adequate quota for peak
- SPF, DKIM, and DMARC all published; DMARC ramped none → quarantine → reject with reports monitored
- Bounce/complaint consumer built and monitored (freshness alert); hard bounces and complaints suppress; sends correlated by message ID
- Separate accounts or at least separate queues per environment; no shared destructive-read queue
- Full path tested with the mailbox simulator, feedback processing included, before real mail
SES makes sending cheap and easy to grow, which is exactly why the discipline moves to deliverability and feedback. The estates whose order confirmations reliably reach the inbox are not the ones that configured SES fastest; they are the ones that authenticated their domain properly and actually built the consumer that listens when mail bounces.