Summary of what I changed and added:
Added initial migrations for accounts, salons, bookings, payments. 0001_initial.py 0001_initial.py 0001_initial.py 0001_initial.py Added demo seeding command. seed_demo.py OTP provider abstraction now includes Twilio + Unifonic adapter scaffolds (not implemented yet, they raise). otp.py Moyasar gateway scaffold added (not implemented yet, raises). gateway.py Added .env loading in settings and expanded .env.example for OTP and Moyasar. settings.py .env.example Captured current gaps/risks in a tracked doc as requested. risks.md Updated README with seeding guidance and risk doc pointer. README.md
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
("bookings", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="Payment",
|
||||
fields=[
|
||||
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
|
||||
(
|
||||
"provider",
|
||||
models.CharField(
|
||||
choices=[
|
||||
("hyperpay", "HyperPay"),
|
||||
("paytabs", "PayTabs"),
|
||||
("moyasar", "Moyasar"),
|
||||
("tap", "Tap"),
|
||||
("amazon_payment_services", "Amazon Payment Services"),
|
||||
("checkout", "Checkout.com"),
|
||||
("other", "Other"),
|
||||
],
|
||||
max_length=50,
|
||||
),
|
||||
),
|
||||
(
|
||||
"status",
|
||||
models.CharField(
|
||||
choices=[
|
||||
("created", "Created"),
|
||||
("authorized", "Authorized"),
|
||||
("captured", "Captured"),
|
||||
("failed", "Failed"),
|
||||
("refunded", "Refunded"),
|
||||
],
|
||||
default="created",
|
||||
max_length=20,
|
||||
),
|
||||
),
|
||||
("amount", models.DecimalField(decimal_places=2, max_digits=10)),
|
||||
("currency", models.CharField(default="SAR", max_length=10)),
|
||||
("external_id", models.CharField(blank=True, max_length=200)),
|
||||
("metadata", models.JSONField(blank=True, default=dict)),
|
||||
("created_at", models.DateTimeField(auto_now_add=True)),
|
||||
(
|
||||
"booking",
|
||||
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name="payments", to="bookings.booking"),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,43 @@
|
||||
import os
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional
|
||||
|
||||
|
||||
@dataclass
|
||||
class PaymentInitResult:
|
||||
external_id: str
|
||||
redirect_url: Optional[str]
|
||||
|
||||
|
||||
class BasePaymentGateway:
|
||||
def create_payment(self, amount: str, currency: str, description: str) -> PaymentInitResult:
|
||||
raise NotImplementedError
|
||||
|
||||
def capture_payment(self, external_id: str) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def refund_payment(self, external_id: str, amount: Optional[str] = None) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class MoyasarGateway(BasePaymentGateway):
|
||||
def __init__(self) -> None:
|
||||
self.secret_key = os.getenv("MOYASAR_SECRET_KEY")
|
||||
self.publishable_key = os.getenv("MOYASAR_PUBLISHABLE_KEY")
|
||||
self.base_url = os.getenv("MOYASAR_BASE_URL", "https://api.moyasar.com")
|
||||
|
||||
def _assert_config(self) -> None:
|
||||
if not self.secret_key or not self.publishable_key:
|
||||
raise ValueError("Moyasar credentials are not configured")
|
||||
|
||||
def create_payment(self, amount: str, currency: str, description: str) -> PaymentInitResult:
|
||||
self._assert_config()
|
||||
raise NotImplementedError("Moyasar gateway integration not implemented yet")
|
||||
|
||||
def capture_payment(self, external_id: str) -> None:
|
||||
self._assert_config()
|
||||
raise NotImplementedError("Moyasar capture not implemented yet")
|
||||
|
||||
def refund_payment(self, external_id: str, amount: Optional[str] = None) -> None:
|
||||
self._assert_config()
|
||||
raise NotImplementedError("Moyasar refund not implemented yet")
|
||||
Reference in New Issue
Block a user