Logo
ClawHub Skills Lib
HomeCategoriesUse CasesTrendingBlog
HomeCategoriesUse CasesTrendingBlog
ClawHub Skills Lib
ClawHub Skills Lib

Browse 20,000+ community-built AI agent skills for OpenClaw. Updated daily from clawhub.ai.

Explore

  • Home
  • Trending
  • Use Cases
  • Blog

Categories

  • Development
  • AI & Agents
  • Productivity
  • Communication
  • Data & Research
  • Business
  • Platforms
  • Lifestyle
  • Education
  • Design

Use Cases

  • Security Auditing
  • Workflow Automation
  • Finance & Fintech
  • MCP Integration
  • Crypto Trading
  • Web3 & DeFi
  • Data Analysis
  • Social Media
  • 中文平台技能
  • All Use Cases →
© 2026 ClawHub Skills Lib. All rights reserved.Built with Next.js · Supabase · Prisma
Home/Blog/Stripe API Skill: Managed OAuth for Payment Workflows in AI Agents
skill-spotlightfinance-accstripe-apiclawhubopenclawstripepaymentsbilling

Stripe API Skill: Managed OAuth for Payment Workflows in AI Agents

March 10, 2026·7 min read

With over 17,000 downloads, the stripe-api skill by @byungkyu is the leading Stripe integration on ClawHub. It gives Claude access to the full Stripe API — customers, subscriptions, invoices, products, prices, charges, payment intents, refunds, and coupons — through Maton's managed OAuth gateway. One API key, no Stripe secret keys stored anywhere, and the same pattern extends to 100+ other APIs.

The Problem It Solves

Integrating Stripe directly means managing secret API keys: storing them in environment variables, rotating them when compromised, and ensuring they never end up in logs or chat history. When an AI agent is involved, there's an additional concern — Claude sees everything in its context, including any credentials that appear in requests or responses.

Maton's gateway solves this with a level of indirection. You connect your Stripe account to Maton via OAuth, then communicate with Stripe through Maton's proxy. Claude only ever sees your MATON_API_KEY, never your Stripe secret key. Maton injects the appropriate Stripe OAuth token server-side before forwarding requests.

Architecture

The skill routes all Stripe API calls through Maton's gateway:

