feat: billing guest access

This commit is contained in:
2024-08-08 07:49:53 +03:00
parent a7c4fabed0
commit 97f835ffde
30 changed files with 682 additions and 140 deletions

3
external/billing/__init__.py vendored Normal file
View File

@@ -0,0 +1,3 @@
from .schemas import *
from .enums import *
from .billing_client import BillingClient

27
external/billing/billing_client.py vendored Normal file
View File

@@ -0,0 +1,27 @@
import aiohttp
from .schemas import *
class BillingClient:
def __init__(self, api_key: str):
self.api_key = api_key
self.headers = {
'Authorization': f'Bearer {self.api_key}'
}
self.base_url = 'https://billing.denco.store'
async def _method(self, http_method, method, **kwargs):
async with aiohttp.ClientSession(headers=self.headers) as session:
async with session.request(http_method, self.base_url + method, **kwargs) as response:
return await response.json()
async def create(self, request: CreateBillRequestSchema) -> CreateBillingResponseSchema:
json_data = request.model_dump()
response = await self._method('POST', '/create', json=json_data)
return CreateBillingResponseSchema.model_validate(response)
async def notify_received(self, request: NotifyReceivedBillRequestSchema) -> NotifyReceivedBillResponseSchema:
json_data = request.model_dump()
response = await self._method('POST', '/notify-received', json=json_data)
return NotifyReceivedBillResponseSchema.model_validate(response)

6
external/billing/enums.py vendored Normal file
View File

@@ -0,0 +1,6 @@
from enum import StrEnum
class NotificationChannel(StrEnum):
PAYMENT_DETAILS = 'PAYMENT_DETAILS'
PAYMENT_VERIFICATION = 'PAYMENT_VERIFICATION'

81
external/billing/schemas.py vendored Normal file
View File

@@ -0,0 +1,81 @@
import re
from typing import List
from pydantic import field_validator
from schemas.base import BaseSchema
from .enums import NotificationChannel
from datetime import datetime as dt
from datetime import date
phone_regexp = re.compile(r'^((\+7)([0-9]){10})$')
class CreateBillingRequestValue(BaseSchema):
name: str = ""
unit: str = "Руб"
vat: str = "None"
price: int
amount: int = 1
class CreateBillRequestItems(BaseSchema):
values: List[CreateBillingRequestValue]
class CreateBillRequestSchema(BaseSchema):
listener_transaction_id: int
payer_name: str
payer_inn: int
payer_phone: str | None
items: CreateBillRequestItems
@field_validator("payer_phone", mode="before")
def payer_phone_validator(cls, phone: str) -> str:
if phone is None:
return None
if not phone.startswith("+"):
phone = f"+{phone}"
if phone_regexp.match(phone):
return phone
return None
class NotifyReceivedBillRequestSchema(BaseSchema):
listener_transaction_id: int
channel: NotificationChannel
received: bool
class CreateBillingResponseSchema(BaseSchema):
ok: bool
class NotifyReceivedBillResponseSchema(BaseSchema):
ok: bool
class BillPaymentInfo(BaseSchema):
pdf_url: str
due_date: date
payment_amount: int
invoice_number: str
@field_validator('due_date', mode='plain')
def serialize_due_date(value: str) -> date:
date = dt.strptime(value, '%Y-%m-%d').date()
return date
class BillPaymentStatus(BaseSchema):
payed: bool
class BillStatusUpdateRequest(BaseSchema):
listener_transaction_id: int
channel: NotificationChannel
info: BillPaymentInfo | BillPaymentStatus