Skip to content

Commit 11b3804

Browse files
authored
Merge pull request #228 from tyllenb/main
adding payman
2 parents d77ae7d + 168e6c0 commit 11b3804

5 files changed

Lines changed: 333 additions & 2 deletions

File tree

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
import os
2+
from typing import Dict, List, Optional, Union, Literal
3+
from paymanai import Paymanai
4+
5+
# Initialize Payman client
6+
PAYMAN_API_SECRET = os.getenv("PAYMAN_API_SECRET")
7+
PAYMAN_ENVIRONMENT = os.getenv("PAYMAN_ENVIRONMENT", "sandbox")
8+
9+
client = Paymanai(
10+
x_payman_api_secret=PAYMAN_API_SECRET,
11+
environment=PAYMAN_ENVIRONMENT
12+
)
13+
14+
def send_payment(
15+
amount_decimal: float,
16+
payment_destination_id: str,
17+
customer_email: Optional[str] = None,
18+
customer_id: Optional[str] = None,
19+
customer_name: Optional[str] = None,
20+
memo: Optional[str] = None
21+
) -> Dict:
22+
"""
23+
Send USD from the agent's wallet to a pre-created payment destination.
24+
25+
Args:
26+
amount_decimal: Amount to send in USD (e.g. 10.00 for $10.00)
27+
payment_destination_id: ID of the pre-created payment destination
28+
customer_email: Optional email address of the customer
29+
customer_id: Optional ID of the customer
30+
customer_name: Optional name of the customer
31+
memo: Optional note or memo for the payment
32+
33+
Returns:
34+
Dictionary containing payment details
35+
"""
36+
try:
37+
return client.payments.send_payment(
38+
amount_decimal=amount_decimal,
39+
payment_destination_id=payment_destination_id,
40+
customer_email=customer_email,
41+
customer_id=customer_id,
42+
customer_name=customer_name,
43+
memo=memo
44+
)
45+
except Exception as e:
46+
return {"error": f"Failed to send payment: {str(e)}"}
47+
48+
def search_destinations(
49+
name: Optional[str] = None,
50+
customer_id: Optional[str] = None,
51+
contact_email: Optional[str] = None,
52+
) -> List[Dict]:
53+
"""
54+
Search for existing payment destinations by name, customer, or email.
55+
56+
Args:
57+
name: Optional name of the payment destination
58+
customer_id: Optional customer ID who owns the destination
59+
contact_email: Optional contact email to search for
60+
61+
Returns:
62+
List of matching payment destinations with their IDs
63+
"""
64+
try:
65+
return client.payments.search_destinations(
66+
name=name,
67+
customer_id=customer_id,
68+
contact_email=contact_email
69+
)
70+
except Exception as e:
71+
return [{"error": f"Failed to search destinations: {str(e)}"}]
72+
73+
def create_payee(
74+
type: Literal["US_ACH", "PAYMAN_AGENT"],
75+
name: str,
76+
customer_id: Optional[str] = None,
77+
account_holder_name: Optional[str] = None,
78+
account_holder_type: Optional[Literal["individual", "business"]] = None,
79+
account_number: Optional[str] = None,
80+
routing_number: Optional[str] = None,
81+
account_type: Optional[Literal["checking", "savings"]] = None,
82+
payman_agent_id: Optional[str] = None,
83+
contact_details: Optional[Dict] = None
84+
) -> Dict:
85+
"""
86+
Create a new payment destination for future USD payments.
87+
88+
Args:
89+
type: Type of payment destination ("US_ACH" or "PAYMAN_AGENT")
90+
name: Name for the payment destination
91+
customer_id: Customer ID who owns this destination (required for US_ACH)
92+
account_holder_name: Name of the account holder (required for US_ACH)
93+
account_holder_type: Type of account holder ("individual" or "business") (required for US_ACH)
94+
account_number: Bank account number (required for US_ACH)
95+
routing_number: Bank routing number (required for US_ACH)
96+
account_type: Type of bank account ("checking" or "savings") (required for US_ACH)
97+
payman_agent_id: The unique ID of the receiving agent (required for PAYMAN_AGENT)
98+
contact_details: Optional dictionary containing contact information
99+
100+
Returns:
101+
Dictionary containing the created payee details
102+
"""
103+
try:
104+
params = {
105+
"type": type,
106+
"name": name,
107+
"contact_details": contact_details
108+
}
109+
110+
if type == "US_ACH":
111+
params.update({
112+
"customer_id": customer_id,
113+
"account_holder_name": account_holder_name,
114+
"account_holder_type": account_holder_type,
115+
"account_number": account_number,
116+
"routing_number": routing_number,
117+
"account_type": account_type
118+
})
119+
elif type == "PAYMAN_AGENT":
120+
params.update({
121+
"payman_agent_id": payman_agent_id
122+
})
123+
124+
return client.payments.create_payee(params)
125+
except Exception as e:
126+
return {"error": f"Failed to create payee: {str(e)}"}
127+
128+
def initiate_customer_deposit(
129+
amount_decimal: float,
130+
customer_id: str,
131+
customer_email: Optional[str] = None,
132+
customer_name: Optional[str] = None,
133+
fee_mode: Optional[Literal["INCLUDED_IN_AMOUNT", "ADD_TO_AMOUNT"]] = None,
134+
memo: Optional[str] = None,
135+
wallet_id: Optional[str] = None
136+
) -> Dict:
137+
"""
138+
Generate a checkout link for customer USD deposits.
139+
140+
Args:
141+
amount_decimal: Amount to deposit in USD (e.g. 10.00 for $10.00)
142+
customer_id: ID of the customer to deposit funds for
143+
customer_email: Optional email address of the customer
144+
customer_name: Optional name of the customer
145+
fee_mode: How to handle processing fees ("INCLUDED_IN_AMOUNT" or "ADD_TO_AMOUNT")
146+
memo: Optional memo for the transaction
147+
wallet_id: Optional ID of specific wallet to deposit to
148+
149+
Returns:
150+
Dictionary containing the checkout URL
151+
"""
152+
try:
153+
response = client.payments.initiate_customer_deposit(
154+
amount_decimal=amount_decimal,
155+
customer_id=customer_id,
156+
customer_email=customer_email,
157+
customer_name=customer_name,
158+
fee_mode=fee_mode,
159+
memo=memo,
160+
wallet_id=wallet_id
161+
)
162+
return response
163+
except Exception as e:
164+
return {"error": f"Failed to generate deposit link: {str(e)}"}
165+
166+
def get_customer_balance(
167+
customer_id: str,
168+
currency: Literal["USD"] = "USD"
169+
) -> Dict:
170+
"""
171+
Check customer's available USD balance.
172+
173+
Args:
174+
customer_id: ID of the customer to check balance for
175+
currency: Currency code (always USD)
176+
177+
Returns:
178+
Dictionary containing balance information
179+
"""
180+
try:
181+
response = client.balances.get_customer_balance(customer_id, currency)
182+
return {
183+
"spendable_balance": response,
184+
"currency": currency,
185+
"customer_id": customer_id
186+
}
187+
except Exception as e:
188+
return {"error": f"Failed to get customer balance: {str(e)}"}
189+
190+
def get_spendable_balance(
191+
currency: Literal["USD"] = "USD"
192+
) -> Dict:
193+
"""
194+
Check agent's available USD balance.
195+
196+
Args:
197+
currency: Currency code (always USD)
198+
199+
Returns:
200+
Dictionary containing balance information
201+
"""
202+
try:
203+
response = client.balances.get_spendable_balance(currency)
204+
return {
205+
"spendable_balance": response,
206+
"currency": currency
207+
}
208+
except Exception as e:
209+
return {"error": f"Failed to get spendable balance: {str(e)}"}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "payman",
3+
"category": "financial-infra",
4+
"tools": [
5+
"send_payment",
6+
"search_available_payees",
7+
"add_payee",
8+
"ask_for_money",
9+
"get_balance"
10+
],
11+
"url": "https://www.paymanai.com",
12+
"cta": "Setup your Agents Payman account at https://app.paymanai.com",
13+
"env": {
14+
"PAYMAN_API_SECRET": null,
15+
"PAYMAN_ENVIRONMENT": null
16+
},
17+
"dependencies": ["paymanai>=2.1.0"]
18+
}

