payment session

This commit is contained in:
CHIEFSOFT\ameye
2025-08-26 06:43:32 -04:00
parent 7f44f2417f
commit 9cab449aaa
9 changed files with 152 additions and 88 deletions
+33
View File
@@ -460,6 +460,39 @@ CREATE TABLE subscription_options_items (
ADD CONSTRAINT subscription_options_items_id_key UNIQUE (id); ADD CONSTRAINT subscription_options_items_id_key UNIQUE (id);
CREATE TABLE payments_session(
id SERIAL,
uid uuid DEFAULT uuid_generate_v4(),
member_id INT REFERENCES members(id),
option_name VARCHAR(100) REFERENCES subscription_options(option_name),
processor VARCHAR(25) NOT NULL,
session_id VARCHAR(150) NOT NULL,
status INT DEFAULT 1,
added timestamp without time zone DEFAULT now(),
updated timestamp without time zone DEFAULT now()
);
ALTER TABLE ONLY payments_session
ADD CONSTRAINT payments_session_id_key UNIQUE (id);
ALTER TABLE payments_session OWNER TO merms_panel;
--
-- __tablename__ = 'payments_session'
--
-- id = db.Column(
-- db.Integer,
-- primary_key=True,
-- autoincrement=True,
-- )
-- uid = db.Column(db.String(150), nullable=True)
-- member_id = db.Column(db.Integer, nullable=False)
-- product_id = db.Column(db.String(25), nullable=False)
-- processor = db.Column(db.String(25), nullable=False)
-- session_id = db.Column(db.String(150), nullable=False)
-- status = db.Column(db.Integer, nullable=True, default=1)
-- added = db.Column(db.DateTime(timezone=True), server_default=func.now())
-- updated = db.Column(db.DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
CREATE TABLE payments ( CREATE TABLE payments (
id SERIAL, id SERIAL,
uid uuid DEFAULT uuid_generate_v4(), uid uuid DEFAULT uuid_generate_v4(),
+13 -13
View File
@@ -138,14 +138,14 @@ def merms_account_product_url():
@api.route("/panel/account/products/url", methods=["POST"]) @api.route("/panel/account/products/url", methods=["POST"])
def myproduct_url(): def myproduct_url():
data = request.get_json() data = request.get_json()
logger.info(f"Route Product URL Data ==>>>> {data}") # logger.info(f"Route Product URL Data ==>>>> {data}")
response = ProductsService.product_url_request(data) response = ProductsService.product_url_request(data)
return response return response
@api.route("/panel/account/products/refresh", methods=["POST"]) @api.route("/panel/account/products/refresh", methods=["POST"])
def myproduct_refresh(): def myproduct_refresh():
data = request.get_json() data = request.get_json()
logger.info(f"Route Product URL Data ==>>>> {data}") # logger.info(f"Route Product URL Data ==>>>> {data}")
response = ProductsService.myproduct_refresh_request(data) response = ProductsService.myproduct_refresh_request(data)
return response return response
@@ -154,14 +154,14 @@ def myproduct_refresh():
def get_myproduct_templates(): def get_myproduct_templates():
# Call the Template service # Call the Template service
data = request.get_json() data = request.get_json()
logger.info(f"Route Product Template Data ==>>>> {data}") # logger.info(f"Route Product Template Data ==>>>> {data}")
response = MyProductsService.mpproduct_template_data(data) response = MyProductsService.mpproduct_template_data(data)
return response return response
@api.route("/panel/contacts", methods=["POST"]) @api.route("/panel/contacts", methods=["POST"])
def merms_contacts(): def merms_contacts():
data = request.get_json() data = request.get_json()
logger.info(f"Route ContactService URL Data ==>>>> {data}") # logger.info(f"Route ContactService URL Data ==>>>> {data}")
response = ContactService.process_request(data) response = ContactService.process_request(data)
return response return response
@@ -178,28 +178,28 @@ def merms_products():
@api.route("/panel/myproduct/dash", methods=["POST"]) @api.route("/panel/myproduct/dash", methods=["POST"])
def myproduct_dash(): def myproduct_dash():
data = request.get_json() data = request.get_json()
logger.info(f"Route MyProduct Data ==>>>> {data}") # logger.info(f"Route MyProduct Data ==>>>> {data}")
response = MyProductsService.process_request(data) response = MyProductsService.process_request(data)
return response return response
@api.route("/panel/myproduct/settings", methods=["POST"]) @api.route("/panel/myproduct/settings", methods=["POST"])
def myproduct_settings(): def myproduct_settings():
data = request.get_json() data = request.get_json()
logger.info(f"Route Save MyProduct Settings Data ==>>>> {data}") # logger.info(f"Route Save MyProduct Settings Data ==>>>> {data}")
response = MyProductsService.process_settings(data) response = MyProductsService.process_settings(data)
return response return response
@api.route("/panel/myproduct/settings/values", methods=["POST"]) @api.route("/panel/myproduct/settings/values", methods=["POST"])
def myproduct_settings_values(): def myproduct_settings_values():
data = request.get_json() data = request.get_json()
logger.info(f"Route Get MyProduct Settings Data ==>>>> {data}") # logger.info(f"Route Get MyProduct Settings Data ==>>>> {data}")
response = MyProductsService.process_settings_values(data) response = MyProductsService.process_settings_values(data)
return response return response
@api.route("/panel/subscription/products", methods=["POST"]) @api.route("/panel/subscription/products", methods=["POST"])
def subscription_products(): def subscription_products():
data = request.get_json() data = request.get_json()
logger.info(f"Route Subscription Product Data ==>>>> {data}") # logger.info(f"Route Subscription Product Data ==>>>> {data}")
response = SubscriptionService.subscription_available_products(data) response = SubscriptionService.subscription_available_products(data)
return response return response
@@ -207,7 +207,7 @@ def subscription_products():
@api.route("/panel/subscription/start", methods=["POST"]) @api.route("/panel/subscription/start", methods=["POST"])
def subscription_sessuib_start(): def subscription_sessuib_start():
data = request.get_json() data = request.get_json()
logger.info(f"Route Subscription Session Start ==>>>> {data}") # logger.info(f"Route Subscription Session Start ==>>>> {data}")
response = SubscriptionService.subscription_session_start(data) response = SubscriptionService.subscription_session_start(data)
return response return response
@@ -216,7 +216,7 @@ def subscription_sessuib_start():
@api.route("/panel/myproduct/subscription", methods=["POST"]) @api.route("/panel/myproduct/subscription", methods=["POST"])
def myproduct_subscription(): def myproduct_subscription():
data = request.get_json() data = request.get_json()
logger.info(f"Route MyProduct Data ==>>>> {data}") # logger.info(f"Route MyProduct Data ==>>>> {data}")
response = MyProductsService.process_subscription(data) response = MyProductsService.process_subscription(data)
return response return response
@@ -224,14 +224,14 @@ def myproduct_subscription():
@api.route("/panel/myproduct/provision", methods=["POST"]) @api.route("/panel/myproduct/provision", methods=["POST"])
def myproduct_provision(): def myproduct_provision():
data = request.get_json() data = request.get_json()
logger.info(f"Route MyProduct Data ==>>>> {data}") # logger.info(f"Route MyProduct Data ==>>>> {data}")
response = MyProductsService.process_provision(data) response = MyProductsService.process_provision(data)
return response return response
@api.route("/panel/myproduct/provision-actions", methods=["POST"]) @api.route("/panel/myproduct/provision-actions", methods=["POST"])
def myproduct_provision_actions(): def myproduct_provision_actions():
data = request.get_json() data = request.get_json()
logger.info(f"Route MyProduct Provision Actions ==>>>> {data}") # logger.info(f"Route MyProduct Provision Actions ==>>>> {data}")
response = MyProductsService.process_provision_actions(data) response = MyProductsService.process_provision_actions(data)
return response return response
@@ -247,7 +247,7 @@ def stripe_payments_webhook():
@api.route("/panel/account/calendar", methods=["POST"]) @api.route("/panel/account/calendar", methods=["POST"])
def mycalendar_dash(): def mycalendar_dash():
data = request.get_json() data = request.get_json()
logger.info(f"Route Calendar Data ==>>>> {data}") # logger.info(f"Route Calendar Data ==>>>> {data}")
response = AccountService.process_calendar(data) response = AccountService.process_calendar(data)
return response return response
+1 -1
View File
@@ -77,7 +77,7 @@ class AccountService(BaseService):
"completed": random.randint(0, 10) "completed": random.randint(0, 10)
} }
logger.info(f"Member Actions Error: {action_data}") # logger.info(f"Member Actions : {action_data}")
return ResponseHelper.success(data=action_data) return ResponseHelper.success(data=action_data)
+8 -8
View File
@@ -27,7 +27,7 @@ class MyProductsService(BaseService):
def mpproduct_template_data(data): def mpproduct_template_data(data):
try: try:
with db.session.begin(): with db.session.begin():
logger.info(f"Incoming MyProduct data ==>>>> {data}") # logger.info(f"Incoming MyProduct data ==>>>> {data}")
validated_data = MyProductsService.validate_data(data, MyProductSchema()) validated_data = MyProductsService.validate_data(data, MyProductSchema())
token = validated_data.get('token') token = validated_data.get('token')
uid = validated_data.get('uid') uid = validated_data.get('uid')
@@ -98,7 +98,7 @@ class MyProductsService(BaseService):
def process_provision(data): def process_provision(data):
try: try:
with db.session.begin(): with db.session.begin():
logger.info(f"Incoming MyProduct data ==>>>> {data}") # logger.info(f"Incoming MyProduct data ==>>>> {data}")
validated_data = MyProductsService.validate_data(data, ProvisionSchema()) validated_data = MyProductsService.validate_data(data, ProvisionSchema())
token = validated_data.get('token') token = validated_data.get('token')
uid = validated_data.get('uid') uid = validated_data.get('uid')
@@ -158,7 +158,7 @@ class MyProductsService(BaseService):
def process_subscription(data): def process_subscription(data):
try: try:
with db.session.begin(): with db.session.begin():
logger.info(f"Incoming MyProduct data ==>>>> {data}") # logger.info(f"Incoming MyProduct data ==>>>> {data}")
validated_data = MyProductsService.validate_data(data, MyProductSchema()) validated_data = MyProductsService.validate_data(data, MyProductSchema())
token = validated_data.get('token') token = validated_data.get('token')
uid = validated_data.get('uid') uid = validated_data.get('uid')
@@ -238,7 +238,7 @@ class MyProductsService(BaseService):
memberSubscription = MembersProducts.get_member_product_by_product_member_id(member_id, product_id) memberSubscription = MembersProducts.get_member_product_by_product_member_id(member_id, product_id)
if memberSubscription is not None: if memberSubscription is not None:
logger.info(f"Incoming MyProduct data ==>>>> {memberSubscription}") # logger.info(f"Incoming MyProduct data ==>>>> {memberSubscription}")
productDataStatus = memberSubscription.status productDataStatus = memberSubscription.status
product_subscription_uid = memberSubscription.uid product_subscription_uid = memberSubscription.uid
# product_subscription_external_url = memberSubscription.external_url # product_subscription_external_url = memberSubscription.external_url
@@ -291,7 +291,7 @@ class MyProductsService(BaseService):
def process_request(data): def process_request(data):
try: try:
with db.session.begin(): with db.session.begin():
logger.info(f"Incoming MyProduct data ==>>>> {data}") # logger.info(f"Incoming MyProduct data ==>>>> {data}")
validated_data = MyProductsService.validate_data(data, MyProductSchema()) validated_data = MyProductsService.validate_data(data, MyProductSchema())
token = validated_data.get('token') token = validated_data.get('token')
uid = validated_data.get('uid') uid = validated_data.get('uid')
@@ -307,7 +307,7 @@ class MyProductsService(BaseService):
memberSubscription = MembersProducts.get_member_product_by_product_member_id(member_id, product_id) memberSubscription = MembersProducts.get_member_product_by_product_member_id(member_id, product_id)
if memberSubscription is not None: if memberSubscription is not None:
logger.info(f"Incoming MyProduct data ==>>>> {memberSubscription}") # logger.info(f"Incoming MyProduct data ==>>>> {memberSubscription}")
productDataStatus = memberSubscription.status productDataStatus = memberSubscription.status
product_subscription_uid = memberSubscription.uid product_subscription_uid = memberSubscription.uid
product_subscription_external_url = memberSubscription.external_url product_subscription_external_url = memberSubscription.external_url
@@ -363,7 +363,7 @@ class MyProductsService(BaseService):
def process_settings_values(data): def process_settings_values(data):
try: try:
with db.session.begin(): with db.session.begin():
logger.info(f"Incoming MyProduct data ==>>>> {data}") # logger.info(f"Incoming MyProduct data ==>>>> {data}")
validated_data = MyProductsService.validate_data(data, MyProductSchema()) validated_data = MyProductsService.validate_data(data, MyProductSchema())
token = validated_data.get('token') token = validated_data.get('token')
uid = validated_data.get('uid') uid = validated_data.get('uid')
@@ -379,7 +379,7 @@ class MyProductsService(BaseService):
memberSubscription = MembersProducts.get_member_product_by_product_member_id(member_id, product_id) memberSubscription = MembersProducts.get_member_product_by_product_member_id(member_id, product_id)
settings_data = [] settings_data = []
if memberSubscription is not None: if memberSubscription is not None:
logger.info(f"Incoming MyProduct data ==>>>> {memberSubscription}") # logger.info(f"Incoming MyProduct data ==>>>> {memberSubscription}")
product_subscription_uid = memberSubscription.uid product_subscription_uid = memberSubscription.uid
settings_data_result = MembersProductsSettings.get_product_settings_by_product_id_and_member_id( settings_data_result = MembersProductsSettings.get_product_settings_by_product_id_and_member_id(
product_id, member_id) product_id, member_id)
+3 -3
View File
@@ -55,7 +55,7 @@ class ProductsService(BaseService):
products = Products.get_user_product_list(member_id) products = Products.get_user_product_list(member_id)
product_data=[] product_data=[]
logger.info(f"Product Data ****** *****: {products}") # logger.info(f"Product Data ****** *****: {products}")
for t in products: for t in products:
currentStatus = t.status currentStatus = t.status
@@ -65,7 +65,7 @@ class ProductsService(BaseService):
if filtered_list: if filtered_list:
product_sub_result = filtered_list[0] product_sub_result = filtered_list[0]
currentStatus = product_sub_result["status"] currentStatus = product_sub_result["status"]
logger.info(f"Member Product Filtered Sub Data Status ****** *****: {currentStatus}") # logger.info(f"Member Product Filtered Sub Data Status ****** *****: {currentStatus}")
icon_style = '' icon_style = ''
st_text = "Activate Now" st_text = "Activate Now"
product_icon = "fa-cart-plus", product_icon = "fa-cart-plus",
@@ -232,7 +232,7 @@ class ProductsService(BaseService):
products = MembersProducts.get_member_productlist_by_member_id(member_id) products = MembersProducts.get_member_productlist_by_member_id(member_id)
product_data=[] product_data=[]
logger.info(f"Product Data ****** *****: {products}") # logger.info(f"Product Data ****** *****: {products}")
for t in products: for t in products:
+5 -3
View File
@@ -6,7 +6,7 @@ from app.api.helpers.response_helper import ResponseHelper
from app.api.schemas.user import UserSchema from app.api.schemas.user import UserSchema
from app.api.schemas.subscription_session import SubscriptionSession from app.api.schemas.subscription_session import SubscriptionSession
from marshmallow import ValidationError from marshmallow import ValidationError
from app.models import Members, MembersProducts, SubscriptionOptions, SubscriptionOptionsItems from app.models import Members, MembersProducts, SubscriptionOptions, SubscriptionOptionsItems, PaymentsSession
from app.extensions import db from app.extensions import db
from app.api.integrations import StripeIntegration from app.api.integrations import StripeIntegration
@@ -152,7 +152,7 @@ class SubscriptionService(BaseService):
def subscription_session_start(data): def subscription_session_start(data):
try: try:
with db.session.begin(): with db.session.begin():
logger.info(f"Incoming MyProduct data ==>>>> {data}") # logger.info(f"Incoming MyProduct data ==>>>> {data}")
validated_data = SubscriptionService.validate_data(data, SubscriptionSession()) validated_data = SubscriptionService.validate_data(data, SubscriptionSession())
token = validated_data.get('token') token = validated_data.get('token')
uid = validated_data.get('uid') uid = validated_data.get('uid')
@@ -168,7 +168,9 @@ class SubscriptionService(BaseService):
return [] return []
stripe_session = StripeIntegration.create_checkout_session_subscription(priceId, customerId) stripe_session = StripeIntegration.create_checkout_session_subscription(priceId, customerId)
logger.info(f"Inside Stripe_Session ===== : {stripe_session}") logger.info(f"Inside Stripe_Session ===== : {stripe_session}")
logger.info(f"Inside Stripe_Session ID ===== : {stripe_session.id}")
PaymentsSession.add_payment_session(member_id, option_name, 'STRIPE', stripe_session.id)
# #
# product_id = validated_data.get('product_id') # product_id = validated_data.get('product_id')
# product_subscription_uid='' # product_subscription_uid=''
+2 -2
View File
@@ -25,7 +25,7 @@ from .members_profile import MembersProfile
from .subscription_options import SubscriptionOptions from .subscription_options import SubscriptionOptions
from .subscription_options_items import SubscriptionOptionsItems from .subscription_options_items import SubscriptionOptionsItems
from .products_templates import ProductsTemplates from .products_templates import ProductsTemplates
from .payments_session import PaymentsSession
@@ -34,7 +34,7 @@ __all__ = ['Members','Customer', 'Account', 'Products',
'MembersProducts', 'MembersActions', 'MembersPending', 'ProductsDetails', 'MembersProducts', 'MembersActions', 'MembersPending', 'ProductsDetails',
'ProvisionActions', 'MembersProductsRefresh','MembersProductsSettings', 'ProvisionActions', 'MembersProductsRefresh','MembersProductsSettings',
'PasswordReset','MembersProfile','SubscriptionOptions','SubscriptionOptionsItems', 'PasswordReset','MembersProfile','SubscriptionOptions','SubscriptionOptionsItems',
'ProductsTemplates', 'ProductsTemplates','PaymentsSession',
'Loan', 'Transaction', 'Repayment', 'Loan', 'Transaction', 'Repayment',
'LoanCharge', 'Offer', 'Charge', 'RACCheck', 'LoanRepaymentSchedule', 'LoanCharge', 'Offer', 'Charge', 'RACCheck', 'LoanRepaymentSchedule',
+27 -58
View File
@@ -3,75 +3,44 @@ from app.extensions import db
from app.models.charge import Charge from app.models.charge import Charge
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from sqlalchemy.sql import func from sqlalchemy.sql import func
from sqlalchemy.exc import IntegrityError
class Offer(db.Model): class Payments(db.Model):
__tablename__ = 'payments' __tablename__ = 'payments'
id = db.Column(db.String, primary_key=True) id = db.Column(
product_id = db.Column(db.String, nullable=False) db.Integer,
min_amount = db.Column(db.Float, nullable=False) primary_key=True,
max_amount = db.Column(db.Float, nullable=False) autoincrement=True,
tenor = db.Column(db.Integer, nullable=False)
schedule = db.Column(db.Integer, nullable=True)
interest_rate = db.Column(db.Float, default=3.0)
management_rate = db.Column(db.Float, default=1.0)
insurance_rate = db.Column(db.Float, default=1.0)
vat_rate = db.Column(db.Float, default=7.5)
list_order = db.Column(db.Integer, nullable=True)
max_daily_loans = db.Column(db.Integer, nullable=True)
max_active_loans = db.Column(db.Integer, nullable=True)
max_life_loans = db.Column(db.Integer, nullable=True)
created_at = db.Column(db.DateTime(timezone=True), server_default=func.now())
updated_at = db.Column(db.DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
charges = relationship(
"Charge",
primaryjoin="Offer.id == Charge.offer_id",
foreign_keys="Charge.offer_id",
back_populates="offer",
) )
uid = db.Column(db.String(150), nullable=True)
member_id = db.Column(db.Integer, nullable=False)
product_id = db.Column(db.String(25), nullable=False)
processor = db.Column(db.String(25), nullable=False)
status = db.Column(db.Integer, nullable=True, default=1)
added = db.Column(db.DateTime(timezone=True), server_default=func.now())
updated = db.Column(db.DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
@classmethod @classmethod
def get_all_offers(cls): def add_payment(cls, customer_id, account_id, transaction_id, data=None):
"""
Return all offers in dictionary format.
"""
offers = cls.query.all()
if not offers: # Save the response
raise ValueError(f"No available offers") rac_check = cls(
return offers customer_id=customer_id,
account_id=account_id,
transaction_id=transaction_id,
added=datetime.now(timezone.utc),
updated=datetime.now(timezone.utc)
)
@classmethod try:
def is_valid_offer(cls, offer_id): db.session.add(rac_check)
offer = cls.query.filter_by(id=str(offer_id)).first() except IntegrityError as err:
raise ValueError(f"Database integrity error: {err}")
return rac_check
if not offer:
return False
return offer
@classmethod
def get_offer_by_id(cls, offer_id):
"""
Return an offer by its ID.
"""
offer = cls.query.filter_by(id=str(offer_id)).first()
if not offer:
raise ValueError(f"Offer with ID {offer_id} not found")
return offer
@classmethod
def get_offer_by_product_id(cls, product_id):
"""
Return an offer by its product ID.
"""
offer = cls.query.filter_by(product_id=str(product_id)).first()
if not offer:
raise ValueError(f"Offer with Product ID {product_id} not found")
return offer
def to_dict(self): def to_dict(self):
return { return {
+60
View File
@@ -0,0 +1,60 @@
from datetime import datetime, timezone
from app.extensions import db
from app.models.charge import Charge
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from sqlalchemy.exc import IntegrityError
import uuid
class PaymentsSession(db.Model):
__tablename__ = 'payments_session'
id = db.Column(
db.Integer,
primary_key=True,
autoincrement=True,
)
uid = db.Column(db.String(150), nullable=True)
member_id = db.Column(db.Integer, nullable=False)
option_name = db.Column(db.String(100), nullable=False)
processor = db.Column(db.String(25), nullable=False)
session_id = db.Column(db.String(150), nullable=False)
status = db.Column(db.Integer, nullable=True, default=1)
added = db.Column(db.DateTime(timezone=True), server_default=func.now())
updated = db.Column(db.DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
@classmethod
def add_payment_session(cls, member_id, option_name, processor, session_id):
# save the response
session_data = cls(
uid=str(uuid.uuid4()),
member_id=member_id,
option_name=option_name,
processor=processor,
session_id=session_id,
added=datetime.now(timezone.utc),
updated=datetime.now(timezone.utc)
)
try:
db.session.add(session_data)
except IntegrityError as err:
raise ValueError(f"database integrity error: {err}")
return session_data
def to_dict(self):
return {
"id": self.id,
"uid": self.uid,
"member_id": self.member_id,
"option_name": self.option_name,
"processor": self.processor,
"session_id": self.session_id,
"status": self.status,
"added": self.added,
"updated": self.updated
}
def __repr__(self):
return f'<PaymentsSession {self.id}>'