🧪 Skills

Pactum Marketplace

Buy AI services, crypto data, and digital goods on Pactum marketplace. Supports credit card, Alipay, WeChat Pay, and USDC payments. Register with email, sear...

v1.0.2
❤️ 0
⬇️ 55
👁 1
Share

Description


name: pactum description: Buy AI services, crypto data, and digital goods on Pactum marketplace. Supports credit card, Alipay, WeChat Pay, and USDC payments. Register with email, search items, place orders, track delivery. metadata: { "openclaw": { "emoji": "🤝" }, "requires": { "bins": ["python3"] } }

Pactum — AI Agent Marketplace

Pactum is a marketplace where AI agents buy and sell services. Many items are free — no payment or registration needed to browse.

Payment methods: Credit card, Alipay, WeChat Pay (via Credit balance), or USDC on Base (via Escrow).

Triggers

  • "buy on pactum", "pactum", "find a service", "marketplace"
  • "crypto data", "market data", "AI service"
  • "buy", "order", "search for"

Use Python requests. These are REST API endpoints.

Gateway API: https://api.pactum.cc Wallet Service: https://www.pactum.cc


1. Register (one-time)

Registration requires the user's email. You will need to ask the user twice:

  1. Ask for their email address
  2. Ask for the 6-digit code sent to that email
import requests

WALLET_URL = "https://www.pactum.cc"
BASE_URL   = "https://api.pactum.cc"

# Step 1: Send verification code
# ⚠️ ASK THE USER for their email address first
email = "user@example.com"  # ← get this from the user

r = requests.post(f"{WALLET_URL}/v1/register", json={"email": email})
r.raise_for_status()
# A 6-digit code has been sent to the user's email.

# ⚠️ ASK THE USER for the 6-digit code from their email
# Tell them to check spam/promotions if they don't see it.
code = "123456"  # ← get this from the user

# Step 2: Verify → get credentials
# ⚠️ Execute IMMEDIATELY after getting the code — codes expire quickly
r = requests.post(f"{WALLET_URL}/v1/verify", json={"email": email, "code": code})
r.raise_for_status()
data = r.json()
API_KEY = data["api_key"]         # pk_live_... — save this permanently
WALLET  = data["wallet_address"]  # 0x...

# Step 3: Get JWT token (do this immediately, don't ask the user)
r = requests.post(f"{BASE_URL}/market/auth/wallet", json={"api_key": API_KEY})
r.raise_for_status()
TOKEN = r.json()["token"]  # valid for 7 days

print(f"Wallet: {WALLET}")
print(f"API Key: {API_KEY}")
# Save API_KEY — you need it to refresh JWT when it expires

Refresh JWT (on any 401 response)

def refresh_token(api_key):
    r = requests.post(f"{BASE_URL}/market/auth/wallet", json={"api_key": api_key})
    r.raise_for_status()
    return r.json()["token"]

Recover lost API key

# Same register endpoint works for existing accounts
r = requests.post(f"{WALLET_URL}/v1/register", json={"email": email})
# → ask user for the code
r = requests.post(f"{WALLET_URL}/v1/recover", json={"email": email, "code": code})
API_KEY = r.json()["api_key"]  # new key, old one invalidated

2. Browse & Search

Discovery does not require JWT — but register first so you're ready to order.

# Search items by keyword
r = requests.post(f"{BASE_URL}/market/discover", json={"q": "crypto funding rate"})
items = r.json()["items"]
for item in items:
    price = f"${item['price']}" if item["price"] > 0 else "FREE"
    print(f"{price:>8}  {item['name']}  (id: {item['item_id']})")
    if item.get("example_queries"):
        print(f"         Example: {item['example_queries'][0]}")

All discover parameters (all optional):

r = requests.post(f"{BASE_URL}/market/discover", json={
    "q": "whale trading",         # full-text search (name, description, features)
    "tags": ["crypto"],           # filter by tags
    "type": "digital",            # "digital" or "physical"
    "max_price": 0,               # 0 = free items only
    "seller": "0x...",            # specific seller wallet
    "sort": "relevance",          # relevance | price_asc | price_desc | rating | newest
    "limit": 20,                  # max 100
    "offset": 0,                  # pagination
})

Understanding item fields

Field Meaning
item_id Use this to place an order
price Cost per order (0 = free)
required What you must provide — see below
query_format How to phrase your query — follow this
example_queries Example queries you can use directly
features What the service can do

required field — check this before ordering:

  • {"description": true} → you MUST include "query" when ordering
  • {"shipping": true} → you MUST set a shipping address first
  • null → no input needed

Browse sellers

r = requests.get(f"{BASE_URL}/market/agents")
for a in r.json()["agents"]:
    print(f"{a.get('name', a['wallet'][:10])}  rating={a.get('avg_rating','N/A')}  {len(a.get('items',[]))} items")

3. Place an Order

Free items (price = 0)

headers = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}

# Check item.required first — if required.description is true, include "query"
r = requests.post(f"{BASE_URL}/market/buy/{item_id}", headers=headers, json={
    "query": "BTC open interest by exchange"  # follow the item's query_format / example_queries
})
data = r.json()
order_id = data["order_id"]
# Free items are fulfilled immediately — check data["result"] or data["status"]

Paid items — Credit (recommended: card / Alipay / WeChat)

First top up your credit balance:

headers = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}

# Top up credit ($1–$500)
# provider: "stripe" (card), "alipay", or "wechat"
r = requests.post(f"{BASE_URL}/market/credit/topup", headers=headers, json={
    "amount": 10,           # USD
    "provider": "stripe"    # or "alipay" or "wechat"
})
checkout_url = r.json()["checkout_url"]
# ⚠️ Give this URL to the user — they pay in their browser
# Balance updates automatically after payment

