BOB Docs
APIApplication

Payment

API

The application is accessible under the path: /api/payment/*.

API Modules

  • User Billing Data: Managed via billing_router.py.
  • Stripe Webhook Processing: Handled via stripe_router.py.

Stripe Webhook Handling

The Stripe webhook endpoint uses a lock to ensure sequential processing of requests, preventing issues caused by out-of-order event handling. For example, this avoids scenarios where a payment is processed before the corresponding Customer is created in Stripe.

@stripe_router.post(
    'webhook',
    auth=None,
    response={200: StripeWebhookResponseDTO, 400: ApiExceptionOut},
    tags=["payment", "stripe"],
    summary="Handle stripe webhooks."
)
async def handle_webhook(request):
    async with lock:
        try:
            # Process the webhook using the payment interactor
            if await payment_interactor.handle_webhook_from_stripe(request.body, request.headers['STRIPE_SIGNATURE']):
                return 200, {"message": "Best regards from Business-Oriented Programming Boilerplate."}
        except Exception as ex:
            # Log the exception for debugging purposes
            print(ex)
 
        # Raise an exception if the webhook event could not be handled
        raise ApiException(f"Could not handle event: {request.body}", status_code=500)

PaymentInteractor

The PaymentInteractor class serves as the central business logic layer for managing payment operations. It integrates multiple services to handle payments, subscriptions, billing, and Stripe webhook events, ensuring a seamless and consistent payment flow.

Key Features

  1. Payment Processing:
  • Manages payment attempts, customer creation, and Stripe checkout sessions.
  1. Subscription Management:
  • Creates, updates, and deletes subscriptions, ensuring synchronization with providers like Stripe.
  1. Billing and Tax Handling:
  • Processes user billing information and validates VAT numbers using VIES.
  1. Webhook Integration:
  • Handles Stripe webhook events to keep the system updated in real-time.
  1. Customer Management:
  • Links external customers to internal records and provides Stripe customer portal links.

Methods

  1. Billing and Tax Management:
  • create_user_billing_info: Creates and synchronizes billing data with external providers.
  • _process_tax: Determines tax exemption status based on user billing data.
  • validate_vies: Validates VAT numbers via the VIES database.
  1. Customer Management:
  • get_customer_management_portal_link: Retrieves a user-friendly Stripe customer portal link.
  • _get_or_create_custom_user: Creates or retrieves a user linked to an organization.
  1. Subscription Management:
  • handle_webhook_from_stripe: Handles Stripe webhook events such as:
  • Customer creation and updates.
  • Subscription creation, updates, and deletions.
  • Tax ID management.
  • Checkout session completions.
  • Ensures subscription limits are enforced and records are updated.
  1. Webhook Handling:
  • Processes real-time events from Stripe to maintain system synchronization.
  1. Stripe Integration:
  • Manages Stripe-specific operations like decoding webhooks and managing subscriptions.

Example Workflow

  1. Create Billing Information:
billing_info = await payment_interactor.create_user_billing_info(user, billing_data)
  1. Retrieve Customer Portal Link:
portal_link = await payment_interactor.get_customer_management_portal_link(user, customer_id=123)
  1. Handle Stripe Webhook:
success = await payment_interactor.handle_webhook_from_stripe(payload, stripe_signature)

Dependencies

  • Services:
  • AuthService: Manages authentication and token validation.
  • PaymentService: Handles payment processing and Stripe integration.
  • BillingService: Manages billing and tax exemptions.
  • CustomerService: Handles customer creation and management.
  • OrganizationService: Manages organization operations.
  • OrderService: Handles orders and payment attempts.
  • MailerService: Sends notifications and invoices.
  • SubscriptionService: Manages subscription plans and updates.
  • PlanService: Handles subscription plan management.
## Commands
 
This module includes a command for synchronizing the system's data with Stripe, covering prices, products, and customers.
 
### SynchronizePayments Command
 
The `synchronizepayments` command ensures the local database is aligned with the external payment provider, such as Stripe. It synchronizes product and customer records for accurate representation in the external system.
 
 
 
### Key Features
 
1. **Product Synchronization**:
   - Retrieves product data from the local database.
   - Converts products into `ProductToSynchronizePayments` DTOs for compatibility.
   - Synchronizes product details, pricing, and metadata with the external payment provider.
2. **Customer Synchronization**:
   - Retrieves all customers from the local database.
   - Updates or creates customer records in the external payment system.
3. **Streamlined Execution**:
   - Combines product and customer synchronization into one efficient process.
 
 
 
### Workflow
 
1. **Fetch Data**:
   - Products are fetched in pages (`page 1, 100 items`).
   - Customers are retrieved from the database.
2. **Data Transformation**:
   - Products are standardized into DTOs for synchronization.
3. **Synchronization**:
   - Products and pricing are synchronized with `payment_service.synchronize_products`.
   - Customer data is updated or added using `payment_service.synchronize_customers`.
4. **Confirmation**:
   - Outputs a success message upon completion.
 
 
 
### Usage
 
Run the command as follows:
 
```bash
python manage.py synchronizepayments

Dependencies

  • Services:
  • ProductService: Fetches local product data.
  • PaymentService: Handles synchronization with external systems.
  • CustomerService: Retrieves customer data.
  • DTOs:
  • ProductToSynchronizePayments: Ensures consistent product data structure.

Benefits

  • Ensures local and external payment systems are synchronized.
  • Streamlines the initialization and management of payment-related records.
  • Scalable for both products and customers.

Signals

The custom_user_post_save signal is triggered whenever a CustomUser instance is saved. It ensures proper many-to-many relationships and executes post-creation logic, including calling the post_user_created method in the UserInteractor.

Models

BillingInformation

This model stores customer billing details, such as name, email, address, tax ID, and tax exemption status. It includes:

  • A one-to-one relationship with the customer.
  • EU VAT handling with the is_from_eu flag.
  • Flexibility for accurate invoicing and tax compliance.

ExternalCustomer

The ExternalCustomer model links internal customer data to external payment platforms (e.g., Stripe). Key features:

  • Tracks synchronization between internal and external systems.
  • Deletes external records when the internal customer is removed, ensuring data integrity.

ExternalPaymentProvider

An abstract model for entities linked to external payment providers. Features include:

  • A provider field to select the payment provider (e.g., Stripe).
  • Designed for reusable implementation across models requiring external provider tracking.

ExternalPricing

This model connects local pricing data to external systems. Key features:

  • Tracks external IDs and providers.
  • Links to the local Pricing model.
  • Ensures external records are removed if the local pricing data is deleted.

ExternalProduct

The ExternalProduct model synchronizes local product data with external payment systems. Key features:

  • Tracks provider type and external IDs.
  • Links to the local Product model.
  • Automatically removes external records when the local product is deleted.

ExternalSubscription

This model bridges local subscription data with external payment systems. Key features:

  • Tracks provider type and external IDs.
  • Links to the local Subscription model.
  • Ensures external records are deleted if the local subscription is removed.

The system treats internal data as the single source of truth, storing only external IDs for synchronization. This approach enables seamless integration with any payment system while maintaining control within the application.

On this page