Process payments, send invoices, issue refunds, manage subscriptions, and detect fraud via a secure payment gateway proxy. Use when a user asks to charge som...
---
name: paypilot
description: Process payments, send invoices, issue refunds, manage subscriptions, and detect fraud via a secure payment gateway proxy. Use when a user asks to charge someone, send a payment link, check sales, issue a refund, create recurring billing, view fraud analytics, configure fraud rules, or manage any payment-related task. Supports 3D Secure, AVS/CVV verification, and risk scoring. Also use for merchant onboarding and first-time payment setup.
metadata: {"openclaw":{"requires":{"bins":["curl","jq"]},"homepage":"https://agms.com/paypilot/"}}
---
# PayPilot — Payment Processing for AI Agents
Accept payments, send invoices, issue refunds, and track sales — all through conversation.
## Setup
PayPilot connects to a hosted API proxy at `https://paypilot.agms.com`. On first use, check for credentials:
```bash
cat ~/.config/paypilot/config.json
```
If no config exists, guide the user through setup:
1. **Register** on the PayPilot proxy:
```bash
curl -s "https://paypilot.agms.com/v1/auth/register" -X POST \
-H "Content-Type: application/json" \
-d '{"name":"BUSINESS_NAME","email":"EMAIL","password":"PASSWORD"}'
```
2. **Login** to get an access token:
```bash
curl -s "https://paypilot.agms.com/v1/auth/login" -X POST \
-H "Content-Type: application/json" \
-d '{"email":"EMAIL","password":"PASSWORD"}'
```
3. **Configure** the payment gateway key:
```bash
curl -s "https://paypilot.agms.com/v1/auth/configure" -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"gateway_key":"YOUR_GATEWAY_KEY"}'
```
4. **Save** credentials locally:
```bash
mkdir -p ~/.config/paypilot
cat > ~/.config/paypilot/config.json << 'EOF'
{
"api_url": "https://paypilot.agms.com",
"email": "merchant@example.com",
"token": "jwt_token_here"
}
EOF
chmod 600 ~/.config/paypilot/config.json
```
**Note:** The password is used only during registration and login to obtain a JWT. It is never stored in the config file or read from environment variables.
If the user doesn't have a gateway account, start the onboarding process:
1. Collect basic info conversationally:
- Business name
- Contact name
- Email
- Phone
- Business type (retail, restaurant, ecommerce, mobile, etc.)
2. Save the lead to our system:
```bash
curl -s "https://paypilot.agms.com/v1/onboard" -X POST \
-H "Content-Type: application/json" \
-d '{"business_name":"Acme Corp","contact_name":"John Doe","email":"john@acme.com","phone":"555-1234","business_type":"retail"}'
```
3. Send them the full application link to complete and e-sign:
> "Great! To finish your application, complete the form here: **https://agms.com/get-started/**
> It takes about 5-10 minutes. You'll need your business address, Tax ID, and banking info. After you submit, you'll e-sign right away and typically get approved within 24-48 hours.
> Once approved, come back and I'll set up your payment processing in seconds."
**Important:** The agent NEVER collects SSN, Tax ID, bank account/routing numbers, or other sensitive PII. Those go through the secure AGMS form only.
## Authentication
All payment endpoints require a JWT bearer token. Load config and set headers:
```bash
CONFIG=$(cat ~/.config/paypilot/config.json)
API=$(echo $CONFIG | jq -r '.api_url')
TOKEN=$(echo $CONFIG | jq -r '.token')
AUTH="Authorization: Bearer $TOKEN"
```
If a request returns 401, re-login and update the saved token.
To refresh an expired token:
Prompt the user for their password — never store it or read it from environment variables:
```bash
# Re-login
LOGIN=$(curl -s "$API/v1/auth/login" -X POST \
-H "Content-Type: application/json" \
-d "{\"email\":\"$(echo $CONFIG | jq -r '.email')\",\"password\":\"$USER_PASSWORD\"}")
NEW_TOKEN=$(echo $LOGIN | jq -r '.access_token')
# Update config
TMP=$(mktemp)
chmod 600 "$TMP"
jq --arg t "$NEW_TOKEN" '.token = $t' ~/.config/paypilot/config.json > "$TMP" && mv "$TMP" ~/.config/paypilot/config.json
chmod 600 ~/.config/paypilot/config.json
```
## Core Commands
### Charge / Sale
Process a payment using a vaulted card token. **Never handle raw card numbers.**
```bash
curl -s "$API/v1/payments/charge" -X POST \
-H "Content-Type: application/json" -H "$AUTH" \
-d '{"amount":500.00,"token":"VAULT_ID","description":"Consulting — January"}'
```
Enable 3D Secure for higher-value or flagged transactions:
```bash
curl -s "$API/v1/payments/charge" -X POST \
-H "Content-Type: application/json" -H "$AUTH" \
-d '{"amount":2500.00,"token":"VAULT_ID","description":"Premium service","three_d_secure":true}'
```
The response includes risk assessment and verification:
```json
{
"transaction_id": "123",
"status": "complete",
"amount": 2500,
"risk": { "score": "low", "flags": [] },
"verification": { "avs": "Y", "cvv": "M" },
"three_d_secure": true
}
```
### Send Invoice / Payment Link
```bash
curl -s "$API/v1/payments/invoice" -X POST \
-H "Content-Type: application/json" -H "$AUTH" \
-d '{"amount":500.00,"email":"john@example.com","description":"Consulting — January"}'
```
### Refund
```bash
# Full refund
curl -s "$API/v1/payments/refund" -X POST \
-H "Content-Type: application/json" -H "$AUTH" \
-d '{"transaction_id":"TXN_ID"}'
# Partial refund
curl -s "$API/v1/payments/refund" -X POST \
-H "Content-Type: application/json" -H "$AUTH" \
-d '{"transaction_id":"TXN_ID","amount":50.00}'
```
### Void (same-day cancel)
```bash
curl -s "$API/v1/payments/void" -X POST \
-H "Content-Type: application/json" -H "$AUTH" \
-d '{"transaction_id":"TXN_ID"}'
```
### View Transactions
```bash
curl -s "$API/v1/transactions" -H "$AUTH" | jq .
```
### Sales Summary
```bash
curl -s "$API/v1/transactions/summary" -H "$AUTH" | jq .
```
### Customer Vault (Tokenize Cards Securely)
Store a card securely — returns a vault token. The customer enters card details through a secure form; raw card data never touches the agent.
```bash
curl -s "$API/v1/vault/add" -X POST \
-H "Content-Type: application/json" -H "$AUTH" \
-d '{"first_name":"John","last_name":"Smith","email":"john@example.com"}'
```
### Charge a Vaulted Card
```bash
curl -s "$API/v1/vault/charge" -X POST \
-H "Content-Type: application/json" -H "$AUTH" \
-d '{"vault_id":"VAULT_ID","amount":99.00,"description":"Monthly service"}'
```
### Recurring Billing
```bash
# Create subscription
curl -s "$API/v1/subscriptions" -X POST \
-H "Content-Type: application/json" -H "$AUTH" \
-d '{"vault_id":"VAULT_ID","plan_id":"monthly_99","amount":99.00,"interval":"monthly"}'
# Cancel subscription
curl -s "$API/v1/subscriptions/SUB_ID" -X DELETE -H "$AUTH"
```
### Fraud Detection & Rules
```bash
# View 30-day fraud analytics
curl -s "$API/v1/fraud/summary" -H "$AUTH" | jq .
# List active fraud rules
curl -s "$API/v1/fraud/rules" -H "$AUTH" | jq .
# Create a fraud rule (flag transactions over $5000)
curl -s "$API/v1/fraud/rules" -X POST \
-H "Content-Type: application/json" -H "$AUTH" \
-d '{"rule_type":"max_amount","threshold":"5000","action":"flag"}'
# Supported rule types: max_amount, min_amount, velocity_limit
# Actions: flag (alert), block (reject), review (hold)
# View a specific rule (if supported)
curl -s "$API/v1/fraud/rules/RULE_ID" -H "$AUTH" | jq .
# Delete a rule
curl -s "$API/v1/fraud/rules/RULE_ID" -X DELETE -H "$AUTH"
```
Note: rule updates are not supported. Delete and recreate the rule instead.
Example response from creating a rule:
```json
{
"rule_id": "rule_123",
"rule_type": "max_amount",
"threshold": "5000",
"action": "flag",
"status": "active",
"created_at": "2026-03-15T00:00:00Z"
}
```
When reporting fraud stats:
> "🛡️ Last 30 days: 45 transactions, 0 flagged, 0 blocked. 1 active rule (max $5,000). Fraud rate: 0.00%"
## Security Rules
- **NEVER** ask for, log, or store raw credit card numbers
- **NEVER** include card numbers in conversation history or memory files
- **ALWAYS** use payment links or customer vault tokens for charges
- **ALWAYS** use HTTPS — the proxy enforces TLS
- API tokens and gateway keys must stay in config files, never in chat
- The proxy encrypts gateway keys at rest (AES-256-GCM)
- Rate limited: 60 requests/min global, 5/min on auth endpoints
## Error Handling
- 401 Unauthorized: re-login, update the saved token, then retry.
- 400 Bad Request: validate request body and log the error message.
- 429 Rate Limited: 60 req/min global, 5/min auth. Back off and retry.
- 5xx Server Error: retry with exponential backoff.
- Network errors: verify HTTPS connectivity, then retry.
## Response Patterns
When a payment succeeds:
> "✅ Payment of $500.00 processed. Transaction ID: abc123."
When sending an invoice:
> "📧 Payment link for $500.00 sent to john@example.com."
When a payment fails:
> "❌ Payment declined. Want to try a different method or send a payment link instead?"
When checking sales:
> "📊 This month: 23 transactions · $4,750 in sales · 2 refunds ($150) · Net: $4,600"
## API Reference
For detailed gateway API documentation, see `references/gateway-api.md`.
For payment flow diagrams, see `references/payment-flows.md`.
For PCI compliance guidelines, see `references/pci-compliance.md`.
## Discovery
AI agents and bots can discover PayPilot capabilities automatically:
- **OpenAPI Spec:** `https://paypilot.agms.com/openapi.json`
- **AI Plugin Manifest:** `https://paypilot.agms.com/.well-known/ai-plugin.json`
- **LLM Resource Index:** `https://paypilot.agms.com/llms.txt`
- **Landing Page:** `https://agms.com/paypilot/`
- **ClawHub:** `https://clawhub.ai/agmsyumet/paypilot-agms`
don't have the plugin yet? install it then click "run inline in claude" again.
by @clawhub
added explicit procedure steps (14 total) with input/output contracts for each operation, extracted decision points covering auth failures, 3D secure logic, rate limits, and merchant onboarding, created structured output contract with json examples for all response types, defined clear outcome signals with user-facing messages, and enhanced security guidance around pii handling and token management.
PayPilot is a secure payment processing gateway proxy that handles charges, invoices, refunds, subscriptions, and fraud detection. use it when a user asks to charge someone, send a payment link, check sales, issue a refund, create recurring billing, view fraud analytics, configure fraud rules, onboard as a merchant, or manage any payment-related task. the skill supports 3D Secure, AVS/CVV verification, and risk scoring without exposing raw card data.
external connection: paypilot api proxy
https://paypilot.agms.comlocal config file
~/.config/paypilot/config.jsonapi_url, email, tokenmerchant account requirements
customer data for transactions
inputs: none
outputs: valid ~/.config/paypilot/config.json with api_url, email, token
load existing config:
CONFIG=$(cat ~/.config/paypilot/config.json 2>/dev/null)
if [ -z "$CONFIG" ]; then
echo "no config found. starting setup."
# proceed to step 2
else
API=$(echo $CONFIG | jq -r '.api_url')
EMAIL=$(echo $CONFIG | jq -r '.email')
TOKEN=$(echo $CONFIG | jq -r '.token')
echo "loaded existing config for $EMAIL"
fi
inputs: user email, user password (prompted once, never stored) outputs: jwt access_token
if no config exists, guide registration:
curl -s "https://paypilot.agms.com/v1/auth/register" -X POST \
-H "Content-Type: application/json" \
-d '{"name":"BUSINESS_NAME","email":"EMAIL","password":"PASSWORD"}'
then login to get token:
LOGIN=$(curl -s "https://paypilot.agms.com/v1/auth/login" -X POST \
-H "Content-Type: application/json" \
-d '{"email":"EMAIL","password":"PASSWORD"}')
TOKEN=$(echo $LOGIN | jq -r '.access_token')
inputs: gateway_key from AGMS dashboard outputs: confirmation that key is registered
curl -s "https://paypilot.agms.com/v1/auth/configure" -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"gateway_key":"YOUR_GATEWAY_KEY"}'
inputs: api_url, email, token outputs: secured config file
mkdir -p ~/.config/paypilot
cat > ~/.config/paypilot/config.json << 'EOF'
{
"api_url": "https://paypilot.agms.com",
"email": "merchant@example.com",
"token": "jwt_token_here"
}
EOF
chmod 600 ~/.config/paypilot/config.json
inputs: amount, vault_token (or email for payment link), description, optional three_d_secure flag outputs: transaction_id, status, risk_score, verification details
load token and call charge endpoint:
CONFIG=$(cat ~/.config/paypilot/config.json)
API=$(echo $CONFIG | jq -r '.api_url')
TOKEN=$(echo $CONFIG | jq -r '.token')
curl -s "$API/v1/payments/charge" -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"amount":500.00,"token":"VAULT_ID","description":"Consulting , January"}'
for high-value or flagged transactions, enable 3D Secure:
curl -s "$API/v1/payments/charge" -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"amount":2500.00,"token":"VAULT_ID","description":"Premium service","three_d_secure":true}'
inputs: amount, customer email, description outputs: payment link sent, confirmation message
curl -s "$API/v1/payments/invoice" -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"amount":500.00,"email":"john@example.com","description":"Consulting , January"}'
inputs: transaction_id, optional amount (for partial refund) outputs: refund_id, status, new balance
full refund:
curl -s "$API/v1/payments/refund" -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"transaction_id":"TXN_ID"}'
partial refund:
curl -s "$API/v1/payments/refund" -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"transaction_id":"TXN_ID","amount":50.00}'
same-day void (before settlement):
curl -s "$API/v1/payments/void" -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"transaction_id":"TXN_ID"}'
inputs: customer first_name, last_name, email outputs: vault_id, customer_id (card details entered in secure form, never handled by agent)
curl -s "$API/v1/vault/add" -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"first_name":"John","last_name":"Smith","email":"john@example.com"}'
customer is directed to secure form to enter card data. agent never sees raw card numbers.
inputs: vault_id, amount, description outputs: transaction_id, status, verification
curl -s "$API/v1/vault/charge" -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"vault_id":"VAULT_ID","amount":99.00,"description":"Monthly service"}'
inputs: vault_id, plan_id, amount, interval (monthly, weekly, etc.) outputs: subscription_id, status, next_billing_date
create subscription:
curl -s "$API/v1/subscriptions" -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"vault_id":"VAULT_ID","plan_id":"monthly_99","amount":99.00,"interval":"monthly"}'
cancel subscription:
curl -s "$API/v1/subscriptions/SUB_ID" -X DELETE \
-H "Authorization: Bearer $TOKEN"
inputs: none outputs: list of transactions or summary metrics
view all transactions:
curl -s "$API/v1/transactions" -H "Authorization: Bearer $TOKEN" | jq .
sales summary (current period):
curl -s "$API/v1/transactions/summary" -H "Authorization: Bearer $TOKEN" | jq .
inputs: optional rule_type, threshold, action outputs: fraud summary, list of active rules, rule_id on creation
view fraud summary (last 30 days):
curl -s "$API/v1/fraud/summary" -H "Authorization: Bearer $TOKEN" | jq .
list active fraud rules:
curl -s "$API/v1/fraud/rules" -H "Authorization: Bearer $TOKEN" | jq .
create fraud rule (e.g., flag transactions over $5000):
curl -s "$API/v1/fraud/rules" -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"rule_type":"max_amount","threshold":"5000","action":"flag"}'
delete a fraud rule:
curl -s "$API/v1/fraud/rules/RULE_ID" -X DELETE \
-H "Authorization: Bearer $TOKEN"
supported rule types: max_amount, min_amount, velocity_limit. supported actions: flag (alert), block (reject), review (hold).
inputs: user password (prompted only on 401 or token refresh request) outputs: new jwt token, updated config file
if any request returns 401, prompt for password and re-login:
read -sp "enter your password to refresh token: " USER_PASSWORD
echo ""
LOGIN=$(curl -s "$API/v1/auth/login" -X POST \
-H "Content-Type: application/json" \
-d "{\"email\":\"$(echo $CONFIG | jq -r '.email')\",\"password\":\"$USER_PASSWORD\"}")
NEW_TOKEN=$(echo $LOGIN | jq -r '.access_token')
TMP=$(mktemp)
chmod 600 "$TMP"
jq --arg t "$NEW_TOKEN" '.token = $t' ~/.config/paypilot/config.json > "$TMP" && mv "$TMP" ~/.config/paypilot/config.json
chmod 600 ~/.config/paypilot/config.json
password is never stored. token is updated in config and request retried.
inputs: business_name, contact_name, email, phone, business_type outputs: lead saved in AGMS system, application link sent to user
if user has no gateway account, collect info conversationally and save lead:
curl -s "https://paypilot.agms.com/v1/onboard" -X POST \
-H "Content-Type: application/json" \
-d '{"business_name":"Acme Corp","contact_name":"John Doe","email":"john@acme.com","phone":"555-1234","business_type":"retail"}'
send user this message:
"great. to finish your application, complete the form here: https://agms.com/get-started/ it takes about 5-10 minutes. you'll need your business address, tax id, and banking info. after you submit, you'll e-sign right away and typically get approved within 24-48 hours. once approved, come back and i'll set up your payment processing in seconds."
note: agent never collects ssn, tax id, bank account numbers, or other sensitive pii. those go through the secure agms form only.
if config exists and token is valid: proceed directly to step 5 (process transaction). skip registration and login.
if config missing or token expired (401 response): prompt for email and password, run login (step 2), update config (step 4), then retry the original request.
if user has no gateway account: start merchant onboarding flow (step 14). collect info, save lead, send application link. do not attempt to process payments until approval confirmed.
if transaction amount exceeds $2000 or fraud score is high: automatically enable 3D Secure (step 5). wait for customer authentication before completing charge.
if refund requested on transaction settled more than 180 days ago: return error and guide user to contact AGMS support. agent cannot process refunds on very old transactions.
if user requests subscription but no vault_id provided: first tokenize card (step 8), then create subscription (step 10).
if api returns 429 (rate limit): back off exponentially (1s, 2s, 4s) and retry up to 3 times. if still rate limited, inform user to retry later.
if api returns 5xx (server error): retry with exponential backoff (1s, 2s, 4s). if still failing after 3 attempts, inform user and suggest contacting AGMS support.
if network timeout or connection error: verify https connectivity and retry. if persistent, inform user to check internet connection and try again.
if user asks to view raw card data or store card numbers: decline. explain that PayPilot stores only vault tokens (opaque identifiers). raw card data is collected via secure form only and never exposed to the agent.
charge success
{
"transaction_id": "txn_abc123",
"status": "complete",
"amount": 500.00,
"currency": "USD",
"risk": {"score": "low", "flags": []},
"verification": {"avs": "Y", "cvv": "M"},
"timestamp": "2026-03-15T12:00:00Z"
}
charge with 3D Secure
{
"transaction_id": "txn_abc123",
"status": "complete",
"amount": 2500.00,
"currency": "USD",
"three_d_secure": true,
"three_d_secure_status": "authenticated",
"risk": {"score": "low", "flags": []},
"verification": {"avs": "Y", "cvv": "M"}
}
invoice sent
{
"invoice_id": "inv_123",
"email": "john@example.com",
"amount": 500.00,
"payment_link": "https://paypilot.agms.com/pay/inv_123",
"status": "sent",
"expires_in_days": 30
}
refund processed
{
"refund_id": "ref_123",
"transaction_id": "txn_abc123",
"amount": 500.00,
"status": "complete",
"timestamp": "2026-03-15T12:05:00Z"
}
subscription created
{
"subscription_id": "sub_123",
"vault_id": "vault_abc",
"amount": 99.00,
"interval": "monthly",
"status": "active",
"next_billing_date": "2026-04-15"
}
fraud rule created
{
"rule_id": "rule_123",
"rule_type": "max_amount",
"threshold": "5000",
"action": "flag",
"status": "active",
"created_at": "2026-03-15T00:00:00Z"
}
fraud summary
{
"period": "last_30_days",
"total_transactions": 45,
"flagged_transactions": 0,
"blocked_transactions": 0,
"fraud_rate": "0.00%",
"active_rules": 1
}
sales summary
{
"period": "current_month",
"total_transactions": 23,
"gross_sales": 4750.00,
"refunds": 150.00,
"net_sales": 4600.00,
"currency": "USD"
}
error response
{
"error": "payment_declined",
"message": "insufficient funds",
"transaction_id": null,
"status_code": 400
}
all responses use https and json format.
charge succeeds: display "✅ payment of $500.00 processed. transaction id: abc123." include transaction_id for reference.
charge fails: display "❌ payment declined. want to try a different method or send a payment link instead?" offer alternatives.
invoice sent: display "📧 payment link for $500.00 sent to john@example.com." confirm email address in message.
refund processed: display "✅ refund of $500.00 issued. refund id: ref_123." include refund_id for tracking.
subscription created: display "✅ subscription active. $99.00 will bill monthly. next charge: 2026-04-15." confirm interval and next date.
fraud rule created: display "✅ fraud rule created. max $5,000 per transaction. action: flag." confirm rule type and action.
fraud summary displayed: display "🛡️ last 30 days: 45 transactions, 0 flagged, 0 blocked. 1 active rule (max $5,000). fraud rate: 0.00%"
token expired/401 error: display "🔐 your session expired. enter your password to refresh." prompt for password, re-login, update config, retry request. confirm refresh with "✅ token refreshed. retrying..."
config created successfully: display "✅ paypilot configured. ready to process payments." confirm api_url, email, and token are saved.
onboarding initiated: display "✅ your info has been saved. complete the application at https://agms.com/get-started/. typically approved within 24-48 hours. come back once you're approved."
rate limit or server error: display "⚠️ service temporarily unavailable. retrying in {n} seconds..." wait and retry. after max retries, display "❌ unable to process. please try again later or contact support."