This guidance demonstrates how to deploy a comprehensive Procure-to-Pay (P2P) and Order-to-Cash (OTC) system on AWS with AI-powered invoice processing, exception handling, and multi-modal communication capabilities. The solution addresses the challenge of automating invoice validation through 2-way and 3-way matching, exception management, and secure communication workflows using AWS managed services.
This guidance provides two architectural approaches to meet different organizational needs:
Strands Agent Architecture - Ideal for organizations that need:
- Custom conversational AI agents with fine-grained control over agent behavior
- Flexible integration with existing web applications and custom UIs
- Direct natural language query processing for invoice exceptions
- Developer-centric workflows with programmatic access to agent capabilities
- Custom authentication flows and API integrations
Quick Suite Architecture - Best suited for organizations that require:
- Low-code/no-code workflow automation with visual interface
- Pre-built integration patterns with enterprise SSO (Amazon Cognito)
- Automated exception resolution recommendations with minimal development
- Business user-friendly interfaces for financial analysts and AP/AR teams
- Rapid deployment with managed workflow orchestration
Both architectures leverage the same core AWS services (AWS Lambda, Amazon DynamoDB, Amazon SNS, Amazon Bedrock Knowledge Base) and can be deployed independently or together based on your use case.
- Strands Agent Gateway - AI-powered conversational agent built with Strands framework and deployed on AWS Bedrock AgentCore
- Invoice Catalog Service - AWS Lambda-based P2P exception handling system with comprehensive data management
- OAuth SNS Email API - OAuth-secured REST API for sending email notifications via Amazon SNS
- Quick Suite Integration - Low-code workflow platform for automated exception resolution
- Bedrock Knowledge Base - Vector storage using Amazon Aurora PostgreSQL (with pgvector extension) as a custom data source, with Amazon S3 document storage for contextual invoice retrieval
Below is the architecture model for the P2P system using Strands Agents on AWS.

Below is the architecture model for the P2P system using Quick Suite Agents on AWS.

Below is the architecture model for the OTC system using Strands Agents on AWS.

