SendPaymentConfirmation Lambda Function
Quick Reference
- Function Name:
payment3-send-payment-confirmation-${BRANCH} - Handler:
send_confirmation_email.lambda_handler - Runtime: Python 3.13 (Docker Image)
- Trigger: API Gateway (POST /send_confirmation_email)
- Timeout: 60 seconds (default)
- Template.yaml: Lines 662-697
Function Overview
The SendPaymentConfirmation function sends payment confirmation emails to customers after successful payment. It checks if an order is paid before sending the email notification. This function is called via API Gateway and validates payment status before proceeding.
Entry Point
File: functions/processPaidOrder/send_confirmation_email.py
Handler: lambda_handler(event, context)
def lambda_handler(event, context):
body = json.loads(event["body"])
orderId = body["orderId"]
processor = SendConfimationEmail(orderId=orderId)
processor.send_notification()
return {"statusCode": 200, "body": json.dumps({"message": "success"})}
Event Structure
API Gateway Event
Path: POST /send_confirmation_email
Auth: NONE (public endpoint)
Request Body (JSON):
{
"orderId": "492500004152"
}
Example Event:
{
"body": "{\"orderId\": \"492500004152\"}"
}
Response (Success - Order Paid):
{
"statusCode": 200,
"body": "{\"message\": \"success\", \"isPaid\": true}"
}
Response (Success - Order Not Paid):
{
"statusCode": 200,
"body": "{\"message\": \"Email not sent - order is not paid\", \"isPaid\": false}"
}
Response (Error):
{
"statusCode": 500,
"body": "{\"error\": \"error message\"}"
}
Core Classes
SendConfimationEmail
Main processor class for sending payment confirmation emails.
Initialization:
processor = SendConfimationEmail(orderId="492500004152")
Properties:
-
order(cached_property): Retrieves order data from OrderTable@cached_property
def order(self) -> dict:
try:
return next(OrderTable.query(self.orderId)).data
except StopIteration:
raise ValueError(f"Order {self.orderId} not found") -
success(property): Checks if order payment is successful@property
def success(self) -> bool:
if not self.order.get("payment"):
return False
return self.order["payment"]["isPaid"]
Methods:
send_notification(): Sends email notification if order is paiddef send_notification(self):
if not self.success:
print(f"Order {self.orderId} is not paid, skipping email")
return
user_email = self.order.get("shipping", {}).get("shippingEmail")
if not user_email:
print(f"No email found for order {self.orderId}")
return
email_sender = Email(self.order)
email_sender._send_email(user_email)
DynamoDB Tables
OrderTable
Table Name: order-table-dev (shared across branches)
Access Pattern: Query by orderId (hash key)
Schema:
orderId(hash_key): Order identifierdata(JSON): Order data including payment informationpayment.isPaid(boolean): Payment success status
Example Query:
from src.tables.orderTable import OrderTable
try:
order_record = next(OrderTable.query(orderId))
order_data = order_record.data
is_paid = order_data.get("payment", {}).get("isPaid", False)
except StopIteration:
# Order not found
pass
Process Flow
- Receive API Request: Lambda receives POST request with
orderIdin body - Parse Event: Extract
orderIdfrom JSON body - Initialize Processor: Create
SendConfimationEmailinstance - Check Payment Status: Verify
order.payment.isPaidisTrue - Skip if Unpaid: If order is not paid, return early with message
- Extract Email: Get
shipping.shippingEmailfrom order data - Send Email: Use
Emailclass to send confirmation email - Return Success: Return HTTP 200 with success message
Error Handling
- Order Not Found: Raises
ValueErrorif order doesn't exist in OrderTable - No Email Address: Logs warning and returns early if no email found
- Email Send Failure: Exceptions are caught and logged, then re-raised
- Payment Not Completed: Returns early with informative message
Lambda Invocations
Invoked Functions
None - This function is a standalone email sender.
IAM Policies
Required Permissions:
DynamoDBReadPolicyonorder-table-devLambdaInvokePolicyonpayment3-check-status-${BRANCH}(optional, for status verification)SESCrudPolicyon*(for sending emails)SNS:Publishon*(for notifications)DynamoDBCrudPolicyonEmailLogTable(for logging email attempts)
Environment Variables
BRANCH: Deployment branch name (default: "dev")
Dependencies
src.tables.orderTable.OrderTable: Order data accesssrc.notifications.sendEmail.Email: Email sending functionalityfunctools.cached_property: Property cachingdatetime.datetime: Timestamp handlingjson: JSON parsing
Testing
Local Testing:
if __name__ == "__main__":
ORDER_ID = "492500004152"
test_events = {"body": json.dumps({"orderId": ORDER_ID})}
lambda_handler(test_events, {})
Test Cases:
- Order exists and is paid → Email sent successfully
- Order exists but not paid → Early return with message
- Order not found → ValueError raised
- Order has no email → Warning logged, early return
Related Functions
ProcessPaidOrder: Processes paid orders and may trigger email sendingCheckStatus: Verifies payment status (can be invoked for verification)
Notes
- This function only sends emails for paid orders
- Email address is extracted from
order.shipping.shippingEmail - If no email is found, the function returns early without error
- Payment status is determined from
order.payment.isPaidfield - Email sending is handled by the
Emailclass which logs toEmailLogTable