Claude → Maton gateway → Stripe API
        (https://gateway.maton.ai/stripe/v1/...)

Base URL pattern:

https://gateway.maton.ai/stripe/v1/{stripe-endpoint}

This mirrors the native Stripe API URL structure (https://api.stripe.com/v1/{endpoint}) — if you know Stripe's API, you already know this skill's endpoints.

Authentication: One header, everywhere:

Authorization: Bearer $MATON_API_KEY

Setup

  1. Create a Maton account at maton.ai and copy your API key from maton.ai/settings
  2. Connect your Stripe account via OAuth at ctrl.maton.ai
  3. Set the environment variable:
export MATON_API_KEY="your_maton_api_key"

Install the skill:

clawdbot install stripe-api

Core Operations

Customers

import os, requests
 
base = "https://gateway.maton.ai/stripe"
headers = {"Authorization": f"Bearer {os.environ['MATON_API_KEY']}"}
 
# List customers
r = requests.get(f"{base}/v1/customers?limit=10", headers=headers)
customers = r.json()["data"]
 
# Create a customer
r = requests.post(f"{base}/v1/customers",
    headers=headers,
    data={"email": "user@example.com", "name": "Jane Doe"})
customer = r.json()
 
# Get a specific customer
r = requests.get(f"{base}/v1/customers/cus_xxx", headers=headers)

Note: Stripe's API uses application/x-www-form-urlencoded for POST requests, not JSON.

Products and Prices

# Create a product
r = requests.post(f"{base}/v1/products",
    headers=headers,
    data={"name": "Pro Plan", "type": "service"})
product_id = r.json()["id"]  # prod_xxx
 
# Create a price for that product ($19.99/month)
r = requests.post(f"{base}/v1/prices",
    headers=headers,
    data={
        "product": product_id,
        "unit_amount": 1999,
        "currency": "usd",
        "recurring[interval]": "month"
    })
price_id = r.json()["id"]  # price_xxx

Amounts are always in the smallest currency unit: cents for USD, pence for GBP, etc.

Subscriptions

# Create a subscription
r = requests.post(f"{base}/v1/subscriptions",
    headers=headers,
    data={"customer": "cus_xxx", "items[0][price]": "price_xxx"})
subscription = r.json()
 
# Filter subscriptions by status
r = requests.get(f"{base}/v1/subscriptions?status=past_due&customer=cus_xxx",
    headers=headers)
 
# Cancel a subscription
r = requests.delete(f"{base}/v1/subscriptions/sub_xxx", headers=headers)

Invoices

# List unpaid invoices
r = requests.get(f"{base}/v1/invoices?status=open&limit=20", headers=headers)
 
# Finalize a draft invoice
r = requests.post(f"{base}/v1/invoices/in_xxx/finalize", headers=headers)
 
# Trigger payment on a finalized invoice
r = requests.post(f"{base}/v1/invoices/in_xxx/pay", headers=headers)
 
# Void an invoice
r = requests.post(f"{base}/v1/invoices/in_xxx/void", headers=headers)

Each paid invoice includes hosted_invoice_url (web) and invoice_pdf links.

Charges and Payment Intents

# List recent charges
r = requests.get(f"{base}/v1/charges?limit=10&customer=cus_xxx", headers=headers)
 
# Create a payment intent
r = requests.post(f"{base}/v1/payment_intents",
    headers=headers,
    data={"amount": 5000, "currency": "usd", "customer": "cus_xxx",
          "payment_method_types[]": "card"})
 
# Confirm a payment intent
r = requests.post(f"{base}/v1/payment_intents/pi_xxx/confirm", headers=headers)

Refunds

# Full refund
r = requests.post(f"{base}/v1/refunds",
    headers=headers,
    data={"charge": "ch_xxx"})
 
# Partial refund ($10.00)
r = requests.post(f"{base}/v1/refunds",
    headers=headers,
    data={"charge": "ch_xxx", "amount": 1000})

Coupons

# Create a 25% off coupon (one-time use)
r = requests.post(f"{base}/v1/coupons",
    headers=headers,
    data={"percent_off": 25, "duration": "once"})
 
# $5 off forever
r = requests.post(f"{base}/v1/coupons",
    headers=headers,
    data={"amount_off": 500, "currency": "usd", "duration": "forever"})

Pagination

Stripe uses cursor-based pagination. To page through results:

def get_all_customers():
    all_customers = []
    last_id = None
    while True:
        params = {"limit": 100}
        if last_id:
            params["starting_after"] = last_id
        r = requests.get(f"{base}/v1/customers", headers=headers, params=params)
        data = r.json()
        all_customers.extend(data["data"])
        if not data["has_more"]:
            break
        last_id = data["data"][-1]["id"]
    return all_customers

Multiple Stripe Accounts

If you manage multiple Stripe accounts, connect each one at Maton's control panel and specify which connection to use per request:

# List your connections
r = requests.get("https://ctrl.maton.ai/connections?app=stripe&status=ACTIVE", headers=headers)
 
# Use a specific connection
r = requests.get(f"{base}/v1/customers",
    headers={
        "Authorization": f"Bearer {os.environ['MATON_API_KEY']}",
        "Maton-Connection": "c3c82a73-4c86-4c73-8ebd-1f325212fde6"
    })

If Maton-Connection is omitted, Maton uses the default (oldest active) connection.

Stripe API vs. stripe-api Skill

AspectDirect Stripe APIstripe-api skill (via Maton)
Credentials in agent contextStripe secret keyMaton API key only
Multiple accountsSeparate keysOne key + connection header
OAuth token rotationManualAutomatic via Maton
Extends to other APIs❌✅ 100+ via api-gateway
API coverageFull StripeFull Stripe (same endpoints)
LatencyDirect+1 proxy hop

Key Resource ID Prefixes

Stripe's IDs are self-describing:

PrefixResource
cus_Customer
prod_Product
price_Price
sub_Subscription
in_Invoice
ch_Charge
pi_Payment Intent
pm_Payment Method
re_Refund

Practical Tips

  1. Use api-gateway for other services. The same Maton API key and OAuth pattern applies to 100+ APIs (Slack, HubSpot, Salesforce, Google Workspace, etc.) via the api-gateway skill. If you're already using Maton for Stripe, you have access to the full catalog.

  2. Amounts in cents, not dollars. This is Stripe's convention, not Maton's. unit_amount: 1999 = $19.99 USD. Always double-check when creating prices or charges.

  3. POST uses form-encoding, not JSON. Stripe's API uses application/x-www-form-urlencoded for writes. In Python's requests, this means using data={} (form) not json={} (JSON body). Nested params use bracket notation: recurring[interval]=month.

  4. Use -g flag with curl for bracket params. When using curl with nested parameters, add -g to disable glob expansion: curl -g "...?items[0][price]=price_xxx".

  5. Filter subscriptions by status for churn analysis. status=past_due catches failed renewals, status=canceled shows churn. These two queries are often the starting point for billing health checks.

  6. Finalize then pay for manual invoice workflows. Draft invoices won't charge customers. Call /finalize to lock the invoice, then /pay to collect payment. Or use Stripe's automatic collection by enabling auto_advance on invoices.

Considerations

  • Maton is an intermediary: Your Stripe connection lives in Maton's OAuth system. If Maton experiences downtime, Stripe API calls through this skill will fail.
  • Proxy latency: Each request adds one network hop through gateway.maton.ai. For high-volume or latency-sensitive operations, measure impact against direct Stripe API calls.
  • Account verification required: Connecting Stripe to Maton requires completing the Stripe OAuth flow in a browser. This can't be done programmatically — it's a one-time manual step per Stripe account.
  • No webhook support: This skill handles outbound API calls. Stripe webhooks (incoming events) require a separate endpoint — the skill doesn't handle event subscriptions.
  • Stripe test mode: Use Stripe test mode credentials during development. Test and live are separate Stripe accounts from Maton's perspective — you'll need separate Maton connections for each.

The Bigger Picture

The stripe-api skill represents a broader pattern: managed OAuth gateways that let AI agents access third-party services without ever seeing actual service credentials. Maton extends this to 100+ APIs using the same model — one API key, many services, credentials handled server-side.

For teams building AI agents that need to touch billing, payment history, or subscription state as part of a broader workflow, this approach avoids the credential management problem that normally creates friction between AI systems and sensitive financial APIs.


View the skill on ClawHub: stripe-api

← Back to Blog