custom_ui/custom_ui/api/public/payments.py

72 lines
No EOL
2.7 KiB
Python

import frappe
import json
from frappe.utils.data import flt
from custom_ui.services import DbService, StripeService, PaymentService
from custom_ui.models import PaymentData
@frappe.whitelist(allow_guest=True)
def half_down_stripe_payment(sales_order):
"""Public endpoint for initiating a half-down advance payment for a sales order."""
if not DbService.exists("Sales Order", sales_order):
frappe.throw("Sales Order does not exist.")
so = DbService.get_or_throw("Sales Order", sales_order)
if not so.requires_half_payment:
frappe.throw("This sales order does not require a half-down payment.")
if so.docstatus != 1:
frappe.throw("Sales Order must be submitted to proceed with payment.")
if so.custom_halfdown_is_paid or so.advanced_paid >= so.custom_halfdown_amount:
frappe.throw("Half-down payment has already been made for this sales order.")
stripe_session = StripeService.create_checkout_session(
company=so.company,
amount=so.custom_halfdown_amount,
service=so.custom_project_template,
sales_order=so.name,
for_advance_payment=True
)
return frappe.redirect(stripe_session.url)
@frappe.whitelist(allow_guest=True)
def stripe_webhook():
"""Endpoint to handle Stripe webhooks."""
payload = frappe.request.get_data()
sig_header = frappe.request.headers.get('Stripe-Signature')
session, metadata = StripeService.get_session_and_metadata(payload, sig_header)
required_keys = ["order_num", "company", "payment_type"]
for key in required_keys:
if not metadata.get(key):
raise frappe.ValidationError(f"Missing required metadata key: {key}")
if DbService.exists("Payment Entry", {"reference_no": session.id}):
raise frappe.ValidationError("Payment Entry already exists for this session.")
reference_doctype = "Sales Invoice"
if metadata.get("payment_type") == "advance":
reference_doctype = "Sales Order"
elif metadata.get("payment_type") != "full":
raise frappe.ValidationError("Invalid payment type in metadata.")
amount_paid = flt(session.amount_total) / 100
# stripe_settings = StripeService.get_stripe_settings(metadata.get("company"))
pe = PaymentService.create_payment_entry(
data=PaymentData(
mode_of_payment="Stripe",
reference_no=session.id,
reference_date=session.created,
received_amount=amount_paid,
company=metadata.get("company"),
reference_doc_name=metadata.get("order_num")
)
)
pe.submit()
return "Payment Entry created and submitted successfully."