Skip to content
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,10 @@ Policy engines apply Cedar-based pre/post-call policies to agent invocations —
Pay-per-call agent transactions via the [x402 protocol](https://www.x402.org/). When a tool call returns
`402 Payment Required`, the payments system signs and submits payment then retries automatically.

| Command | Description |
| ----------------------- | ---------------------------------------------------------------------------- |
| `add payment-manager` | Add a payment manager (orchestrates payment sessions for the agent) |
| `add payment-connector` | Add a payment connector with provider credentials (CoinbaseCDP, StripePrivy) |
| Command | Description |
| ----------------------- | ------------------------------------------------------------------------- |
| `add payment-manager` | Add a payment manager (orchestrates payment sessions for the agent) |
| `add payment-connector` | Add a Quick Create or manual payment connector (CoinbaseCDP, StripePrivy) |

> See [Payments](docs/payments.md) for the full setup including instrument creation and tool allowlists.

Expand Down
19 changes: 10 additions & 9 deletions docs/PERMISSIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -426,15 +426,16 @@ Required only when the project defines payment managers and connectors (the `pay
CLI calls the Payment control-plane and data-plane APIs directly with the developer's credentials; both are signed under
the `bedrock-agentcore` service.

| Action | CLI Commands | Purpose |
| --------------------------------------------------- | ------------ | -------------------------------------------------------------------- |
| `bedrock-agentcore:GetPaymentCredentialProvider` | `deploy` | Check if a payment credential provider already exists |
| `bedrock-agentcore:CreatePaymentCredentialProvider` | `deploy` | Create a payment credential provider from connector secrets |
| `bedrock-agentcore:UpdatePaymentCredentialProvider` | `deploy` | Update a payment credential provider with new secret values |
| `bedrock-agentcore:DeletePaymentCredentialProvider` | `deploy` | Remove a payment credential provider when a connector is removed |
| `bedrock-agentcore:GetPaymentManager` | `status` | Look up payment manager status |
| `bedrock-agentcore:ListPaymentSessions` | `invoke` | Find an existing active payment session before creating a new one |
| `bedrock-agentcore:CreatePaymentSession` | `invoke` | Create a payment session with a default budget for `invoke` auto-pay |
| Action | CLI Commands | Purpose |
| --------------------------------------------------- | ------------------ | -------------------------------------------------------------------- |
| `bedrock-agentcore:GetPaymentCredentialProvider` | `deploy` | Check if a payment credential provider already exists |
| `bedrock-agentcore:CreatePaymentCredentialProvider` | `deploy` | Create a payment credential provider from connector secrets |
| `bedrock-agentcore:UpdatePaymentCredentialProvider` | `deploy` | Update a payment credential provider with new secret values |
| `bedrock-agentcore:DeletePaymentCredentialProvider` | `deploy` | Remove a payment credential provider when a connector is removed |
| `bedrock-agentcore:GetPaymentManager` | `status` | Look up payment manager status |
| `bedrock-agentcore:GetPaymentConnector` | `deploy`, `status` | Retrieve connector status and a pending authorization URL |
| `bedrock-agentcore:ListPaymentSessions` | `invoke` | Find an existing active payment session before creating a new one |
| `bedrock-agentcore:CreatePaymentSession` | `invoke` | Create a payment session with a default budget for `invoke` auto-pay |

Creating or updating a payment credential provider also writes the connector secrets into a service-managed Secrets
Manager secret (named `bedrock-agentcore-identity!default/payment/*`). Unlike API key and OAuth2 providers, the Payment
Expand Down
33 changes: 20 additions & 13 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,12 @@ agentcore add payment-manager \
Add a payment connector to an existing payment manager. See [Payments](payments.md) for credential details.

```bash
# Quick Create (recommended)
agentcore add payment-connector \
--manager MyManager \
--name MyCDPConnector \
--provision-mode QUICK_CREATE

# CoinbaseCDP provider
agentcore add payment-connector \
--manager MyManager \
Expand All @@ -541,19 +547,20 @@ agentcore add payment-connector \
--authorization-id your-auth-id
```

| Flag | Description |
| ----------------------------------- | ------------------------------------------ |
| `--manager <name>` | Parent payment manager (required) |
| `--name <name>` | Connector name (required) |
| `--provider <provider>` | `CoinbaseCDP` (default) or `StripePrivy` |
| `--api-key-id <id>` | Coinbase CDP API Key ID |
| `--api-key-secret <secret>` | Coinbase CDP API Key Secret |
| `--wallet-secret <secret>` | Coinbase CDP Wallet Secret |
| `--app-id <id>` | Privy App ID (StripePrivy) |
| `--app-secret <secret>` | Privy App Secret (StripePrivy) |
| `--authorization-private-key <key>` | ECDSA P-256 private key (StripePrivy) |
| `--authorization-id <id>` | Authorization key identifier (StripePrivy) |
| `--json` | JSON output |
| Flag | Description |
| ----------------------------------- | ------------------------------------------------------ |
| `--manager <name>` | Parent payment manager (required) |
| `--name <name>` | Connector name (required) |
| `--provision-mode <mode>` | `QUICK_CREATE` or `MANUAL` (default) |
| `--provider <provider>` | `CoinbaseCDP` or `StripePrivy` (manual mode only) |
| `--api-key-id <id>` | Coinbase CDP API Key ID (manual mode) |
| `--api-key-secret <secret>` | Coinbase CDP API Key Secret (manual mode) |
| `--wallet-secret <secret>` | Coinbase CDP Wallet Secret (manual mode) |
| `--app-id <id>` | Privy App ID (StripePrivy manual mode) |
| `--app-secret <secret>` | Privy App Secret (StripePrivy manual mode) |
| `--authorization-private-key <key>` | ECDSA P-256 private key (StripePrivy manual mode) |
| `--authorization-id <id>` | Authorization key identifier (StripePrivy manual mode) |
| `--json` | JSON output |

### add credential

Expand Down
22 changes: 14 additions & 8 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,11 @@ wallet credentials. See [Payments](payments.md) for the full usage guide.
{
"name": "MyCDPConnector",
"provider": "CoinbaseCDP",
"provisionMode": "QUICK_CREATE"
},
{
"name": "MyManualConnector",
"provider": "CoinbaseCDP",
"credentialName": "my-cdp-creds"
}
]
Expand Down Expand Up @@ -572,17 +577,18 @@ wallet credentials. See [Payments](payments.md) for the full usage guide.

### Payment Connector

| Field | Required | Description |
| ---------------- | -------- | -------------------------------------------------- |
| `name` | Yes | Connector name (alphanumeric + underscore, max 48) |
| `provider` | No | `"CoinbaseCDP"` (default) or `"StripePrivy"` |
| `credentialName` | Yes | Name of the credential (maps to `.env.local` vars) |
| Field | Required | Description |
| ---------------- | -------- | ----------------------------------------------------------------- |
| `name` | Yes | Connector name (alphanumeric + underscore, max 48) |
| `provider` | Yes | `"CoinbaseCDP"` for Quick Create; either provider for manual mode |
| `provisionMode` | Cond. | `"QUICK_CREATE"` for Quick Create; omit or use `"MANUAL"` |
| `credentialName` | Cond. | Required for manual mode; forbidden for Quick Create |

### Payment Credential Provider

Payment connectors use a `PaymentCredentialProvider` credential type, distinct from `ApiKeyCredentialProvider` and
`OAuthCredentialProvider`. The credential is automatically created during `agentcore deploy` from values in
`.env.local`. You do not need to add it to the `credentials` array manually.
Manual payment connectors use a `PaymentCredentialProvider` credential type, distinct from `ApiKeyCredentialProvider`
and `OAuthCredentialProvider`. The credential is automatically created during `agentcore deploy` from values in
`.env.local`. Quick Create provisions its provider through the service and does not add a local credential entry.

---

Expand Down
38 changes: 28 additions & 10 deletions docs/payments.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,13 @@ cd MyProject
# 2. Add a payment manager
agentcore add payment-manager --name MyManager

# 3. Add a payment connector with CoinbaseCDP credentials
# 3. Add a Coinbase connector with Quick Create
agentcore add payment-connector \
--manager MyManager \
--name MyCDPConnector \
--provider CoinbaseCDP \
--api-key-id your-api-key-id \
--api-key-secret your-api-key-secret \
--wallet-secret your-wallet-secret
--provision-mode QUICK_CREATE

# 4. Deploy (creates payment infrastructure on AWS)
# 4. Deploy, then open the authorization URL printed by the CLI
agentcore deploy -y

# 5. Create + fund an instrument out-of-band (SDK), then invoke with auto-session
Expand Down Expand Up @@ -126,8 +123,28 @@ For details on IAM role separation (ManagementRole vs ProcessPaymentRole), see
A payment connector links a credential provider (wallet credentials) to a payment manager. Each manager needs at least
one connector before it can process payments.

### Quick Create with Coinbase (Recommended)

Quick Create provisions the Coinbase credential provider through AWS after deployment. It does not collect credentials,
add a local credential entry, or write payment variables to `.env.local`.

```bash
agentcore add payment-connector \
--manager MyManager \
--name MyCDPConnector \
--provision-mode QUICK_CREATE

agentcore deploy -y
```

Deploy prints the live authorization URL. Open it to complete consent. The deployment succeeds while the connector is
`PENDING_AUTHENTICATION`; use `agentcore status --type payment` to retrieve the current status and URL. Once consent
completes, status becomes `READY` and the generated credential provider ARN appears in status output.

### CoinbaseCDP Provider

Manual mode remains available when you already manage Coinbase CDP credentials.

```bash
agentcore add payment-connector \
--manager MyManager \
Expand Down Expand Up @@ -174,8 +191,8 @@ agentcore add payment-connector \

### Credential Storage

Connector credentials are stored in `agentcore/.env.local` and never committed to source control. The env var naming
convention is:
Manual connector credentials are stored in `agentcore/.env.local` and never committed to source control. Quick Create
does not use local payment credentials. The manual env var naming convention is:

**CoinbaseCDP** (3 variables):

Expand Down Expand Up @@ -462,11 +479,12 @@ agentcore remove payment-manager --name MyManager -y
```

Removing a payment manager cascades: it deletes all associated connectors and credential providers from the local
configuration.
configuration. The CLI never imperatively deletes a provider generated by Quick Create.

## Validation

`agentcore validate` checks payment configuration for common issues:
`agentcore validate` checks payment configuration for common issues. Credential and `.env.local` checks apply only to
manual connectors:

- Credential cross-references: verifies each connector's `credentialName` maps to a valid credential entry
- `.env.local` existence: confirms the secrets file exists when payment connectors are configured
Expand Down
1 change: 1 addition & 0 deletions docs/policies/iam-policy-user.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
"bedrock-agentcore:UpdatePaymentCredentialProvider",
"bedrock-agentcore:DeletePaymentCredentialProvider",
"bedrock-agentcore:GetPaymentManager",
"bedrock-agentcore:GetPaymentConnector",
"bedrock-agentcore:ListPaymentSessions",
"bedrock-agentcore:CreatePaymentSession"
],
Expand Down
119 changes: 119 additions & 0 deletions integ-tests/add-remove-payment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,125 @@ describe('integration: add and remove payment managers and connectors', () => {
});
});

describe('Quick Create connector lifecycle', () => {
const managerName = `IntegQuickMgr${Date.now().toString().slice(-6)}`;
const connectorName = `IntegQuick${Date.now().toString().slice(-6)}`;
let envBefore = '';

beforeAll(async () => {
await runCLI(['add', 'payment-manager', '--name', managerName], project.projectPath);
envBefore = await readFile(join(project.projectPath, 'agentcore', '.env.local'), 'utf-8').catch(() => '');
});

it('adds Quick Create without provider or credential flags', async () => {
const result = await runCLI(
[
'add',
'payment-connector',
'--manager',
managerName,
'--name',
connectorName,
'--provision-mode',
'QUICK_CREATE',
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
expect(JSON.parse(result.stdout)).toEqual(
expect.objectContaining({
success: true,
managerName,
connectorName,
})
);

const config = await readProjectConfig(project.projectPath);
const manager = config.payments?.find((p: Record<string, unknown>) => p.name === managerName);
expect(manager?.connectors).toEqual([
{
name: connectorName,
provider: 'CoinbaseCDP',
provisionMode: 'QUICK_CREATE',
},
]);
expect(
config.credentials?.some((c: Record<string, unknown>) => c.authorizerType === 'PaymentCredentialProvider')
).toBe(false);
});

it('does not write payment secrets to .env.local', async () => {
const envAfter = await readFile(join(project.projectPath, 'agentcore', '.env.local'), 'utf-8').catch(() => '');
expect(envAfter).toBe(envBefore);
});

it('rejects credential flags with Quick Create', async () => {
const result = await runCLI(
[
'add',
'payment-connector',
'--manager',
managerName,
'--name',
`${connectorName}Secret`,
'--provision-mode',
'QUICK_CREATE',
'--api-key-id',
'must-not-be-used',
'--json',
],
project.projectPath
);

expect(result.exitCode).toBe(1);
expect(JSON.parse(result.stdout).error).toContain('Credential options cannot be used with QUICK_CREATE');
});

it('rejects StripePrivy with Quick Create', async () => {
const result = await runCLI(
[
'add',
'payment-connector',
'--manager',
managerName,
'--name',
`${connectorName}Stripe`,
'--provision-mode',
'QUICK_CREATE',
'--provider',
'StripePrivy',
'--json',
],
project.projectPath
);

expect(result.exitCode).toBe(1);
expect(JSON.parse(result.stdout).error).toContain('QUICK_CREATE only supports the CoinbaseCDP provider');
});

it('validates a Quick Create connector without local credentials', async () => {
const result = await runCLI(['validate'], project.projectPath);
expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
});

it('removes Quick Create without credential cleanup', async () => {
const result = await runCLI(
['remove', 'payment-connector', '--manager', managerName, '--name', connectorName, '--yes', '--json'],
project.projectPath
);
expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);

const envAfter = await readFile(join(project.projectPath, 'agentcore', '.env.local'), 'utf-8').catch(() => '');
expect(envAfter).toBe(envBefore);
});

afterAll(async () => {
await runCLI(['remove', 'payment-manager', '--name', managerName, '--yes'], project.projectPath);
});
});

describe('StripePrivy connector lifecycle', () => {
const managerName = `IntegSpMgr${Date.now().toString().slice(-6)}`;
const connectorName = `IntegSpConn${Date.now().toString().slice(-6)}`;
Expand Down
Loading
Loading