This guide covers integrating Nevermined payments with AWS services, specifically Strands SDK and AgentCore.
AWS provides infrastructure for deploying and running AI agents at scale. Nevermined adds the payment layer, enabling your agents to monetize their services.
Key integrations:
- Strands SDK: Add payment tools to your Strands agents
- AgentCore: Deploy payment-enabled agents to production
- AWS account with appropriate permissions
- AWS CLI configured (
aws configure) - Nevermined API key and payment plan
pip install strands-agents payments-py[strands]import os
from strands import Agent
from strands.tools import tool
from payments_py import Payments, PaymentOptions
# Initialize Nevermined
payments = Payments.get_instance(
PaymentOptions(
nvm_api_key=os.environ.get("NVM_API_KEY"),
environment="sandbox"
)
)
PLAN_ID = os.environ.get("NVM_PLAN_ID")
@tool
def paid_data_lookup(query: str) -> str:
"""Look up data (requires payment verification)."""
# In production, verify payment before executing
return f"Results for: {query}"
# Create agent with payment-aware tools
agent = Agent(
tools=[paid_data_lookup],
system_prompt="You are a data assistant that charges for premium lookups."
)
# Run the agent
result = agent("Find me the latest market data for AAPL")
print(result.message)from payments_py.x402.helpers import build_payment_required
@tool
def premium_analysis(data: str, payment_token: str = None) -> str:
"""Perform premium analysis (payment required)."""
if not payment_token:
requirements = build_payment_required(
plan_id=PLAN_ID,
description="Premium data analysis"
)
return f"Payment required: {requirements}"
# Verify the payment token
verification = payments.facilitator.verify_permissions(
plan_id=PLAN_ID,
access_token=payment_token
)
if not verification.get("success"):
return "Payment verification failed"
# Execute the paid operation
result = perform_analysis(data)
# Settle the payment
payments.facilitator.settle_permissions(
plan_id=PLAN_ID,
access_token=payment_token,
credits=1
)
return resultWrap tools with automatic payment verification using a decorator:
from functools import wraps
def requires_payment(credits: int = 1):
"""Decorator to require payment for a tool."""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
payment_token = kwargs.get("payment_token")
if not payment_token:
return {"error": "Payment token required"}
# Verify
verification = payments.facilitator.verify_permissions(
plan_id=PLAN_ID,
access_token=payment_token
)
if not verification.get("success"):
return {"error": "Payment verification failed"}
# Execute
result = func(*args, **kwargs)
# Settle
payments.facilitator.settle_permissions(
plan_id=PLAN_ID,
access_token=payment_token,
credits=credits
)
return result
return wrapper
return decorator
@tool
@requires_payment(credits=5)
def expensive_analysis(data: str, payment_token: str) -> dict:
"""Perform expensive analysis (5 credits)."""
return {"analysis": f"Analysis of {data}"}Note: The
payments-pySDK includes a built-in@requires_paymentdecorator. Install withpip install payments-py[strands]and import frompayments_py.x402.strands. Seeagents/strands-simple-agent/for a complete example.
PRICING_TIERS = {
"basic": {"plan_id": "plan-basic", "credits": 1},
"standard": {"plan_id": "plan-standard", "credits": 5},
"premium": {"plan_id": "plan-premium", "credits": 10},
}
@tool
def tiered_service(query: str, tier: str, payment_token: str) -> dict:
"""Service with tiered pricing."""
tier_config = PRICING_TIERS.get(tier, PRICING_TIERS["basic"])
verification = payments.facilitator.verify_permissions(
plan_id=tier_config["plan_id"],
access_token=payment_token
)
if not verification.get("success"):
return {"error": f"Payment verification failed for {tier} tier"}
result = process_with_tier(query, tier)
payments.facilitator.settle_permissions(
plan_id=tier_config["plan_id"],
access_token=payment_token,
credits=tier_config["credits"]
)
return result@tool
def safe_paid_operation(query: str, payment_token: str) -> dict:
"""Paid operation with proper error handling."""
try:
verification = payments.facilitator.verify_permissions(
plan_id=PLAN_ID,
access_token=payment_token
)
if not verification.get("success"):
return {
"success": False,
"error": "Payment verification failed",
"details": verification.get("error")
}
try:
result = do_work(query)
except Exception as e:
# Don't charge for failed execution
return {"success": False, "error": f"Execution failed: {e}", "charged": False}
# Settle only on success
settlement = payments.facilitator.settle_permissions(
plan_id=PLAN_ID,
access_token=payment_token,
credits=1
)
return {
"success": True,
"result": result,
"credits_charged": settlement.get("credits_burned", 1)
}
except Exception as e:
return {"success": False, "error": f"Payment system error: {e}"}AWS AgentCore provides managed infrastructure for deploying AI agents.
Full deployment guide: See Deploy to AgentCore for step-by-step instructions using the working buyer and seller agents, including the header remapping, SigV4 signing, and seller pre-registration patterns needed to make Nevermined payments work through AgentCore's proxy.
my-agent/
├── agent.py # Agent code with Nevermined
├── requirements.txt
├── Dockerfile
└── agentcore.yaml # AgentCore configuration
# agent.py
from bedrock_agentcore import BedrockAgentCoreApp
from payments_py import Payments, PaymentOptions
import os
app = BedrockAgentCoreApp()
# Initialize Nevermined
payments = Payments.get_instance(
PaymentOptions(
nvm_api_key=os.environ.get("NVM_API_KEY"),
environment="sandbox"
)
)
PLAN_ID = os.environ.get("NVM_PLAN_ID")
@app.entrypoint
def invoke(payload):
"""Main entry point for the agent."""
prompt = payload.get("prompt", "")
payment_token = payload.get("payment_token")
# Verify payment
if payment_token:
verification = payments.facilitator.verify_permissions(
plan_id=PLAN_ID,
access_token=payment_token
)
if not verification.get("success"):
return {"error": "Payment verification failed"}
else:
return {"error": "Payment token required", "plan_id": PLAN_ID}
# Execute agent logic
result = process_request(prompt)
# Settle payment
payments.facilitator.settle_permissions(
plan_id=PLAN_ID,
access_token=payment_token,
credits=1
)
return {"result": result}
def process_request(prompt: str) -> str:
"""Your agent's business logic here."""
# Add your LLM calls, data processing, etc.
return f"Processed: {prompt}"
if __name__ == "__main__":
app.run()# agentcore.yaml
name: my-payment-agent
version: 1.0.0
runtime: python3.10
environment:
NVM_API_KEY: ${NVM_API_KEY}
NVM_PLAN_ID: ${NVM_PLAN_ID}
NVM_ENVIRONMENT: sandbox
resources:
memory: 512MB
timeout: 30s
entrypoint: agent:invoke# Install AgentCore CLI
pip install bedrock-agentcore-cli
# Deploy the agent
agentcore deploy --config agentcore.yamlThe following patterns from amazon-bedrock-agentcore-samples are useful:
- Basic Strands agent setup
- Tool definition patterns
- Multi-tool agents
enterprise-web-intelligence-agent/— Web data gathering with cost trackingcost-optimization-agent/— Budget management patternsmarket-trends-agent/— Data marketplace integration
Never hardcode credentials:
NVM_API_KEY = os.environ.get("NVM_API_KEY")
if not NVM_API_KEY:
raise ValueError("NVM_API_KEY environment variable required")Always handle payment failures gracefully:
try:
verification = payments.facilitator.verify_permissions(...)
except Exception as e:
logger.error(f"Payment verification failed: {e}")
return {"error": "Payment service unavailable"}Use unique request IDs for settlement:
import uuid
request_id = str(uuid.uuid4())
settlement = payments.facilitator.settle_permissions(
plan_id=PLAN_ID,
access_token=token,
credits=1,
request_id=request_id # Prevents double-charging
)Track all payment operations:
import logging
logger = logging.getLogger(__name__)
logger.info(f"Payment verified: {verification.get('agent_request_id')}")
logger.info(f"Credits used: {settlement.get('credits_burned')}")- Deploy to AgentCore — Step-by-step deployment guide with Nevermined payments
- AWS AgentCore Documentation
- Strands SDK Documentation
- AgentCore Samples
- Nevermined Documentation