You are responsible for the cost of the AWS services used while running this Guidance.
Below is an estimated cost breakdown for processing 100 exception requests per month in the US East (N. Virginia) us-east-1 region with an estimated monthly total of $350.09. Costs calculated using AWS Pricing Calculator methodology. Actual costs will vary based on usage patterns, data volume, and specific configuration choices.
Scenario: Monthly processing of 100 invoice exceptions with the following usage patterns:
- 5 agent interactions per exception (500 total interactions)
- 5 email notifications per exception (500 total emails)
- 5 AWS Quick Suite Professional accounts + 1 Enterprise account
- 15 minutes per agent session
| AWS Service | Dimensions | Monthly Cost [USD] |
|---|---|---|
| AWS Lambda (Invoice Catalog) | 500 requests, 1024 MB memory, 3 sec avg duration | $0.03 |
| AWS Lambda (OAuth Email Publisher) | 500 requests, 512 MB memory, 1 sec avg duration | $0.01 |
| Amazon DynamoDB (On-Demand) | 100 GB storage, 1,000 write request units, 2,000 read request units | $25.00 |
| Amazon SNS | 500 email notifications | $0.00 |
| Amazon SQS | 500 requests | $0.00 |
| Amazon Cognito | 700 monthly active users | $0.00 |
| AWS Bedrock | Anthropic Claude 3.5 Sonnet - 50 requests per minute | $12.96 |
| AWS Bedrock Runtime | 500 Agent Sessions, 15 minute interactions | $59.05 |
| AWS Bedrock Gateway | 500 Agent Sessions, 10 tools, 10 tool invocations per session | $0.15 |
| AWS Bedrock Memory | 500 Agent Sessions, 15 avg number of turns, 15 minute interactions, 5 GB avg session memory | $4.14 |
| Amazon Bedrock Knowledge Base | 500 queries, 5M tokens retrieved | $0.50 |
| Amazon Aurora | db.r8g.large instance, 8 hours a day, 100 GB | $77.69 |
| Amazon S3 | Standard Tier, 1000 GB storage, 1,000 PUT requests, 5,000 GET requests | $23.01 |
| Amazon CloudWatch Logs | 10 GB ingested, 10 GB storage (Amazon S3) | $7.55 |
| Amazon Quick Suite | 5 Professional Accounts | $100.00 |
| Amazon Quick Suite | 1 Enterprise Account | $40.00 |
| Total | $350.09 |
We recommend creating a Budget through AWS Cost Explorer to help manage costs. Prices are subject to change. For full details, refer to the pricing webpage for each AWS service used in this Guidance.
In order to be able to run this guidance you need to have the following:
- AWS CLI installed and configured
- AWS SAM CLI version 1.145.2+
- Python 3.12+
- Docker/Podman
- UV package manager
We recommend using AWS CloudShell to quickly set up an environment that already has the credentials and command line tools you'll need to get started. The AWS CloudShell Console already has credentials to your AWS account, the AWS CLI, and Python installed. If you're not using CloudShell, make sure you have these installed in your local environment before continuing.
This guidance can be deployed in any AWS region that supports the required services (AWS Lambda, Amazon DynamoDB, Amazon API Gateway, AWS SNS, AWS Cognito, and Amazon Bedrock). Verify service availability in your target region before deployment.
This system uses OAuth 2.0 for secure API access. You will need:
- An AWS Cognito User Pool for OAuth authentication
- A Cognito App Client configured with client credentials flow
- Required OAuth scope:
email-api/send
The deployment requires IAM permissions to create and manage the following resources:
- Lambda functions and execution roles
- DynamoDB tables
- API Gateway REST APIs
- SNS topics and subscriptions
- SQS queues
- Cognito User Pools and App Clients
- Bedrock AgentCore runtimes
- S3 buckets and bucket policies
- KMS keys for encryption
- CloudWatch Logs and X-Ray tracing
- IAM roles and policies
Ensure your AWS account user or role has sufficient permissions to create these resources, or work with your IT services team to provision the required IAM resources.
Before deploying the main infrastructure, you must provision an Amazon Bedrock Knowledge Base to enable user queries to retrieve relevant information from data sources.
-
Amazon Aurora PostgreSQL with pgvector
- Create an Aurora cluster with PostgreSQL 15.5 or later
- Enable the pgvector extension for vector similarity search
- Note the cluster endpoint and credentials
-
Amazon S3 Bucket
- Create an S3 bucket for storing SOP documents (PDFs, text files, etc.)
- Upload your exception handling procedures and guidelines
- Enable versioning and encryption at rest
-
Amazon Bedrock Knowledge Base
- Create a knowledge base using the Aurora PostgreSQL cluster as the vector store
- Configure the S3 bucket as the data source
- Select an embedding model (e.g., Amazon Titan Embeddings G1 - Text)
- Sync the knowledge base to ingest documents from S3
- Note the Knowledge Base ID (format:
XXXXXXXXXX)
Configuration Steps:
After provisioning the knowledge base, update the following configuration files with your Knowledge Base ID:
-
Invoice Catalog Lambda Configuration (
deployment/invoice-catalog/template.yaml):# Line 35: Update the IAM policy resource ARN Resource: - "arn:aws:bedrock:region:accountid:knowledge-base/XXXXXXXXXX" # Line 44: Update the environment variable Environment: Variables: KNOWLEDGE_BASE_ID: "XXXXXXXXXX"
Replace
us-east-1with your deployment region andXXXXXXXXXXwith your actual Knowledge Base ID. -
CloudFormation Outputs (
deployment/invoice-catalog/template.yaml):# Line 88: Update the output value KnowledgeBaseId: Value: "XXXXXXXXXX"
Finding Your Knowledge Base ID:
You can retrieve your Knowledge Base ID using the AWS CLI:
aws bedrock-agent list-knowledge-bases --region <region>Or from the AWS Console:
- Navigate to Amazon Bedrock > Knowledge bases
- Select your knowledge base
- Copy the Knowledge Base ID from the details page
Do not proceed with these steps without first implementing the necessary knowledge base requirements as stated above.
-
Clone the repository
git clone <repository-url> cd procure-to-pay-exceptions
-
Deploy Invoice Catalog Service
cd deployment/invoice-catalog sam build sam deploy --guided # Seed test data python seed_data.py # Base dataset for testing
-
Deploy OAuth Email API
cd deployment/oauth-sns-email-api # Verify SAM CLI version (1.145.2+) sam --version sam build sam deploy --resolve-s3 --capabilities CAPABILITY_IAM \ --parameter-overrides "CognitoUserPoolId=<YOUR_USER_POOL_ID> CognitoAppClientId=<YOUR_APP_CLIENT_ID> EmailRecipient=<YOUR_EMAIL>" # Enable X-Ray tracing (post-deployment) API_ID=$(aws cloudformation describe-stacks --stack-name oauth-sns-email-api --region us-west-2 --query 'Stacks[0].Outputs[?OutputKey==`ApiId`].OutputValue' --output text) aws apigateway update-stage --rest-api-id $API_ID --stage-name Prod --patch-operations '[{"op":"replace","path":"/tracingEnabled","value":"true"}]' --region <YOUR_REGION>
-
Deploy Strands Agent
- Edit etc/environment.sh with your values
cd deployment/strands-agent-procurepay-gw make infrastructure make podman make agentcore.create -
Configure Amazon QuickSight Analytics (Optional) Apply Amazon S3 bucket policy for Amazon QuickSight access
- Replace YOUR_BUCKET_NAME in quicksight-bucket-policy.json
- Apply policy to your S3 bucket via AWS Console or CLI
aws s3api put-bucket-policy --bucket YOUR_BUCKET_NAME --policy file://quicksight-bucket-policy.json
Once your system has been deployed and provisioned, you can interact with the P2P system through the following methods:
The system supports the following invoice processing capabilities:
- 2-Way Matching: Invoice ↔ Purchase Order validation
- 3-Way Matching: Invoice ↔ PO ↔ Goods Receipt validation
- Exception Management: Automated exception creation and tracking
- Status Checking: Real-time invoice status with full context
check_invoice_status()- Get current invoice status with full detailsextract_invoice_data()- Get invoice details from DynamoDBget_purchase_order()- Retrieve PO details from DynamoDBvalidate_goods_receipt()- Get goods receipt details from DynamoDBget_vendor_info()- Get vendor information from DynamoDBcreate_exception_case()- Create exception tracking caseslist_open_exceptions()- List all open P2P exceptionsget_exception()- Get details for a specific exception
1. IAM Authentication (AgentCore)
make agentcore.invoke2. JWT Bearer Token (OAuth)
# Get token from Cognito
curl -X POST "https://<YOUR_COGNITO_DOMAIN>.auth.<YOUR_AWS_REGION>.amazoncognito.com/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=<YOUR_APP_CLIENT_ID>&client_secret=<YOUR_CLIENT_SECRET>&scope=email-api/send"
# Use token with escaped agent ARN
curl -X POST "${BEDROCK_AGENT_CORE_ENDPOINT_URL}/runtimes/${ESCAPED_AGENT_ARN}/invocations?qualifier=DEFAULT" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"prompt": "Show me the list of exceptions in Resolved status."}'Seed Test Data
Before testing the P2P system, populate DynamoDB with test data:
cd deployment/invoice-catalog
python seed_data.pyThis script generates comprehensive P2P test data including:
- 10 vendors with contact information and payment terms
- 15 purchase orders with line-item details
- 12 goods receipts linked to POs for 3-way matching
- 30 invoices with various matching scenarios (perfect match, price variance, quantity discrepancy)
- ~25 exception cases across 6 types (MISSING_PO, PRICE_VARIANCE, QUANTITY_DISCREPANCY, DUPLICATE_INVOICE, VENDOR_NOT_IN_SYSTEM, and ESCALATED)
The seed data script is located at deployment/invoice-catalog/seed_data.py and includes detailed documentation about the data structure and exception scenarios. All test data is written to the DynamoDB table specified in your SAM deployment (default: ProcureToPayTable).
Invoice Catalog
cd deployment/invoice-catalog
python tests/test_integration.py
python tests/test_lambda.pyOAuth Email API
cd deployment/oauth-sns-email-api
./test-api.sh
# or
python test-api.py --api-endpoint <endpoint> --token-endpoint <token-endpoint> --client-id <id> --client-secret <secret>Strands Agent
cd deployment/strands-agent-procurepay-gw
make local.testTo clean up your deployment and remove all provisioned resources:
-
Delete Strands Agent
cd deployment/strands-agent-procurepay-gw make agentcore.delete make infrastructure.delete -
Delete OAuth Email API
cd deployment/oauth-sns-email-api sam delete --stack-name oauth-sns-email-api -
Delete Invoice Catalog Service
cd deployment/invoice-catalog sam delete --stack-name <your-stack-name>
-
Remove Amazon S3 bucket policies and data (if QuickSight was configured)
aws s3api delete-bucket-policy --bucket YOUR_BUCKET_NAME aws s3 rm s3://YOUR_BUCKET_NAME --recursive
The seed_data.py script (located at deployment/invoice-catalog/seed_data.py) generates comprehensive test data for the P2P system including vendors, purchase orders, goods receipts, invoices, and exception cases. The test data covers various invoice matching scenarios (perfect match, price variance, quantity discrepancy) and creates approximately 25 exception cases across 6 different types (MISSING_PO, PRICE_VARIANCE, QUANTITY_DISCREPANCY, DUPLICATE_INVOICE, VENDOR_NOT_IN_SYSTEM, and ESCALATED). All test data includes realistic linkages between invoices, POs, and GRs to support both 2-way and 3-way matching validation.
- OAuth 2.0 authentication for all external APIs
- IAM roles with least-privilege permissions
- JWT token validation with scope-based authorization
- Encryption at rest and in transit (Amazon S3 encryption at rest)
- Dead letter queues with encryption for failed operations
- API Gateway access logging and response caching
- X-Ray tracing for security monitoring and audit trails
- HTTPS enforcement for all API communications
- CloudWatch logging with retention policies for compliance
To enhance data protection and prevent sensitive customer information from being exposed in agent interactions, you can integrate Amazon Bedrock Guardrails into your architecture. Guardrails provide content filtering, PII detection and redaction, and topic-based controls to ensure your agentic workflows handle customer data responsibly.
Both the Strands and Amazon Quick Suite agent architectures can be configured to use Guardrails by:
- Defining content filters to block harmful or inappropriate responses
- Enabling PII detection to automatically redact sensitive information like credit card numbers, SSNs, and email addresses
- Setting up denied topics to prevent the agent from discussing restricted subjects
- Applying word filters to block specific terms or phrases
CloudWatch Logs:
- Lambda Functions:
/aws/lambda/ProcureToPayFunction,/aws/lambda/oauth-email-publisher - AgentCore Runtime:
/aws/bedrock-agentcore/runtimes/* - API Gateway:
/aws/apigateway/<API_GATEWAY_ID>(with 14-day retention)
Key Metrics:
- Lambda invocations, errors, duration, concurrent executions
- API Gateway requests, latency, 4xx/5xx errors, cache hit/miss
- SNS publish success/failure, delivery attempts
- AgentCore runtime performance
- X-Ray distributed tracing for end-to-end monitoring
- Advanced matching algorithms (2-way/3-way) are pending implementation
- Real-time dashboard features are under development
- Integration with external ERP systems is not yet available
Customers are responsible for making their own independent assessment of the information in this Guidance. This Guidance: (a) is for informational purposes only, (b) represents AWS current product offerings and practices, which are subject to change without notice, and (c) does not create any commitments or assurances from AWS and its affiliates, suppliers or licensors. AWS products or services are provided “as is” without warranties, representations, or conditions of any kind, whether express or implied. AWS responsibilities and liabilities to its customers are controlled by AWS agreements, and this Guidance is not part of, nor does it modify, any agreement between AWS and its customers.
This library is licensed under the MIT-0 License. See the LICENSE file.
- Neel Mitra
- Shashi Kiran