Skip to content

Commit

Permalink
added get_payment_status & set_webhook
Browse files Browse the repository at this point in the history
  • Loading branch information
kafkasl committed Feb 10, 2025
1 parent a004322 commit 979cc8b
Show file tree
Hide file tree
Showing 7 changed files with 437 additions and 98 deletions.
74 changes: 70 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ The library provides a
class to handle payments. You can use handle them manually or use the
`as_tools()` method to create tools for autonomous agents.

### Making Payments

Obtain information about your account and perform payments:

``` python
from fewsats.core import *
```
Expand All @@ -49,13 +53,14 @@ fs.payment_methods().json(), fs.balance().json(), fs.me().json()
'exp_month': 12,
'exp_year': 2034,
'is_default': True}],
[{'id': 1, 'balance': 4468, 'currency': 'usd'}],
[{'id': 1, 'balance': 4464, 'currency': 'usd'}],
{'name': 'Pol',
'last_name': 'Alvarez Vecino',
'email': 'pol@fewsats.com',
'billing_info': None,
'id': 1,
'created_at': '2024-08-20T16:13:01.255Z'})
'created_at': '2024-08-20T16:13:01.255Z',
'webhook_url': 'https://example.com/webhook'})

The `pay` method uses the information returned by a [L402
Protocol](https://github.com/l402-protocol/l402?tab=readme-ov-file#402-response-format)
Expand Down Expand Up @@ -92,8 +97,8 @@ l402_offer = {
fs.pay_offer(l402_offer).json()
```

{'id': 118,
'created_at': '2025-02-06T13:57:59.586Z',
{'id': 121,
'created_at': '2025-02-10T11:04:48.083Z',
'status': 'success',
'payment_method': 'lightning'}

Expand All @@ -109,6 +114,67 @@ requires you to specify the amount you are expecting to pay in cents.
This is done for accounting purposes and convenience, but the amount
paid will be the sats in the invoice.

### Getting Paid

Fewsats also provides methods for receiving payments. You can create
offers for receiving payments as follows.

``` python
# Create offers for receiving payments
offers_data = [{
"offer_id": "offer_example",
"amount": 1,
"currency": "USD",
"description": "Receive payment for your service",
"title": "1 Credit Package",
"payment_methods": ["lightning", "stripe"]
}]
r = fs.create_offers(offers_data)
offers = r.json()
offers
```

{'offers': [{'offer_id': 'offer_example',
'amount': 1,
'currency': 'USD',
'description': 'Receive payment for your service',
'title': '1 Credit Package',
'payment_methods': ['lightning', 'stripe'],
'type': 'one-off'}],
'payment_context_token': 'a175fd73-cb68-4a22-8685-b236eff2f1a0',
'payment_request_url': 'http://localhost:8000/v0/l402/payment-request',
'version': '0.2.2'}

You can check if an offer has been paid using the payment context token
as follows.

``` python
fs.get_payment_status(payment_context_token=offers["payment_context_token"]).json()
```

{'payment_context_token': 'a175fd73-cb68-4a22-8685-b236eff2f1a0',
'status': 'pending',
'offer_id': None,
'paid_at': None,
'amount': None,
'currency': None}

If you prefer to be notified whenever an offer is paid, you can set up a
webhook as follows, and we will call it whenever a payment is made.

``` python
r = fs.set_webhook(webhook_url="https://example.com/webhook")
r.json()
```

{'name': 'Pol',
'last_name': 'Alvarez Vecino',
'email': 'pol@fewsats.com',
'billing_info': None,
'id': 1,
'created_at': '2024-08-20T16:13:01.255Z',
'webhook_url': 'https://example.com/webhook'}

### AI Agent Integration

We will show how to enable your AI assistant to handle payments using
Expand Down
3 changes: 3 additions & 0 deletions fewsats/_modidx.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@
'fewsats.core.Fewsats.as_tools': ('core.html#fewsats.as_tools', 'fewsats/core.py'),
'fewsats.core.Fewsats.balance': ('core.html#fewsats.balance', 'fewsats/core.py'),
'fewsats.core.Fewsats.create_offers': ('core.html#fewsats.create_offers', 'fewsats/core.py'),
'fewsats.core.Fewsats.get_payment_details': ('core.html#fewsats.get_payment_details', 'fewsats/core.py'),
'fewsats.core.Fewsats.get_payment_status': ('core.html#fewsats.get_payment_status', 'fewsats/core.py'),
'fewsats.core.Fewsats.me': ('core.html#fewsats.me', 'fewsats/core.py'),
'fewsats.core.Fewsats.pay_lightning': ('core.html#fewsats.pay_lightning', 'fewsats/core.py'),
'fewsats.core.Fewsats.pay_offer': ('core.html#fewsats.pay_offer', 'fewsats/core.py'),
'fewsats.core.Fewsats.payment_info': ('core.html#fewsats.payment_info', 'fewsats/core.py'),
'fewsats.core.Fewsats.payment_methods': ('core.html#fewsats.payment_methods', 'fewsats/core.py'),
'fewsats.core.Fewsats.set_webhook': ('core.html#fewsats.set_webhook', 'fewsats/core.py'),
'fewsats.core.Fewsats.wait_for_settlement': ('core.html#fewsats.wait_for_settlement', 'fewsats/core.py')},
'fewsats.l402': { 'fewsats.l402.L.starstarmap': ('claudette.html#l.starstarmap', 'fewsats/l402.py'),
'fewsats.l402.Offer': ('claudette.html#offer', 'fewsats/l402.py'),
Expand Down
34 changes: 30 additions & 4 deletions fewsats/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,32 @@ def create_offers(self:Fewsats,

# %% ../nbs/00_core.ipynb 30
@patch
def get_payment_details(self:Fewsats,
payment_request_url:str,
offer_id:str,
payment_method:str,
payment_context_token:str,
) -> dict:
data = {"offer_id": offer_id, "payment_method": payment_method, "payment_context_token": payment_context_token}
return httpx.post(payment_request_url, json=data)


# %% ../nbs/00_core.ipynb 33
@patch
def get_payment_status(self:Fewsats,
payment_context_token:str,
) -> dict:
return self._request("GET", f"v0/l402/payment-status?payment_context_token={payment_context_token}")

# %% ../nbs/00_core.ipynb 35
@patch
def set_webhook(self:Fewsats,
webhook_url:str,
) -> dict:
return self._request("POST", f"v0/users/webhook/set", json={"webhook_url": webhook_url})

# %% ../nbs/00_core.ipynb 38
@patch
def pay_offer(self:Fewsats,
l402_offer: Dict, # a dictionary containing the response of an L402 endpoint
payment_method:str = '', # preferred payment method (optional)
Expand All @@ -93,7 +119,7 @@ def pay_offer(self:Fewsats,
data = {"payment_method": payment_method, **l402_offer} if payment_method else l402_offer
return self._request("POST", "v0/l402/purchases/from-offer", json=data)

# %% ../nbs/00_core.ipynb 32
# %% ../nbs/00_core.ipynb 40
@patch
def pay_lightning(self: Fewsats,
invoice: str, # lightning invoice
Expand All @@ -109,14 +135,14 @@ def pay_lightning(self: Fewsats,
}
return self._request("POST", "v0/l402/purchases/lightning", json=data)

# %% ../nbs/00_core.ipynb 37
# %% ../nbs/00_core.ipynb 45
@patch
def payment_info(self:Fewsats,
pid:str): # purchase id
"Retrieve the details of a payment."
return self._request("GET", f"v0/l402/purchases/{pid}")

# %% ../nbs/00_core.ipynb 40
# %% ../nbs/00_core.ipynb 48
@patch
def wait_for_settlement(self:Fewsats,
pid:str, # purchase id
Expand All @@ -134,7 +160,7 @@ def wait_for_settlement(self:Fewsats,
wait *= 2
raise TimeoutError(f"Payment {pid} did not settle within {max_wait} seconds. Final status: {status}")

# %% ../nbs/00_core.ipynb 43
# %% ../nbs/00_core.ipynb 51
@patch
def as_tools(self:Fewsats):
"Return list of available tools for AI agents"
Expand Down
Loading

0 comments on commit 979cc8b

Please sign in to comment.