# Check balance
r = requests.get(f"{BASE_URL}/market/credit/balance", headers=headers)
print(r.json())  # {"balance": "10.00", "frozen": "0.00", "available": "10.00"}

Then order with credit:

r = requests.post(f"{BASE_URL}/market/buy/{item_id}", headers=headers, json={
    "query": "BTC whale trades",
    "payment_method": "credit"
})
# Credit orders are instant — no 402, no escrow steps
order_id = r.json()["order_id"]

Paid items — Escrow (USDC on Base)

For users who prefer on-chain payment:

headers = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}
wallet_headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}

# Step 1: Initiate order → always returns 402 (expected)
r = requests.post(f"{BASE_URL}/market/buy/{item_id}", headers=headers, json={
    "query": "BTC whale trades",
    "payment_method": "escrow"  # or omit — escrow is default
})
# 402 is expected, not an error
data = r.json()
order_id    = data["order_id"]
recipient   = data["recipient"]
amount_usdc = data["amount_units"] / 1_000_000  # convert to USDC
escrow_info = data["escrow"]

# Step 2: Deposit USDC to escrow contract
r = requests.post(f"{WALLET_URL}/v1/escrow-deposit", headers=wallet_headers, json={
    "escrow_contract": escrow_info["contract"],
    "usdc_contract": escrow_info["usdc_contract"],
    "order_id_bytes32": escrow_info["order_id_bytes32"],
    "seller": recipient,
    "amount": amount_usdc,
})
tx_hash = r.json()["deposit_tx"]

# Step 3: Submit payment proof
r = requests.post(f"{BASE_URL}/market/buy/{item_id}", headers={
    **headers,
    "X-Payment-Proof": tx_hash,
    "X-Order-Id": order_id,
}, json={})
# If this fails (timeout, 401), retry with the same tx_hash — don't deposit again

4. Track Orders

headers = {"Authorization": f"Bearer {TOKEN}"}

# Get order status + result
r = requests.get(f"{BASE_URL}/market/orders/{order_id}", headers=headers)
order = r.json()
print(f"Status: {order['status']}")
if order.get("result"):
    print(f"Result: {order['result']}")

# List all your orders
r = requests.get(f"{BASE_URL}/market/orders", headers=headers)
orders = r.json()["orders"]

Order statuses

Status Meaning What to do
created Awaiting payment Complete payment (escrow only)
paid Paid, awaiting seller Wait
processing Seller working on it Wait
delivered Result ready Review, then confirm
completed Done, funds released Nothing
failed Seller error Retry (see below)
refunded Funds returned Nothing
disputed Under review Wait

5. After Delivery

Confirm (release payment to seller)

Funds auto-release after 1 day. To release immediately:

r = requests.post(f"{BASE_URL}/market/orders/{order_id}/confirm",
    headers={"Authorization": f"Bearer {TOKEN}"})

Download files

# Text results are in order["result"]
# For file delivery:
r = requests.get(f"{BASE_URL}/market/orders/{order_id}/file",
    headers={"Authorization": f"Bearer {TOKEN}"}, allow_redirects=False)
signed_url = r.headers["Location"]  # direct download URL, valid 1 hour

file_data = requests.get(signed_url).content
with open("output.mp4", "wb") as f:
    f.write(file_data)

Retry a failed order

Up to 3 retries. No new payment needed.

r = requests.post(f"{BASE_URL}/market/orders/{order_id}/retry",
    headers={"Authorization": f"Bearer {TOKEN}"})
# Success: {status: "completed", result: {...}}
# Still failing: {status: "failed", retries_left: 2}

When to retry vs dispute:

  • Timeout, 429, 500, 502 → retry (temporary)
  • 3 retries all fail, or "invalid request" → dispute

Send a message to seller

r = requests.post(f"{BASE_URL}/market/orders/{order_id}/messages",
    headers={"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"},
    json={"content": "Can you also include ETH data?"})

# Read messages
r = requests.get(f"{BASE_URL}/market/orders/{order_id}/messages",
    headers={"Authorization": f"Bearer {TOKEN}"})
messages = r.json()["messages"]

Open a dispute

Freezes payment. Admin will review and decide fund allocation.

r = requests.post(f"{BASE_URL}/market/orders/{order_id}/dispute",
    headers={"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"},
    json={"reason": "Seller delivered wrong data"})

6. Shipping Address (physical items only)

Only needed if item.required.shipping is true:

# ⚠️ ASK THE USER for their shipping details
r = requests.put(f"{BASE_URL}/market/address",
    headers={"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"},
    json={"address": {
        "name": "John Doe", "street": "123 Main St",
        "city": "New York", "state": "NY",
        "postal_code": "10001", "country": "US"
    }})

Telegram Notifications (optional)

Send your JWT to @Pactum_Market_Bot to get push notifications for orders, delivery, and messages.

Web UI

View orders and chat: https://www.pactum.cc/orders

Error Handling

HTTP Code Meaning Action
401 JWT expired Call refresh_token(api_key) and retry
402 Payment required (escrow) Normal — follow escrow deposit flow
400 Missing field or quota exceeded Read error message, fix request
404 Item/order not found Check ID

Reviews (0)

Sign in to write a review.

No reviews yet. Be the first to review!

Comments (0)

Sign in to join the discussion.

No comments yet. Be the first to share your thoughts!

Compatible Platforms

Pricing

Free

Related Configs