Skip to content

This project integrates your local customer catalog with external services like Stripe and potentially Salesforce. It uses FastAPI for the web server, Celery for asynchronous task processing, Docker for containerization, and Ngrok for local webhook testing.

Notifications You must be signed in to change notification settings

mogiiee/Real-time-stripe

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This project integrates your local customer catalog with external services like Stripe and potentially Salesforce. It uses FastAPI for the web server, Celery for asynchronous task processing, Docker for containerization, and Ngrok for local webhook testing.

Table of Contents

Prerequisites

  • Python 3.9+
  • Docker & Docker Compose (for Docker setup)
  • A Stripe account for testing Stripe integration

Be sure to have all the environment variable set up, All the keys and auth token for the webhook

Tech stack

  • fastapi
  • sqlite
  • docker
  • stripe API
  • Ngrok (webhook)
  • Celery (worker)
  • rabbitMQ (queue)
git clone https://github.com/mogiiee/Zenskar-Task.git
cd Zenskar-Task

Workflow Diagram

workflow diagram

Running with Docker

This method uses Docker to run the FastAPI server, Celery worker, and RabbitMQ. It has a docker-compose up file which can start all the docker container at the same time for the ease of deployment.

Build and Start Services

docker-compose up --build

This command builds the Docker images and starts the containers defined in docker-compose.yml.

Please wait for about 10 seconds for the server to start up. You should see something like this

success docker compose up

its okay for the celery worker to try 3 or 4 times to connect to the server.

this is okay

this too is okay

both of these scenarios are okay just wait for about 10 seconds.

Accessing the Application

Running Locally

It is not recommended as you might face alot of errors. I have designed it to work with docker-compose ... you will have to change alot of paths manually. Just use docker bro

error pic

Virtual Environment Setup

python -m venv virtualenv
source virtualenv/bin/activate  
(linux)

Install Dependencies

pip install -r requirements.txt

Start the FastAPI Server

uvicorn app.main:app --reload

Start the Celery Worker

In a new terminal session, activate the virtual environment and run: (this is handled in the docker-compose file)

celery -A app.worker.celery_worker worker --loglevel=info

Setting Up Ngrok for Webhooks

Ngrok allows you to expose your local server to the internet, facilitating webhook testing.

  1. Download and install Ngrok from Ngrok's website.

  2. Start Ngrok to expose port 8000:

    ./ngrok http 8000 or ngrok http 8000
  3. Copy the forwarding URL provided by Ngrok (e.g., https://<random_string>.ngrok.io).

  4. Add this URL in the webhook section in the Dashboard of stripe.

Remember to add URL/webhooks/stripe at the end else you would get a 400 error as it wont hit the right endpoint. Been there done that lol.

Environment Variables

Create a .env file or just populate the .env.sample file in the root directory and add the following variables:

  • STRIPE_SECRET_KEY='sk_test.... replace it here'
  • STRIPE_PUBLISHABLE_KEY='pk_test_.... replace it here although this is not used in the backend'secret.

there is another .env.sample file in app/webhook_handler/.env.sample you can poplulate it with

  • SIGNING_SECRET="get it from the Stripe dashboard> webhook> signing secret"

Obtaining Stripe Environment Variables

  1. API Key: Found in your Stripe Dashboard under Developers > API keys.
  2. Endpoint Secret: Create a webhook endpoint in Stripe Dashboard (Developers > Webhooks) using your Ngrok URL. Use the secret provided there.

Issues Faced

  • I had to spend alot of time figuring out what the logic will be for the local id and the id mentioned in Stripe

  • If you see my initial commits, I tried using Kafka with a producer and consumer queue. I could not figure out how I can include it as a container and run it with docker-compose. Hence I decided to go with RabbitMQ

API Endpoints

  • Greeting to the people of Zenskar with love: GET /
  • Create Customer: POST /customers/
  • Update Customer: PUT /customers/{customer_id}
  • Delete Customer: DELETE /customers/{customer_id}
  • Stripe Webhook: POST /webhooks/stripe

Answers to throretical question 1

How would the current setup be utilized with salesforce API. With the research I have done, this setup would work fine provided there are 3 key changes done on top of this setup.

  1. Salesforce does not have a customers API like stripe but it has Account> Contact where objects like customer details can be stored. Account is where business details are stored and contact is where custormers of that business is stored. Salesforce just like Stripe has a REST API to access these and perform CRUD ops on their dashboard, but it requires secondary authentication with OAuth2, which brings me to my second point.

  2. Authentication, now this would have to be implemented completely from scratch as an OAuth flow would be needed to make valid API requests.

  3. As we used Stripe's webhook, salesforce also provides a service called Salesforce outbound messages. A new end point could be made or the same one could be updated so that it calls different functions, when different services hit that endpoint. I have put the sample code above the webhook endpoint in comments here.

  4. We could also implement a celery beat which hits the Salesforce API as a cron job, and syncs the local db. The functions to sync the local db wll remain the same, only another beat would have to be implemented.

  5. Minor changes in the the docker-compose file to make sure that this beat is running when the entire service is up.

Answers to throretical question 2

Since invoicing is a completely different topic from the customers, there would need to be extentions to some of the code base. The part where both of these can be linked would be where each customer_id has some invoices(status does not matter)

  1. Celery workers-
  • Similarity: Just as how i have tasks for syncing customer data (update_customer_in_stripe), I can create tasks like create_invoice_in_stripe and update_invoice_status_in_local_db.

  • Improvement: Implement task routing in Celery to separate customer-related tasks from invoice-related tasks, improving task management and scalability.

  1. Data Model Expansion
  • Similarity: Just as i have a customer model that includes Stripe-specific information (stripe_customer_id), i will need an invoice model that might include fields like stripe_invoice_id, amount, status, and a relationship to the customer model.
  1. Webhook Handling
  • Similarity: The existing webhook endpoint (@app.post("/webhooks/stripe")) uses payload validation and event type checking. Similar logic will apply to invoice events, identifying them through event['type'] (e.g., invoice.paid, invoice.payment_failed). This can be checked when creating the webhook on the dashboard.
  1. API and Authentication
  • Since I am using the same stripe API's there would be no issues to get the Stripe's Invoices API. New functions would have to be created to make changes to the invoice, update its status and preprocess it to get important information.

With a few changes to the code, we can implement new functions which write the same to the local db and show all the invoice information which the stripe API is giving in a new table.

Screenshots

  • main dashboard of all the endpoints using swagger UI. Can also use Postman if that's more up your alley.

main dashboard

  • Be sure to check these events while creating the webhook

webhook opts

  • My first customer Christopher Nolan when made directly on the dashboard, will be reflected in app/data/database.db

customer

  • all the customers can be created, updated and deleted from the dashboard and everything will reflect in the local database

all customers

  • creation endpoint

creation

  • update endpoint

update

  • delete endpoint delete

  • local database

localdb

About

This project integrates your local customer catalog with external services like Stripe and potentially Salesforce. It uses FastAPI for the web server, Celery for asynchronous task processing, Docker for containerization, and Ngrok for local webhook testing.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published