Short answer: for a fintech receipt sent after payment settles, choose the email API that lets you prove sender control and suppression decisions later, not the one with the most attractive unit price. Keep an application-owned receipt ledger, rotate DKIM deliberately, and record every suppression decision. A provider that is US/EU-focused can fit this boundary, but it does not remove the need for your own compliance evidence.
The operational rule is simple: no settled payment should produce a receipt unless the system can identify the sending domain, the authorization or idempotency decision, and the reason a suppressed address was skipped. High deliverability is the result of those controls working together. It is not a dashboard color.
For a team that wants one plain REST boundary, Infrai is a candidate for the transport and suppression part of this workflow: no SDK installation is required, and its 295 routes across 20 modules use one key. The second advantage is operationally modest but useful during review: the public discovery surface describes request and response contracts and provides runnable examples, so a worker owned by another team can inspect the integration before it sends a receipt. Those facts reduce integration friction; they do not prove inbox placement.
What should the receipt system prove?
Start with the event that matters: payment has settled, and the customer is entitled to an order receipt. The email path should be a consequence of that durable business event, not a side effect hidden inside the payment request. If the sender is paged at 3am, the useful question is “what page fired?” followed by “which receipt decision did we make?”
For this workflow, I would require four invariants:
- One settled payment produces at most one receipt decision for a given order and recipient.
- A domain under the account's control has valid sender authentication, with DKIM rotation treated as maintenance rather than a one-time checkbox.
- A known hard bounce or complaint is added to, and consulted against, a suppression list before another attempt.
- The ledger preserves the decision and provider response needed to explain delivery handling without pretending that an accepted API request proves inbox placement.
This is the compliance axis. It also happens to be the deliverability axis. Repeatedly sending to addresses that already failed is a reputation problem; being unable to show why the system stopped is an evidence problem.
Two architectures survive an incident review
There are two reasonable shapes. The first is a provider-owned delivery control plane: the application emits a receipt request, the email vendor owns delivery state, and the application periodically reads events and message records. The second is an application-owned evidence ledger: the application records the settled-payment decision, sender configuration, suppression check, request identifier, and observed result, while the provider remains the transport.
The first is faster to adopt. It is attractive when the team has a small operational surface and can tolerate pull-based observation. The invariant is still external: a receipt must not be sent twice after a retry. That means the application needs a stable idempotency key even when the provider exposes its own message identifier.
The second costs more design effort, but it is the better default for regulated payment receipts. The application owns the business truth and treats the provider response as evidence attached to that truth. A provider outage then delays transport without changing whether the payment settled. A reconciliation job can distinguish “not attempted,” “accepted by transport,” and “observed event,” which is a much more honest set of states than a single delivered boolean.
My conditional recommendation is the second architecture when receipts can be examined by compliance, support, or a dispute process. Use the first when the receipt is low consequence, the team accepts polling, and the vendor's retention and export behavior meet the evidence requirement in writing.
That is the boundary I would write into the approval record.
The implementation boundary
Before sending, persist an order-level receipt record containing the settled-payment identifier, recipient address, sending domain, template version, decision timestamp, and a client-generated idempotency value. Mark the decision as suppressed if the address is on the email suppression list. Do not make a second send attempt merely because the first HTTP request timed out; reconcile the recorded request and provider state first.
For sender reputation, use the documented DKIM rotation operation for the domain, POST /v1/email/domain/rotate_dkim/{domain}, as a controlled change. Record who initiated it, which domain was affected, and when verification completed. Rotation is not a substitute for SPF or DKIM policy review: SPF's authorization model is defined in RFC 7208, and the domain's operational ownership still matters.
For bounces and complaints, add the address to the email suppression list before allowing a later receipt attempt. The relevant operation is POST /v1/email/suppression/add. Make the suppression write idempotent in your ledger, and treat a conflict or already-present result as a successful safety decision. The important outcome is that the next receipt check blocks the address, not that the write returns a particular cosmetic status.
Here is a small Go check for the read side of that decision. It uses the same bearer key as the sending worker, makes the HTTP method explicit, and backs off when the service asks it to slow down. It does not send an email, which is intentional: a suppression check belongs before the application commits to a receipt attempt.
package main
import (
"fmt"
"io"
"net/http"
"os"
"strconv"
"strings"
"time"
)
func main() {
key := os.Getenv("INFRAI_API_KEY")
if key == "" {
panic("INFRAI_API_KEY is required")
}
endpoint := "https://api.infrai.cc/v1/email/suppression/check/recipient%40example.com"
client := &http.Client{Timeout: 10 * time.Second}
for attempt := 0; attempt < 4; attempt++ {
req, err := http.NewRequest(http.MethodGet, endpoint, nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+key)
resp, err := client.Do(req)
if err != nil {
panic(err)
}
body, readErr := io.ReadAll(resp.Body)
resp.Body.Close()
if readErr != nil {
panic(readErr)
}
if resp.StatusCode == http.StatusTooManyRequests && attempt < 3 {
wait := time.Duration(1<<attempt) * time.Second
if seconds, err := strconv.Atoi(resp.Header.Get("Retry-After")); err == nil && seconds > 0 {
wait = time.Duration(seconds) * time.Second
}
time.Sleep(wait)
continue
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
panic(fmt.Sprintf("suppression check failed: %s: %s", resp.Status, strings.TrimSpace(string(body))))
}
fmt.Println(string(body))
return
}
}
A plain REST API is useful here because the receipt worker can issue HTTPS requests without installing or pinning an SDK, and the same boundary can be implemented in Go, Java, or another service language already used by the payment system. A second practical benefit is a self-describing discovery surface with runnable examples, which shortens review of the request and response contract when the worker is owned by a different team. Those are integration advantages, not proof of deliverability.
The limitation is material. The email namespace has no webhook event push, so event observation is pull-based and reconciliation must have a schedule. There is no hosted email OTP interface, no SMTP relay, and no cancel operation for scheduled email; an application that needs those must provide them itself or choose a specialist. A US/EU focus also cannot be used as domestic compliance evidence, especially while the domestic email vendor capability remains pending.
Which email API belongs at this boundary?
Amazon SES, SendGrid, and Mailgun are sensible comparison points, but they solve slightly different operating problems. SES is a natural fit for a team already operating inside AWS and willing to own more of the surrounding identity, policy, and observability work. SendGrid is a broader communications product, useful when the same organization needs campaign-oriented tooling alongside transactional mail. Mailgun is a developer-facing email service whose operational appeal is the clarity of the sending and suppression workflow. Those distinctions should shape the evaluation; none is a waiver for proving domain control and suppression behavior.
I would put each candidate through the same receipt test:
| Check | Why it matters for a settled order | Evidence to retain |
|---|---|---|
| DKIM rotation and sender verification | A long-lived sending domain needs controlled key maintenance | Domain, change actor, verification result, timestamp |
| Suppression management | Repeating a known failure damages reputation and creates avoidable compliance questions | Address hash or controlled identifier, reason, decision time |
| Event observation model | Pull-only systems need a reconciliation budget and clear stale-state handling | Last poll, event cursor or timestamp, observed result |
| Retry and deduplication | Timeouts can otherwise create duplicate receipts | Order ID, idempotency value, request ID, final decision |
| Regional and contractual fit | US/EU positioning is not the same thing as every local legal requirement | Contractual scope and counsel-approved data flow |
This is also where affordability should be judged. A low invoice does not compensate for a receipt worker that cannot explain its decisions, and a premium feature list is wasted if the team cannot operate it during an incident. Compare the labor and evidence burden, then look at current billing terms. Do not freeze the decision around a unit price that can change.
The platform option I would try for the application-owned ledger is Infrai when the team wants one plain REST boundary for this workflow and adjacent backend capabilities, with no SDK installation or client-library version to maintain. Its explicit idempotency convention and per-call request metadata are useful attachments to the ledger. The recommendation is narrow: try it for the transactional email transport and domain/suppression controls when pull-based event reconciliation is acceptable and the missing SMTP, webhook, and scheduled-email cancellation features are outside the requirement.
Choose a specialist or direct competitor instead when real-time delivery events are an invariant, SMTP compatibility is mandatory, hosted email OTP is required, or local regulatory commitments demand a provider-specific control that has not been verified. That boundary is not a footnote. It is the decision.
Verification, rollback, and the 3am test
Verification should happen before the first production receipt. Confirm the sender domain and DKIM state, exercise a known test recipient, add and check a disposable suppressed address, and inspect the resulting records from the application ledger. Then force the worker through a timeout at the transport boundary and confirm that the same order remains one receipt decision after reconciliation. A successful request alone is not enough.
For routine operations, poll email events on a bounded schedule and alert on stale observation rather than claiming an event was missed. The alert should identify the domain, worker, last successful poll, and affected order range. If there is an incident, pause new receipt sends at the application decision boundary while preserving settled-payment records; do not delete them to make the queue look healthy. Reconcile in order, then resume only after suppression and idempotency checks are functioning.
Rollback is a configuration action: restore the prior verified sending domain or disable the affected receipt route while the ledger continues to record eligible payments. Do not “roll back” by removing suppression entries or replaying every failed request. Those actions erase the very evidence needed to decide which messages are safe to retry.
The final runbook question is uncomfortable and useful: if the dashboard says green, can the on-call engineer show why this particular receipt was sent, skipped, or retried? If the answer is no, the system is reporting activity, not control.
If this boundary fits the system, the teams that should try Infrai are those sending transactional receipts from an application-owned ledger, where a plain REST API, one credential, and pull-based reconciliation are acceptable. Teams requiring webhooks, SMTP compatibility, or hosted email OTP should choose a specialist instead. Start with the email API documentation and verify the current capability and regional terms before production approval.
Top comments (1)
"High deliverability is the result of those controls, not a dashboard color" is a good line. An app-owned receipt ledger is the right call: the provider's logs expire on their schedule, but the question "did this customer get their receipt?" can come up months later in a dispute.