fix: handle payment completion via payment request
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index b7d80ae..11ab020 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -950,12 +950,12 @@
 
 
 @frappe.whitelist()
-def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=None, mode_of_payment=None):
+def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=None):
 	doc = frappe.get_doc(dt, dn)
 	if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0:
 		frappe.throw(_("Can only make payment against unbilled {0}").format(dt))
 
-	if dt in ("Sales Invoice", "Sales Order", "Dunning", "POS Invoice"):
+	if dt in ("Sales Invoice", "Sales Order", "Dunning"):
 		party_type = "Customer"
 	elif dt in ("Purchase Invoice", "Purchase Order"):
 		party_type = "Supplier"
@@ -965,7 +965,7 @@
 		party_type = "Student"
 
 	# party account
-	if dt in ["Sales Invoice", "POS Invoice"]:
+	if dt == "Sales Invoice":
 		party_account = get_party_account_based_on_invoice_discounting(dn) or doc.debit_to
 	elif dt == "Purchase Invoice":
 		party_account = doc.credit_to
@@ -984,7 +984,7 @@
 		party_account_currency = doc.get("party_account_currency") or get_account_currency(party_account)
 
 	# payment type
-	if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees", "Dunning", "POS Invoice") and doc.outstanding_amount > 0)) \
+	if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees", "Dunning") and doc.outstanding_amount > 0)) \
 		or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
 			payment_type = "Receive"
 	else:
@@ -994,7 +994,7 @@
 	grand_total = outstanding_amount = 0
 	if party_amount:
 		grand_total = outstanding_amount = party_amount
-	elif dt in ("Sales Invoice", "Purchase Invoice", "POS Invoice"):
+	elif dt in ("Sales Invoice", "Purchase Invoice"):
 		if party_account_currency == doc.company_currency:
 			grand_total = doc.base_rounded_total or doc.base_grand_total
 		else:
@@ -1021,11 +1021,11 @@
 		outstanding_amount = grand_total - flt(doc.advance_paid)
 
 	# bank or cash
