Use sid to route user back to the shopping cart from external cart builder

Hello all, this is my first post. I am enjoying learning about ERPNext.
Here is my situation.
I am creating a custom app with api calls to authenticate the user and then build a shopping cart.

This part is working. We collect the usr and pwd from the user, then pass that to a whitelisted function that logs in and returns the sid for subsequent calls.
We then update the cart with items.

Here is where I am hung up:
Once the cart is built from our external app I would like to send the user directly to the shopping cart to finalize the purchase. They may not be logged in on the default browser.

I am hoping to call an api endpoint and pass the sid, then be redirected to the cart.
Has this been done already?
If not, are there any recommendations on how?

Thanks in advance!

OK, so after a bunch of research, I have figured out how to do this.
Bear in mind that our shopping cart builder is part of a separate app.
We create the website user and login from api calls.
The user works in our tool to configure a widget then submits the info to build the cart.
This is where we go off the rails. We needed a way back to the cart on ERPNext.
Most of our api calls are made by passing back the sid.
So how do we pass the sid in a browser GET to redirect to the cart?

@frappe.whitelist( allow_guest=True )
def redirect_to_cart(sid):
	'''Redirects to the shopping cart of the user with the passed in sid.
		This allows a GET from any browser. Like: https://<you>/api/method/<yourapi>.redirect_to_cart?sid=<your-sid>

		Only works if the sid is valid (not expired).

		The sid parameter must be named sid since the frappe.form_dict 
		will keep a reference to it for use in the new Session call.
		
		If the sid is not found the function it routes to the login page.
		Sure would be nice if there was a way to redirect to the cart
		after login
		'''
	#we are going to redirect so let the response know
	frappe.local.response["type"] = "redirect"

	#format up a sql query on the Sessions table to get our user name 
	#from the sid.
	#there is probably a better way to do this by checking the cache
	#but i haven't figured it out yet.
	sql = f"""Select `user` from `tabSessions` WHERE `sid` = '{sid}'"""

	#run the query
	user_name = frappe.db.sql(sql)


	#if not found redirect to the login page.
	if not user_name:
		frappe.local.response["location"] = "/login"
		return
	
	#find our user from the username
	user = frappe.get_doc("User", user_name[0])

	#create a new session. It's really not new it is a resumed session if 
	#the user matches the sid in the constructor of the Session object
	#assign the resumed session to our local sesssion_obj
	frappe.local.session_obj = Session(user=user, resume=True,
			full_name=user.full_name, user_type=user.user_type)

	#redirect to the cart once our session has been resumed
	frappe.local.response["location"] = "/cart"

Hopefully this helps someone else out.
I am open to suggestions to improve it.

1 Like