From 926498ee5fbea027638bc1f2fa78ce944c16f2b8 Mon Sep 17 00:00:00 2001 From: Neeraj Bansal Date: Wed, 21 Aug 2024 17:18:13 +0530 Subject: [PATCH 1/5] feat(integration): add payment solution integration through stripe --- .../stripe_payment_solution/README.md | 88 +++++++ .../stripe_payment_solution/project.json | 9 + .../stripe_payment_solution/pyproject.toml | 18 ++ .../src/stripe_agent/agent.py | 157 ++++++++++++ .../src/stripe_demo_server/app.py | 79 ++++++ .../stripe_demo_server/templates/index.html | 230 ++++++++++++++++++ .../src/stripe_models/models.py | 31 +++ .../src/stripe_webhook/webhook.py | 78 ++++++ 8 files changed, 690 insertions(+) create mode 100644 integrations/stripe_payment_solution/README.md create mode 100644 integrations/stripe_payment_solution/project.json create mode 100644 integrations/stripe_payment_solution/pyproject.toml create mode 100644 integrations/stripe_payment_solution/src/stripe_agent/agent.py create mode 100644 integrations/stripe_payment_solution/src/stripe_demo_server/app.py create mode 100644 integrations/stripe_payment_solution/src/stripe_demo_server/templates/index.html create mode 100644 integrations/stripe_payment_solution/src/stripe_models/models.py create mode 100644 integrations/stripe_payment_solution/src/stripe_webhook/webhook.py diff --git a/integrations/stripe_payment_solution/README.md b/integrations/stripe_payment_solution/README.md new file mode 100644 index 00000000..ebe2daa0 --- /dev/null +++ b/integrations/stripe_payment_solution/README.md @@ -0,0 +1,88 @@ +# Stripe Payment Solution + +Have you ever considered using Stripe as a payment partner for your business? +That's exactly what we've done by leveraging the power of Fetch.AI Agents and Stripe's cutting-edge payment technology. +We’ve developed an integrated Stripe payment solution that simplifies and streamlines all your payment processes. + +## Table of Contents + +- [Introduction](#introduction) +- [Features](#features) +- [How It Works](#how-it-works) +- [Installation](#installation) +- [Usage](#usage) +- [Contributing](#contributing) +- [License](#license) + +## Introduction + +Imagine a world where your payment requirements are effortlessly handled, +giving you more time to focus on what truly matters—growing your business. +Our solution ensures +that transactions are not only fast and secure but also incredibly convenient for both you and your customers. + +By integrating Fetch.AI's intelligent agent technology with Stripe’s robust payment infrastructure, we offer a seamless experience that adapts to your unique business needs. +Whether you're handling subscriptions, one-time payments, or complex billing scenarios, our solution is designed to evolve with your business. + +Take the next step in transforming your payment processes. +With our **Stripe Payment Solution**, you can expect reduced friction, +enhanced security, and an overall superior payment experience. +Let’s simplify your payments, so you can focus on innovation and growth. + +## Features + +- Real Time Payment Link Generator. +- Real Time Payment Confirmation mechanism. +- Custom Multi Cart Item Payments. +- Simple UI. +- Automated Invoicing & Receipts +- One-Click Payments for Customers + +## How It Works + +Stripe Payment Solution few items to choose from, for testing purposes. + +1. Choose one of the items to initiate the payment. +2. Then a payment link from Stripe is generated for payment, Click it. +3. Fill it the Payment Details and click **Place Order**, wait for Payment Confirmation. + +## Installation + +To get started with **Stripe Payment Solution**, follow these steps: + +1. **Clone the repository**: + ```bash + git clone https://github.com/fetchai/uAgents.git + cd stripe-agent + +2. Get API Key and Endpoint Secret from [Stripe.com](https://dashboard.stripe.com/login). + +3. **Set up .env file**: + To run the demo, you need to add these API keys in .env file: + ```bash + STRIPE_API_KEY='YOUR_STRIPE_KEY' + STRIPE_ENDPOINT_SECRET='YOUR_STRIPE_ENDPOINT_SECRET' + STRIPE_WEBHOOK_URL='YOUR_STRIPE_WEBHOOK_URL' + +4. **Open a shell**: + ```bash + poetry shell + +5. **Install dependencies using Poetry**: + ```bash + poetry install --no-root + +6. **Run the agent**: + ```bash + cd src/stripe_agent + poetry run python agent.py + +7. **Run the demo_server**: + ```bash + cd src/stripe_demo_server + poetry run python app.py + +8. **Run the webhook**: + ```bash + cd src/stripe_webhook + poetry run python webhook.py \ No newline at end of file diff --git a/integrations/stripe_payment_solution/project.json b/integrations/stripe_payment_solution/project.json new file mode 100644 index 00000000..08108c09 --- /dev/null +++ b/integrations/stripe_payment_solution/project.json @@ -0,0 +1,9 @@ +{ + "categories": [ + "Stripe", + "Payment Solution" + ], + "deltav": false, + "description": "Helps User for there Payment Requirements", + "title": "Stripe Payment Solution" +} \ No newline at end of file diff --git a/integrations/stripe_payment_solution/pyproject.toml b/integrations/stripe_payment_solution/pyproject.toml new file mode 100644 index 00000000..54f9bf76 --- /dev/null +++ b/integrations/stripe_payment_solution/pyproject.toml @@ -0,0 +1,18 @@ +[tool.poetry] +name = "general-use-payment-stripe-solution" +version = "0.1.0" +description = "General Use Payment Solution with Stripe and Fetch.AI Agents" +authors = ["Neeraj Bansal "] +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.10" +uagents = { version = "^0.15.2", python = ">=3.10,<3.13" } +uagents-ai-engine = { version = "^0.5.0", python = ">=3.10,<3.12" } +stripe = "^10.7.0" +Flask = { extras = ["async"], version = "^3.0.3" } +python-dotenv = "^1.0.1" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/integrations/stripe_payment_solution/src/stripe_agent/agent.py b/integrations/stripe_payment_solution/src/stripe_agent/agent.py new file mode 100644 index 00000000..c7ae6ba6 --- /dev/null +++ b/integrations/stripe_payment_solution/src/stripe_agent/agent.py @@ -0,0 +1,157 @@ +import os +import uuid + +import requests +from ai_engine import UAgentResponse, UAgentResponseType +from dotenv import load_dotenv +from uagents import Agent, Protocol, Context, Model +from uagents.setup import fund_agent_if_low + +class KeyValue(Model): + currency: str + product_name: str + unit_price: int + units: int + +class StripePaymentRequest(Model): + item_in_cart: list[KeyValue] + customer_email: str + order_id: str + +class QueryPaymentStatus(Model): + client_reference_id: str + + + +class PaymentStatus(Model): + client_reference_id: str + data: dict + +load_dotenv() + +agent = Agent( + name="Stripe Agent", + seed="Stripe Agent secret seed phrase", + log_level="DEBUG", + endpoint="http://localhost:8001/submit", + port=8001 +) +fund_agent_if_low(str(agent.wallet.address())) + +print("Agent Address:", agent.address) + + +stripe_payment_protocol = Protocol("Stripe Payment Protocol", "1.00") + +API_KEY = os.getenv('STRIPE_API_KEY', "") +ENDPOINT_SECRET = os.getenv('STRIPE_ENDPOINT_SECRET', "") +WEBHOOK_URL = os.getenv('STRIPE_WEBHOOK_URL', "") +STRIPE_API_URL = os.getenv('STRIPE_API_URL', "") + + +@stripe_payment_protocol.on_message(model=StripePaymentRequest, replies={UAgentResponse}) +async def create_checkout_session(ctx: Context, sender: str, msg: StripePaymentRequest): + ctx.logger.info( + f"Received Request from {msg.customer_email} for Payment Link.") + try: + print(agent.address) + payload = { + 'customer_creation': 'always', + 'customer_email': msg.customer_email, + 'mode': 'payment', + 'payment_intent_data[metadata][order_id]': msg.order_id, + 'success_url': f"{WEBHOOK_URL}/order/success?session_id={{CHECKOUT_SESSION_ID}}", + 'cancel_url': f"{WEBHOOK_URL}/cancel" + } + + for index, item in enumerate(msg.item_in_cart): + payload[f'line_items[{index}][price_data][currency]'] = item.currency + payload[f'line_items[{index}][price_data][product_data][name]'] = item.product_name + payload[f'line_items[{index}][price_data][unit_amount]'] = item.unit_price + payload[f'line_items[{index}][quantity]'] = item.units + + headers = { + 'Authorization': f'Bearer {API_KEY}', + 'Content-Type': 'application/x-www-form-urlencoded' + } + + # encoded_payload = urllib.parse.urlencode(payload, doseq=True) + response = requests.post(f"{STRIPE_API_URL}/checkout/sessions", headers=headers, data=payload) + session = response.json() + request_id = str(uuid.uuid4()) + if response.status_code == 200 and 'url' in session: + resp = await ctx.send( + sender, + UAgentResponse( + message=str(session['url']), + type=UAgentResponseType.FINAL, + request_id=request_id + ), + ) + + ctx.storage.set(msg.order_id, {'address': sender}) + else: + await ctx.send( + sender, + UAgentResponse( + message="Can't generate payment link, please try again after some time.!", + type=UAgentResponseType.FINAL, + request_id=request_id + ), + ) + except Exception as exc: + ctx.logger.error(exc) + await ctx.send( + sender, UAgentResponse(message=str(exc), type=UAgentResponseType.ERROR) + ) + + +@stripe_payment_protocol.on_message(model=QueryPaymentStatus, replies={UAgentResponse}) +async def payment_status(ctx: Context, sender: str, msg: QueryPaymentStatus): + ctx.logger.info( + f"Received query request from {msg.client_reference_id}.") + try: + payment_details = ctx.storage.get(msg.client_reference_id) or None + if 'payment_data' in payment_details: + await ctx.send( + sender, UAgentResponse(message="Payment Succeeded", type=UAgentResponseType.FINAL) + ) + else: + await ctx.send( + sender, UAgentResponse(message="Payment confirmation awaited", type=UAgentResponseType.FINAL) + ) + except Exception as exc: + ctx.logger.error(exc) + await ctx.send( + sender, UAgentResponse(message=str(exc), type=UAgentResponseType.ERROR) + ) + + +@stripe_payment_protocol.on_message(model=PaymentStatus, replies={UAgentResponse}) +async def payment_status(ctx: Context, sender: str, msg: PaymentStatus): + ctx.logger.info( + f"Received Payment Update of Customer {msg.client_reference_id}.") + try: + payment_details = ctx.storage.get(msg.client_reference_id) or None + if payment_details: + payment_details['payment_data'] = msg.data + ctx.storage.set(msg.client_reference_id, payment_details) + + await ctx.send( + payment_details['address'], UAgentResponse(message="Payment Succeeded", type=UAgentResponseType.FINAL) + ) + print(f"Notified {payment_details['address']} of payment confirmation") + else: + print('Weird...') + + except Exception as exc: + ctx.logger.error(exc) + await ctx.send( + sender, UAgentResponse(message=str(exc), type=UAgentResponseType.ERROR) + ) + + +agent.include(stripe_payment_protocol, publish_manifest=True) + +if __name__ == "__main__": + agent.run() diff --git a/integrations/stripe_payment_solution/src/stripe_demo_server/app.py b/integrations/stripe_payment_solution/src/stripe_demo_server/app.py new file mode 100644 index 00000000..829db710 --- /dev/null +++ b/integrations/stripe_payment_solution/src/stripe_demo_server/app.py @@ -0,0 +1,79 @@ +import asyncio +from typing import List + +from flask import Flask, render_template, request, jsonify +from pydantic import Field +from uagents import Model +from uagents.communication import send_sync_message + + +app = Flask(__name__) + +class KeyValue(Model): + currency: str + product_name: str + unit_price: int + units: int + +class QueryPaymentStatus(Model): + client_reference_id: str + +class StripePaymentRequest(Model): + item_in_cart: list[KeyValue] + customer_email: str + order_id: str + + +@app.route('/', methods=['GET']) +def index(): + return render_template('index.html') + + +@app.route('/test', methods=['GET']) +def test(): + return jsonify({"message": "Flask server is running"}), 200 + + +def run_async(coro): + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + return loop.run_until_complete(coro) + + +@app.route('/query', methods=['POST']) +async def query_agent(): + payment_status = QueryPaymentStatus( + client_reference_id='123456' + ) + response = await send_sync_message( + 'agent1qtehcv05d2yfdxgyhk8wnk9pavl7yxyzg2m05gvqwgggwtxas99nugry6xk', + payment_status + ) + print(response) + + return jsonify(response) + + +@app.route('/process', methods=['POST']) +async def process(): + data = request.json + + # Create a StripePaymentRequest object + payment_request = StripePaymentRequest( + item_in_cart=data['item_in_cart'], + customer_email=data['customer_email'], + order_id=data['order_id'] + ) + print("sending the payment request to Stripe agent") + + response = await send_sync_message( + 'agent1qtehcv05d2yfdxgyhk8wnk9pavl7yxyzg2m05gvqwgggwtxas99nugry6xk', + payment_request + ) + print(response) + + return jsonify(response) + + +if __name__ == '__main__': + app.run(debug=True, port=9000, host='0.0.0.0') diff --git a/integrations/stripe_payment_solution/src/stripe_demo_server/templates/index.html b/integrations/stripe_payment_solution/src/stripe_demo_server/templates/index.html new file mode 100644 index 00000000..8acad55d --- /dev/null +++ b/integrations/stripe_payment_solution/src/stripe_demo_server/templates/index.html @@ -0,0 +1,230 @@ + + + + + + DeltaV Agent Demo + + + +