-	bank = get_default_bank_cash_account(doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment", mode_of_payment),
+	bank = get_default_bank_cash_account(doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment"),
 		account=bank_account)
 
 	if not bank:
-		bank = get_default_bank_cash_account(doc.company, "Cash", mode_of_payment=doc.get("mode_of_payment", mode_of_payment),
+		bank = get_default_bank_cash_account(doc.company, "Cash", mode_of_payment=doc.get("mode_of_payment"),
 			account=bank_account)
 
 	paid_amount = received_amount = 0
@@ -1050,7 +1050,7 @@
 	pe.company = doc.company
 	pe.cost_center = doc.get("cost_center")
 	pe.posting_date = nowdate()
-	pe.mode_of_payment = doc.get("mode_of_payment", mode_of_payment)
+	pe.mode_of_payment = doc.get("mode_of_payment")
 	pe.party_type = party_type
 	pe.party = doc.get(scrub(party_type))
 	pe.contact_person = doc.get("contact_person")
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.js b/erpnext/accounts/doctype/payment_request/payment_request.js
index e1e4314..5c72186 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.js
+++ b/erpnext/accounts/doctype/payment_request/payment_request.js
@@ -25,7 +25,7 @@
 })
 
 frappe.ui.form.on("Payment Request", "refresh", function(frm) {
-	if(frm.doc.payment_request_type == 'Inward' &&
+	if(frm.doc.payment_request_type == 'Inward' && frm.doc.payment_channel === "Phone" &&
 		!in_list(["Initiated", "Paid"], frm.doc.status) && !frm.doc.__islocal && frm.doc.docstatus==1){
 		frm.add_custom_button(__('Resend Payment Email'), function(){
 			frappe.call({
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py
index d01f298..ebe8cb1 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.py
+++ b/erpnext/accounts/doctype/payment_request/payment_request.py
@@ -86,6 +86,7 @@
 			payment_record = dict(
 				reference_doctype="Payment Request",
 				reference_docname=self.name,
+				payment_reference=self.reference_name,
 				grand_total=self.grand_total,
 				sender=self.email_to,
 				currency=self.currency,
@@ -154,10 +155,14 @@
 		})
 
 	def set_as_paid(self):
-		payment_entry = self.create_payment_entry()
-		self.make_invoice()
+		if self.payment_channel == "Phone":
+			self.db_set("status", "Paid")
 
-		return payment_entry
+		else:
+			payment_entry = self.create_payment_entry()
+			self.make_invoice()
+
+			return payment_entry
 
 	def create_payment_entry(self, submit=True):
 		"""create entry"""
@@ -269,7 +274,7 @@
 
 			# if shopping cart enabled and in session
 			if (shopping_cart_settings.enabled and hasattr(frappe.local, "session")
-				and frappe.local.session.user != "Guest") and  self.payment_channel != "Phone":
+				and frappe.local.session.user != "Guest") and self.payment_channel != "Phone":
 
 				success_url = shopping_cart_settings.payment_success_url
 				if success_url:
@@ -332,6 +337,7 @@
 			"payment_request_type": args.get("payment_request_type"),
 			"currency": ref_doc.currency,
 			"grand_total": grand_total,
+			"mode_of_payment": args.mode_of_payment,
 			"email_to": args.recipient_id or ref_doc.owner,
 			"subject": _("Payment Request for {0}").format(args.dn),
 			"message": gateway_account.get("message") or get_dummy_message(ref_doc),
diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
index 73cf118..1a304ca 100644
--- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
+++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
@@ -58,6 +58,7 @@
 			against_psi_doc.make_loyalty_point_entry()
 		if self.redeem_loyalty_points and self.loyalty_points:
 			self.apply_loyalty_points()
+		self.check_phone_payments()
 		self.set_status(update=True)
 
 	def on_cancel(self):
@@ -70,6 +71,18 @@
 			against_psi_doc.delete_loyalty_point_entry()
 			against_psi_doc.make_loyalty_point_entry()
 
+	def check_phone_payments(self):
+		for pay in self.payments:
+			if pay.type == "Phone" and pay.amount >= 0:
+				paid_amt = frappe.db.get_value("Payment Request",
+					filters=dict(
+						reference_doctype="POS Invoice", reference_name=self.name,
+						mode_of_payment=pay.mode_of_payment, status="Paid"),
+					fieldname="grand_total")
+
+				if pay.amount != paid_amt:
+					return frappe.throw(_("Payment related to {0} is not completed").format(pay.mode_of_payment))
+
 	def validate_stock_availablility(self):
 		allow_negative_stock = frappe.db.get_value('Stock Settings', None, 'allow_negative_stock')
 
@@ -333,6 +346,7 @@
 					"payment_request_type": "Inward",
 					"party_type": "Customer",
 					"party": self.customer,
+					"mode_of_payment": pay.mode_of_payment,
 					"recipient_id": self.contact_mobile,
 					"submit_doc": True
 				}
diff --git a/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.py b/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.py
index 8fc05c6..6c36c16 100644
--- a/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.py
+++ b/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.py
@@ -76,7 +76,7 @@
 
 		response = connector.stk_push(business_shortcode=mpesa_settings.till_number,
 			passcode=mpesa_settings.get_password("online_passkey"), amount=args.grand_total,
-			callback_url=callback_url, reference_code=args.payment_request_name,
+			callback_url=callback_url, reference_code=mpesa_settings.till_number,
 			phone_number=args.sender, description="POS Payment")
 
 		return response
@@ -100,14 +100,15 @@
 	transaction_data = frappe._dict(loads(request.data))
 
 	if transaction_response['ResultCode'] == 0:
-		if transaction_data.reference_doctype and transaction_data.reference_docname:
+		if request.reference_doctype and request.reference_docname:
 			try:
-				doc = frappe.get_doc(transaction_data.reference_doctype,
-					transaction_data.reference_docname).run_method("on_payment_authorized", 'Completed')
+				doc = frappe.get_doc(request.reference_doctype,
+					request.reference_docname)
+				doc.run_method("on_payment_authorized", 'Completed')
 
 				item_response = transaction_response["CallbackMetadata"]["Item"]
 				mpesa_receipt = fetch_param_value(item_response, "MpesaReceiptNumber", "Name")
-				frappe.db.set_value("POS Invoice", doc.reference_docname, "mpesa_receipt_number", mpesa_receipt)
+				frappe.db.set_value("POS Invoice", doc.reference_name, "mpesa_receipt_number", mpesa_receipt)
 				request.process_response('output', transaction_response)
 			except Exception:
 				request.process_response('error', transaction_response)
@@ -116,8 +117,8 @@
 	else:
 		request.process_response('error', transaction_response)
 
-	frappe.publish_realtime('process_phone_payment', after_commit=True, doctype=transaction_data.reference_doctype,
-		docname=transaction_data.reference_docname, user=request.owner, message=transaction_response)
+	frappe.publish_realtime('process_phone_payment', doctype="POS Invoice",
+		docname=transaction_data.payment_reference, user=request.owner, message=transaction_response)
 
 def get_account_balance(request_payload):
 	"""Call account balance API to send the request to the Mpesa Servers."""
diff --git a/erpnext/selling/page/point_of_sale/pos_payment.js b/erpnext/selling/page/point_of_sale/pos_payment.js
index 915564c..b1f7de0 100644
--- a/erpnext/selling/page/point_of_sale/pos_payment.js
+++ b/erpnext/selling/page/point_of_sale/pos_payment.js
@@ -9,8 +9,8 @@
 	}
 
 	init_component() {
-        this.prepare_dom();
-        this.initialize_numpad();
+		this.prepare_dom();
+		this.initialize_numpad();
 		this.bind_events();
 		this.attach_shortcuts();
 		
@@ -18,32 +18,32 @@
 
 	prepare_dom() {
 		this.wrapper.append(
-            `<section class="col-span-6 flex shadow rounded payment-section bg-white mx-h-70 h-100 d-none">
+			`<section class="col-span-6 flex shadow rounded payment-section bg-white mx-h-70 h-100 d-none">
 				<div class="flex flex-col p-16 pt-8 pb-8 w-full">
 					<div class="text-grey mb-6 payment-section no-select pointer">
 						PAYMENT METHOD<span class="octicon octicon-chevron-down collapse-indicator"></span>
 					</div>
 					<div class="payment-modes flex flex-wrap"></div>
 					<div class="invoice-details-section"></div>
-                    <div class="flex mt-auto justify-center w-full">
-                        <div class="flex flex-col justify-center flex-1 ml-4">
-                            <div class="flex w-full">
-                                <div class="totals-remarks items-end justify-end flex flex-1">
-                                    <div class="remarks text-md-0 text-grey mr-auto"></div>
-                                    <div class="totals flex justify-end pt-4"></div>
-                                </div>
-                                <div class="number-pad w-40 mb-4 ml-8 d-none"></div>
-                            </div>
-                            <div class="flex items-center justify-center mt-4 submit-order h-16 w-full rounded bg-primary text-md text-white no-select pointer text-bold">
-                                Complete Order
+					<div class="flex mt-auto justify-center w-full">
+							<div class="flex flex-col justify-center flex-1 ml-4">
+							<div class="flex w-full">
+								<div class="totals-remarks items-end justify-end flex flex-1">
+									<div class="remarks text-md-0 text-grey mr-auto"></div>
+									<div class="totals flex justify-end pt-4"></div>
+								</div>
+								<div class="number-pad w-40 mb-4 ml-8 d-none"></div>
+							</div>
+							<div class="flex items-center justify-center mt-4 submit-order h-16 w-full rounded bg-primary text-md text-white no-select pointer text-bold">
+								Complete Order
 							</div>
 							<div class="order-time flex items-center justify-end mt-2 pt-2 pb-2 w-full text-md-0 text-grey no-select pointer d-none"></div>
-                        </div>
-                    </div>
-                </div>
-            </section>`
-        )
-        this.$component = this.wrapper.find('.payment-section');
+						</div>
+					</div>
+				</div>
+			</section>`
+		)
+		this.$component = this.wrapper.find('.payment-section');
 		this.$payment_modes = this.$component.find('.payment-modes');
 		this.$totals_remarks = this.$component.find('.totals-remarks');
 		this.$totals = this.$component.find('.totals');
@@ -174,16 +174,16 @@
 			}
 		})
 
-		frappe.realtime.on("process_phone_payments", function(data) {
+		frappe.realtime.on("process_phone_payment", function(data) {
+			console.log('within')
 			frappe.dom.unfreeze();
 			let message = data["ResultDesc"];
 			let title = __("Payment Failed");
-			const frm = me.events.get_frm();
 
 			if (data["ResultCode"] == 0) {
 				title = __("Payment Received");
-				$('[data-fieldname=request_for_payment]').text("Paid")
-				cur_pos.submit()
+				$('.btn.btn-xs.btn-default[data-fieldname=request_for_payment]').html(`Payment Received`)
+				me.events.submit_invoice();
 			}
 
 			frappe.msgprint({
@@ -527,5 +527,5 @@
 
 	toggle_component(show) {
 		show ? this.$component.removeClass('d-none') : this.$component.addClass('d-none');
-    }
+	}
  }
\ No newline at end of file