Setting the file. One moment.
Agentcore Payments Setup Script · Amazon Bedrock · aws/agent-toolkit-for-aws · Skills Docs
Once you have all inputs from Step 3, generate a single Python script called setup_payments.py that executes all the following steps automatically without human intervention. Write the script, then execute it.
The script must:
ContentsBack to the top of the page Fetch Bedrock Agent
70
Creating Amazon Aurora Db Cluster With Instances
93
Routing Traffic With Route53 And CloudFront
Resilience Program Design
Creating API Gateway Stage
Store payment provider credentials in AgentCore Identity
Create the IAM execution role with trust policy and permissions
Wait for IAM propagation (15 seconds)
Create the Payment Manager and wait for READY status
Create the Payment Connector
Create the Payment Instrument (wallet)
Print a summary of all created resources and next steps
Substitute the developer’s inputs into the configuration section:
Tell the developer to run source .env.payments before executing the script
Print the summary to the developer
Tell them to complete the two manual steps (delegation + funding) for the provider they chose
Do NOT reference the other provider’s flow — only show steps for the provider in use
Wait for them to confirm before proceeding to Step 5 (wiring)
references/agentcore-payments-setup-script.md
=
"<ACCOUNT_ID>"
# e.g., "123456789012"
PROVIDER = "<PROVIDER>" # "CoinbaseCDP" or "StripePrivy"
END_USER_EMAIL = "<END_USER_EMAIL>" # e.g., "developer@example.com"
RESOURCE_PREFIX = "paymentspoc" # prefix for all resource names
# Read credentials from environment variables (NOT from file directly).
# Run `source .env.payments` in your terminal before executing this script.
# Do NOT pass credentials through the agent — they must stay local.
# For Coinbase:
COINBASE_API_KEY_ID = os.environ.get( "COINBASE_API_KEY_ID" , "" )
COINBASE_API_KEY_SECRET = os.environ.get( "COINBASE_API_KEY_SECRET" , "" )
COINBASE_WALLET_SECRET = os.environ.get( "COINBASE_WALLET_SECRET" , "" )
# For Stripe:
AUTH_PRIVATE_KEY = os.environ.get( "AUTH_PRIVATE_KEY" , "" )
AUTH_ID = os.environ.get( "AUTH_ID" , "" )
PRIVY_APP_ID = os.environ.get( "PRIVY_APP_ID" , "" )
PRIVY_APP_SECRET = os.environ.get( "PRIVY_APP_SECRET" , "" )
# === CLIENTS ===
iam = boto3.client( "iam" )
cp_client = boto3.client( "bedrock-agentcore-control" , region_name = REGION )
dp_client = boto3.client( "bedrock-agentcore" , region_name = REGION )
print ( "=" * 60 )
print ( "AgentCore Payments Setup" )
print ( "=" * 60 )
# === STEP 1: Store credentials ===
print ( " \n [1/6] Storing payment provider credentials..." )
cred_name = f " { RESOURCE_PREFIX } -creds"
def create_credential_provider_with_retry (name, vendor, config, max_retries = 5 ):
"""Create credential provider, appending a numeric suffix if name already exists."""
for attempt in range (max_retries):
unique_name = name if attempt == 0 else f " { name } - { attempt } "
try :
if vendor == "CoinbaseCDP" :
resp = cp_client.create_payment_credential_provider(
name = unique_name,
credentialProviderVendor = vendor,
providerConfigurationInput = { "coinbaseCdpConfiguration" : config}
)
elif vendor == "StripePrivy" :
resp = cp_client.create_payment_credential_provider(
name = unique_name,
credentialProviderVendor = vendor,
providerConfigurationInput = { "stripePrivyConfiguration" : config}
)
print ( f " (Using name: { unique_name } )" )
return resp
except Exception as e:
if "already exists" in str (e).lower() or "conflict" in str (e).lower():
print ( f " Name ' { unique_name } ' already exists, trying with suffix..." )
continue
raise
raise Exception ( f "Failed to create credential provider after { max_retries } attempts" )
if PROVIDER == "CoinbaseCDP" :
cred_config = {
"apiKeyId" : COINBASE_API_KEY_ID ,
"apiKeySecret" : COINBASE_API_KEY_SECRET ,
"walletSecret" : COINBASE_WALLET_SECRET
}
elif PROVIDER == "StripePrivy" :
cred_config = {
"appId" : PRIVY_APP_ID ,
"appSecret" : PRIVY_APP_SECRET ,
"authorizationPrivateKey" : AUTH_PRIVATE_KEY ,
"authorizationId" : AUTH_ID
}
cred_resp = create_credential_provider_with_retry(cred_name, PROVIDER , cred_config)
credential_provider_arn = cred_resp[ "credentialProviderArn" ]
print ( f " OK Credential Provider ARN: { credential_provider_arn } " )
# === STEP 2: Create IAM role ===
print ( " \n [2/6] Creating IAM service role..." )
base_role_name = f "AgentCorePayments- { RESOURCE_PREFIX } "
def create_role_with_retry (base_name, max_retries = 5 ):
"""Create IAM role, appending a numeric suffix if name already exists."""
for attempt in range (max_retries):
unique_name = base_name if attempt == 0 else f " { base_name } - { attempt } "
try :
iam.create_role(
RoleName = unique_name,
AssumeRolePolicyDocument = json.dumps({
"Version" : "2012-10-17" ,
"Statement" : [{
"Effect" : "Allow" ,
"Principal" : { "Service" : "bedrock-agentcore.amazonaws.com" },
"Action" : "sts:AssumeRole" ,
"Condition" : {
"StringEquals" : { "aws:SourceAccount" : ACCOUNT_ID },
"ArnLike" : { "aws:SourceArn" : f "arn:aws:bedrock-agentcore: { REGION } : { ACCOUNT_ID } :payment-manager/ { RESOURCE_PREFIX } -*" }
}
}]
}),
Description = "Service role for AgentCore Payments"
)
print ( f " (Using role name: { unique_name } )" )
return unique_name
except iam.exceptions.EntityAlreadyExistsException:
print ( f " Role ' { unique_name } ' already exists, trying with suffix..." )
continue
raise Exception ( f "Failed to create role after { max_retries } attempts" )
role_name = create_role_with_retry(base_role_name)
iam.put_role_policy(
RoleName = role_name,
PolicyName = "PaymentsResourceRetrievalPolicy" ,
PolicyDocument = json.dumps({
"Version" : "2012-10-17" ,
"Statement" : [
{
"Sid" : "WorkloadIdentity" ,
"Effect" : "Allow" ,
"Action" : [
"bedrock-agentcore:CreateWorkloadIdentity" ,
"bedrock-agentcore:GetWorkloadAccessToken" ,
"bedrock-agentcore:GetResourcePaymentToken"
],
"Resource" : [
f "arn:aws:bedrock-agentcore: { REGION } : { ACCOUNT_ID } :token-vault/default" ,
f "arn:aws:bedrock-agentcore: { REGION } : { ACCOUNT_ID } :token-vault/default/paymentcredentialprovider/*" ,
f "arn:aws:bedrock-agentcore: { REGION } : { ACCOUNT_ID } :workload-identity-directory/default" ,
f "arn:aws:bedrock-agentcore: { REGION } : { ACCOUNT_ID } :workload-identity-directory/default/workload-identity/*"
]
},
{
"Sid" : "SecretsAccess" ,
"Effect" : "Allow" ,
"Action" : "secretsmanager:GetSecretValue" ,
"Resource" : f "arn:aws:secretsmanager: { REGION } : { ACCOUNT_ID } :secret:bedrock-agentcore-identity*"
}
]
})
)
role_arn = f "arn:aws:iam:: { ACCOUNT_ID } :role/ { role_name } "
print ( f " OK Role ARN: { role_arn } " )
print ( " Waiting 15s for IAM propagation..." )
time.sleep( 15 )
# === STEP 3: Create Payment Manager ===
print ( " \n [3/6] Creating Payment Manager..." )
mgr_resp = cp_client.create_payment_manager(
name = RESOURCE_PREFIX ,
description = "Payment manager created by AgentCore Payments skill" ,
authorizerType = "AWS_IAM" ,
roleArn = role_arn,
clientToken = str (uuid.uuid4())
)
payment_manager_arn = mgr_resp[ "paymentManagerArn" ]
manager_id = mgr_resp[ "paymentManagerId" ]
print ( f " OK Payment Manager ARN: { payment_manager_arn } " )
# Wait for READY
for i in range ( 12 ):
status_resp = cp_client.get_payment_manager( paymentManagerId = manager_id)
if status_resp[ "status" ] == "READY" :
break
time.sleep( 5 )
if status_resp[ "status" ] != "READY" :
raise Exception (
f "Payment Manager did not reach READY status after 60s "
f "(current: { status_resp[ 'status' ] } ). Check CloudTrail for errors."
)
print ( f " OK Status: { status_resp[ 'status' ] } " )
# === STEP 4: Create Payment Connector ===
print ( " \n [4/6] Creating Payment Connector..." )
connector_config_key = "coinbaseCDP" if PROVIDER == "CoinbaseCDP" else "stripePrivy"
conn_resp = cp_client.create_payment_connector(
paymentManagerId = manager_id,
name = f " { RESOURCE_PREFIX } connector" ,
description = f " { PROVIDER } connector" ,
type = PROVIDER ,
credentialProviderConfigurations = [{
connector_config_key: { "credentialProviderArn" : credential_provider_arn}
}],
clientToken = str (uuid.uuid4())
)
connector_id = conn_resp[ "paymentConnectorId" ]
print ( f " OK Connector ID: { connector_id } " )
# === STEP 5: Create Payment Instrument ===
print ( " \n [5/6] Creating Payment Instrument (wallet)..." )
user_id = f " { RESOURCE_PREFIX } -user"
instr_resp = dp_client.create_payment_instrument(
paymentManagerArn = payment_manager_arn,
paymentConnectorId = connector_id,
userId = user_id,
paymentInstrumentType = "EMBEDDED_CRYPTO_WALLET" ,
paymentInstrumentDetails = {
"embeddedCryptoWallet" : {
"network" : "ETHEREUM" ,
"linkedAccounts" : [
{ "email" : { "emailAddress" : END_USER_EMAIL }}
]
}
},
clientToken = str (uuid.uuid4())
)
instrument_data = instr_resp.get( "paymentInstrument" , instr_resp)
payment_instrument_id = instrument_data[ "paymentInstrumentId" ]
wallet_details = instrument_data.get( "paymentInstrumentDetails" , {}).get( "embeddedCryptoWallet" , {})
wallet_address = wallet_details.get( "walletAddress" , "pending" )
redirect_url = wallet_details.get( "redirectUrl" , None )
print ( f " OK Instrument ID: { payment_instrument_id } " )
print ( f " OK Wallet Address: { wallet_address } " )
# === STEP 6: Create Payment Session ===
print ( " \n [6/6] Creating Payment Session..." )
session_resp = dp_client.create_payment_session(
paymentManagerArn = payment_manager_arn,
userId = user_id,
expiryTimeInMinutes = 60
)
payment_session_id = session_resp[ "paymentSession" ][ "paymentSessionId" ]
print ( f " OK Session ID: { payment_session_id } " )
# === SUMMARY ===
print ( " \n " + "=" * 60 )
print ( "SETUP COMPLETE" )
print ( "=" * 60 )
print ( f """
Resources created:
Payment Manager ARN: { payment_manager_arn }
Connector ID: { connector_id }
Instrument ID: { payment_instrument_id }
Wallet Address: { wallet_address }
Session ID: { payment_session_id }
User ID: { user_id }
Region: { REGION }
Environment variables for your agent:
export PAYMENT_MANAGER_ARN=" { payment_manager_arn } "
export PAYMENT_INSTRUMENT_ID=" { payment_instrument_id } "
export PAYMENT_SESSION_ID=" { payment_session_id } "
export PAYMENT_USER_ID=" { user_id } "
export AWS_REGION=" { REGION } "
""" )
print ( " \n MANUAL STEPS REQUIRED: \n " )
# Step 1: Delegation — provider-specific
if PROVIDER == "CoinbaseCDP" :
print ( f """1. DELEGATION — Grant the agent permission to spend from the wallet:
Visit: { redirect_url }
Log in with: { END_USER_EMAIL }
Grant permissions to the wallet address: { wallet_address }
""" )
elif PROVIDER == "StripePrivy" :
print ( f """1. DELEGATION — Enable delegation on the embedded wallet:
a. Set up a frontend using the Privy frontend SDK:
https://github.com/privy-io/aws-agentcore-sdk
b. Log in with the end user email: { END_USER_EMAIL }
c. Approve delegation for the wallet address: { wallet_address }
""" )
# Step 2: Funding — same for both providers
print ( f """2. FUNDING — Send testnet USDC to the wallet:
Go to: https://faucet.circle.com/
Select: Base Sepolia
Paste wallet address: { wallet_address }
""" )