Stripe Agent Demo

+
+ + + + + + + + + + +
+

Payment Status:

+

Agent Response:

+
+ + + + diff --git a/integrations/stripe_payment_solution/src/stripe_models/models.py b/integrations/stripe_payment_solution/src/stripe_models/models.py new file mode 100644 index 00000000..d5dfaa61 --- /dev/null +++ b/integrations/stripe_payment_solution/src/stripe_models/models.py @@ -0,0 +1,31 @@ +from uagents import Models + + +class KeyValue(Model): + currency: str + product_name: str + unit_price: int + units: int + + +class StripePaymentRequest(Model): + item_in_cart: list[KeyValue] + customer_email: str + order_id: str + + +class PaymentStatus(Model): + client_reference_id: str + data: dict + + +class QueryPaymentStatus(Model): + client_reference_id: str + + +class PaymentLinkRequest(Model): + no_of_items: int = Field(default=1, + description="This field describes the number of items user wants to buy. It should be MORE THAN 0.") + item_in_list: List[KeyValue] = Field( + description="This field describes the List of items in KeyValue Model Format. It should never be Null or Blank.") + customer_email: str = Field(description="This field describes the Email of Customer Placing Order.") \ No newline at end of file diff --git a/integrations/stripe_payment_solution/src/stripe_webhook/webhook.py b/integrations/stripe_payment_solution/src/stripe_webhook/webhook.py new file mode 100644 index 00000000..0ae2755f --- /dev/null +++ b/integrations/stripe_payment_solution/src/stripe_webhook/webhook.py @@ -0,0 +1,78 @@ +import asyncio +import json +import os + +import stripe +from flask import Flask, request, jsonify, render_template_string +from uagents import Agent +from uagents import Model +from uagents.communication import send_sync_message + +class PaymentStatus(Model): + client_reference_id: str + data: dict + +app = Flask(__name__) + +agent = Agent() + +stripe.api_key = os.getenv('STRIPE_API_KEY') +webhook_secret = os.getenv('STRIPE_ENDPOINT_SECRET') + + +@app.route('/order/success', methods=['GET']) +async def order_success(): + session = stripe.checkout.Session.retrieve(request.args.get('session_id')) + customer = stripe.Customer.retrieve(session.customer) + retries = 5 + for attempt in range(retries): + try: + return render_template_string( + '

Thanks for your order, {{customer.name}}!

', + customer=customer) + except Exception as e: + print(f"Attempt {attempt + 1} failed with error: {e}") + if attempt < retries - 1: + print("Retrying...") + await asyncio.sleep(5) # Add a delay before retrying + + +@app.route('/webhook', methods=['POST']) +async def webhook_received(): + # You can use webhooks to receive information about asynchronous payment events. + # For more about our webhook events, check out https://stripe.com/docs/webhooks. + webhook_secret = os.getenv('STRIPE_WEBHOOK_SECRET') + request_data = json.loads(request.data) + + if webhook_secret: + # Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured. + signature = request.headers.get('stripe-signature') + try: + event = stripe.Webhook.construct_event( + payload=request.data, sig_header=signature, secret=webhook_secret) + data = event['data'] + except Exception as e: + return e + # Get the type of webhook event sent - used to check the status of PaymentIntents. + event_type = event['type'] + else: + data = request_data['data'] + event_type = request_data['type'] + data_object = data['object'] + print(data_object, "Payment") + print('event ' + event_type) + + if event_type == 'charge.updated': + print("Event Details:", data_object) + response = await send_sync_message('agent1qtehcv05d2yfdxgyhk8wnk9pavl7yxyzg2m05gvqwgggwtxas99nugry6xk', + PaymentStatus( + client_reference_id=data_object['metadata']['order_id'], + data=data_object + )) + print(response) + + return jsonify({'status': 'success'}) + + +if __name__ == '__main__': + app.run(port=4242, debug=True) From d6e46a6471ff06c8db096f15016146a017bad042 Mon Sep 17 00:00:00 2001 From: Neeraj Bansal Date: Thu, 22 Aug 2024 11:30:36 +0530 Subject: [PATCH 2/5] feat(integration): add system daigram in readme.md --- integrations/stripe_payment_solution/README.md | 7 +++++++ .../images/payment_system_overview.png | Bin 0 -> 48132 bytes 2 files changed, 7 insertions(+) create mode 100644 integrations/stripe_payment_solution/images/payment_system_overview.png diff --git a/integrations/stripe_payment_solution/README.md b/integrations/stripe_payment_solution/README.md index ebe2daa0..f241a02f 100644 --- a/integrations/stripe_payment_solution/README.md +++ b/integrations/stripe_payment_solution/README.md @@ -38,6 +38,13 @@ Let’s simplify your payments, so you can focus on innovation and growth. - Automated Invoicing & Receipts - One-Click Payments for Customers +## Working Diagram + +![Working Diagram](./images/payment_system_overview.png "Working Diagram") + +This Agent can work like a template and can be used in different organizations with their API keys from stripe A/c. + + ## How It Works Stripe Payment Solution few items to choose from, for testing purposes. diff --git a/integrations/stripe_payment_solution/images/payment_system_overview.png b/integrations/stripe_payment_solution/images/payment_system_overview.png new file mode 100644 index 0000000000000000000000000000000000000000..898e1b498320b05fcc6000d159383560fba901f7 GIT binary patch literal 48132 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 literal 0 HcmV?d00001 From 85f896648798d9618d6caa9d77eaaad541e924b4 Mon Sep 17 00:00:00 2001 From: neerajkrbansal1996 Date: Thu, 22 Aug 2024 12:01:33 +0530 Subject: [PATCH 3/5] feat(integration): Update README.md --- integrations/stripe_payment_solution/README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/integrations/stripe_payment_solution/README.md b/integrations/stripe_payment_solution/README.md index f241a02f..4468d75a 100644 --- a/integrations/stripe_payment_solution/README.md +++ b/integrations/stripe_payment_solution/README.md @@ -45,6 +45,16 @@ Let’s simplify your payments, so you can focus on innovation and growth. This Agent can work like a template and can be used in different organizations with their API keys from stripe A/c. +## Demo Video + +https://github.com/user-attachments/assets/3de86092-e2aa-43f1-b59d-73b725698600 + + +## Detail Document + +[Detail Document](https://github.com/user-attachments/files/16706323/Stripe_Agent_Integration.pdf) + + ## How It Works Stripe Payment Solution few items to choose from, for testing purposes. @@ -92,4 +102,4 @@ To get started with **Stripe Payment Solution**, follow these steps: 8. **Run the webhook**: ```bash cd src/stripe_webhook - poetry run python webhook.py \ No newline at end of file + poetry run python webhook.py From d03812baff7617979a62c1ea0440c8878e764892 Mon Sep 17 00:00:00 2001 From: neerajkrbansal1996 Date: Thu, 22 Aug 2024 16:37:04 +0530 Subject: [PATCH 4/5] feat(integration): Re-structure README.md --- .../stripe_payment_solution/README.md | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/integrations/stripe_payment_solution/README.md b/integrations/stripe_payment_solution/README.md index 4468d75a..0c138673 100644 --- a/integrations/stripe_payment_solution/README.md +++ b/integrations/stripe_payment_solution/README.md @@ -1,8 +1,8 @@ # Stripe Payment Solution -Have you ever considered using Stripe as a payment partner for your business? -That's exactly what we've done by leveraging the power of Fetch.AI Agents and Stripe's cutting-edge payment technology. -We’ve developed an integrated Stripe payment solution that simplifies and streamlines all your payment processes. +Ever had an idea to use Stripe as a payment partner for your business, That's why I've harnessed the power of Fetch.AI +Agent and Stripe payment ecosystem to develop a **Stripe Payment Solution** integration, designed to transform all your +payment requirements, into a simple and convenient manner. ## Table of Contents @@ -16,18 +16,7 @@ We’ve developed an integrated Stripe payment solution that simplifies and stre ## Introduction -Imagine a world where your payment requirements are effortlessly handled, -giving you more time to focus on what truly matters—growing your business. -Our solution ensures -that transactions are not only fast and secure but also incredibly convenient for both you and your customers. - -By integrating Fetch.AI's intelligent agent technology with Stripe’s robust payment infrastructure, we offer a seamless experience that adapts to your unique business needs. -Whether you're handling subscriptions, one-time payments, or complex billing scenarios, our solution is designed to evolve with your business. - -Take the next step in transforming your payment processes. -With our **Stripe Payment Solution**, you can expect reduced friction, -enhanced security, and an overall superior payment experience. -Let’s simplify your payments, so you can focus on innovation and growth. +**Stripe Payment Solution** is an innovative tool that leverages Fetch.AI's Agent technology to help anyone with a requirement to accept payment over the Internet. This System integrates Stripe as the Payment regulator for all the payment related services. ## Features From 9f9a4874be519cc0499ff92ea81b810a87691f4b Mon Sep 17 00:00:00 2001 From: Neeraj Bansal Date: Thu, 22 Aug 2024 19:11:53 +0530 Subject: [PATCH 5/5] feat(integration): Re-structure Installation Steps in README.md --- .../stripe_payment_solution/README.md | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/integrations/stripe_payment_solution/README.md b/integrations/stripe_payment_solution/README.md index 0c138673..5cc2d75a 100644 --- a/integrations/stripe_payment_solution/README.md +++ b/integrations/stripe_payment_solution/README.md @@ -61,34 +61,36 @@ To get started with **Stripe Payment Solution**, follow these steps: git clone https://github.com/fetchai/uAgents.git cd stripe-agent -2. Get API Key and Endpoint Secret from [Stripe.com](https://dashboard.stripe.com/login). +2. **Open a shell**: + ```bash + poetry shell -3. **Set up .env file**: - To run the demo, you need to add these API keys in .env file: +3. **Install dependencies using Poetry**: ```bash - STRIPE_API_KEY='YOUR_STRIPE_KEY' - STRIPE_ENDPOINT_SECRET='YOUR_STRIPE_ENDPOINT_SECRET' - STRIPE_WEBHOOK_URL='YOUR_STRIPE_WEBHOOK_URL' + poetry install --no-root + +4. Get API Key and Endpoint Secret from [Stripe.com](https://dashboard.stripe.com/login). -4. **Open a shell**: +5. **Run the webhook**: ```bash - poetry shell + cd src/stripe_webhook + poetry run python webhook.py + +6. Using Ngrok or any Tunneling Software, Create secure https endpoint and set it up as a webhook in Stripe dashboard under the webhook section. -5. **Install dependencies using Poetry**: +7. **Set up .env file**: + To run the demo, you need to add these API keys and URLs in .env file: ```bash - poetry install --no-root + STRIPE_API_KEY='YOUR_STRIPE_KEY' + STRIPE_ENDPOINT_SECRET='YOUR_STRIPE_ENDPOINT_SECRET' + STRIPE_WEBHOOK_URL='YOUR_STRIPE_WEBHOOK_URL' -6. **Run the agent**: +8. **Run the agent**: ```bash cd src/stripe_agent poetry run python agent.py -7. **Run the demo_server**: +9. **Run the demo_server**: ```bash cd src/stripe_demo_server poetry run python app.py - -8. **Run the webhook**: - ```bash - cd src/stripe_webhook - poetry run python webhook.py