docs/llms.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,7 @@ description: 'AgentStack tools from community contributors'
950950

951951
## Application Specific
952952
- [Stripe](/tools/tool/stripe)
953-
953+
- [Payman](/tools/tool/payman)
954954
<CardGroup cols={1}>
955955
<Card
956956
title="Core Tools"

docs/tools/community.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ description: 'AgentStack tools from community contributors'
3434

3535
## Application Specific
3636
- [Stripe](/tools/tool/stripe)
37-
37+
- [Payman](/tools/tool/payman)
3838
<CardGroup cols={1}>
3939
<Card
4040
title="Core Tools"

docs/tools/tool/payman.mdx

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
---
2+
title: Payman
3+
description: Trust your AI Agents to deal with money.
4+
icon: dollar-sign
5+
---
6+
7+
## Description
8+
9+
Payman enables your agents to handle USD payments, manage payment destinations, and handle customer deposits. This tool allows agents to send payments, create payees, manage balances, and generate deposit links for customers.
10+
11+
## Example
12+
13+
Add the Payman tool with
14+
```bash
15+
agentstack tools add payman
16+
```
17+
18+
Set up your environment variables:
19+
```env
20+
PAYMAN_API_SECRET=your_api_secret_here
21+
PAYMAN_ENVIRONMENT=sandbox # or "production" for live environment
22+
```
23+
24+
## Features
25+
26+
### Send Payments
27+
Send USD payments to pre-created payment destinations:
28+
```python
29+
response = payman.send_payment(
30+
amount_decimal=50.00,
31+
payment_destination_id="dest_123",
32+
customer_name="John Doe",
33+
memo="Invoice payment"
34+
)
35+
```
36+
37+
### Create Payment Destinations
38+
Set up new payment destinations for US ACH or Payman agent transfers:
39+
```python
40+
# Create US ACH payment destination
41+
ach_payee = payman.create_payee(
42+
type="US_ACH",
43+
name="John's Bank Account",
44+
customer_id="cust_123",
45+
account_holder_name="John Doe",
46+
account_holder_type="individual",
47+
account_number="1234567890",
48+
routing_number="021000021",
49+
account_type="checking"
50+
)
51+
52+
# Create Payman agent destination
53+
agent_payee = payman.create_payee(
54+
type="PAYMAN_AGENT",
55+
name="Partner Agent",
56+
payman_agent_id="agent_123"
57+
)
58+
```
59+
60+
### Customer Deposits
61+
Generate checkout links for customer deposits:
62+
```python
63+
deposit_link = payman.initiate_customer_deposit(
64+
amount_decimal=100.00,
65+
customer_id="cust_123",
66+
customer_email="customer@example.com",
67+
fee_mode="ADD_TO_AMOUNT"
68+
)
69+
```
70+
71+
### Balance Management
72+
Check available balances:
73+
```python
74+
# Check agent balance
75+
agent_balance = payman.get_spendable_balance()
76+
77+
# Check customer balance
78+
customer_balance = payman.get_customer_balance(
79+
customer_id="cust_123"
80+
)
81+
```
82+
83+
### Search Payment Destinations
84+
Find existing payment destinations:
85+
```python
86+
destinations = payman.search_destinations(
87+
name="John",
88+
customer_id="cust_123",
89+
contact_email="john@example.com"
90+
)
91+
```
92+
93+
## Available Functions
94+
95+
The Payman tool provides the following core functions:
96+
97+
- `send_payment()`: Send USD payments to payment destinations
98+
- `create_payee()`: Create new payment destinations (US ACH or Payman Agent)
99+
- `search_destinations()`: Search for existing payment destinations
100+
- `initiate_customer_deposit()`: Generate customer deposit checkout links
101+
- `get_customer_balance()`: Check customer USD balance
102+
- `get_spendable_balance()`: Check agent USD balance
103+
104+
For detailed function parameters and usage, refer to the function docstrings in your IDE or the Payman API documentation.

0 commit comments

Comments
 (0)