[{"data":1,"prerenderedAt":845},["ShallowReactive",2],{"header:help":3,"footer:default":67,"story:navigation\u002Fsearch:help":250,"story:help\u002Fcategories":288,"story:help\u002Farticles\u002Fset-up-sso-between-the-customer-portal-and-checkout":314,"no-guide:set-up-sso-between-the-customer-portal-and-checkout":59,"article:\u002Fhelp\u002Farticles\u002Fset-up-sso-between-the-customer-portal-and-checkout":609,"story:contact":626,"help:tree:5c105c21-8ef6-44b9-a0d0-df88448d7ee5":815,"_apollo:default":844},{"name":4,"created_at":5,"published_at":6,"updated_at":7,"id":8,"uuid":9,"content":10,"slug":57,"full_slug":58,"sort_by_date":59,"position":60,"tag_list":61,"is_startpage":24,"parent_id":62,"meta_data":59,"group_id":63,"first_published_at":64,"release_id":59,"lang":65,"path":59,"alternates":66,"default_full_slug":59,"translated_slugs":59},"Help Center Header","2024-08-09T18:06:34.939Z","2024-10-21T21:58:39.217Z","2024-10-21T21:58:39.232Z",10082752,"3e9b88f7-c163-4657-a2f2-62532d600fad",{"_uid":11,"link":12,"badge":16,"items":17,"title":13,"buttons":50,"new_tab":24,"submenu":51,"alignment":13,"component":52,"badge_link":53,"top_menu_items":56},"e5645a1a-f991-40e8-8d67-e40ebc082b5a",{"id":13,"url":13,"linktype":14,"fieldtype":15,"cached_url":13},"","story","multilink","Help Center",[18,27,34,39,44],{"_uid":19,"link":20,"title":23,"new_tab":24,"submenu":25,"component":26},"5cbe2861-1f49-4166-97da-a4dddd8105e3",{"id":21,"url":13,"linktype":14,"fieldtype":15,"cached_url":22},"4c0a2d99-ec30-4579-8ef1-6bf5564d4839","help\u002Fcategories\u002F","Articles",false,[],"header___item",{"_uid":28,"link":29,"title":32,"new_tab":33,"component":26},"1c8edeb5-b9e9-4cb8-b1c6-c1f292f7d7cd",{"id":13,"url":30,"linktype":31,"fieldtype":15,"cached_url":30},"https:\u002F\u002Fwiki.foxycart.com\u002F","url","Documentation",true,{"_uid":35,"link":36,"title":38,"new_tab":33,"component":26},"8d7df70e-f087-4da0-b616-6f0e9a5af35c",{"id":13,"url":37,"linktype":31,"fieldtype":15,"cached_url":37},"https:\u002F\u002Fapi.foxycart.com\u002F","API Documentation",{"_uid":40,"link":41,"title":43,"new_tab":33,"component":26},"f76e7944-23d5-4652-87e4-cdae79272762",{"id":13,"url":42,"linktype":31,"fieldtype":15,"cached_url":42},"https:\u002F\u002Fstatus.foxy.io\u002F","System Status",{"_uid":45,"link":46,"title":49,"new_tab":24,"component":26},"0de16771-4c84-466c-a1da-d8568113c71f",{"id":47,"url":13,"linktype":14,"fieldtype":15,"cached_url":48},"01e4e370-f9b9-45af-8fa9-f15540699b0d","contact","Contact Us",[],[],"header",{"id":54,"url":13,"linktype":14,"fieldtype":15,"cached_url":55},"4a679eb7-662d-4ea4-a976-5a2acbf0b663","help\u002F",[],"help-header","navigation\u002Fhelp-header",null,20,[],10082747,"71b81c2e-5e09-48a1-a397-a3c72fcd344a","2022-09-21T14:50:25.655Z","default",[],{"name":68,"created_at":69,"published_at":70,"updated_at":71,"id":72,"uuid":73,"content":74,"slug":243,"full_slug":244,"sort_by_date":59,"position":245,"tag_list":246,"is_startpage":24,"parent_id":62,"meta_data":59,"group_id":247,"first_published_at":248,"release_id":59,"lang":65,"path":59,"alternates":249,"default_full_slug":59,"translated_slugs":59},"Default Footer","2024-08-09T18:06:59.024Z","2025-09-04T06:24:46.223Z","2025-09-04T06:24:46.241Z",10082753,"e59e67ac-248a-482f-84a1-53d4f318186a",{"_uid":75,"about":76,"logos":77,"socials":82,"sections":108,"component":225,"cta_title":226,"bottom_links":227,"cta_subtitle":241,"cta_button_link":242,"cta_button_text":183},"830983f5-c4c4-43c8-b150-86a5e3fa6dc8","Foxy’s hosted cart & payment page allow you to sell anything, using your existing website or platform.",[78],{"id":79,"alt":13,"name":13,"focus":13,"title":13,"filename":80,"copyright":13,"fieldtype":81},14760,"https:\u002F\u002Fa-us.storyblok.com\u002Ff\u002F1001040\u002Fx\u002F3b030847ec\u002Fb-corp.svg","asset",[83,90,96,102],{"_uid":84,"icon":85,"link":86,"name":88,"component":89},"faf0a618-ea94-42ea-9182-03be18c43216","fa-facebook",{"id":13,"url":87,"linktype":31,"fieldtype":15,"cached_url":87},"https:\u002F\u002Fwww.facebook.com\u002Ffoxycart","Facebook","footer___social",{"_uid":91,"icon":92,"link":93,"name":95,"component":89},"14309c18-7e79-423e-b375-34555bac0811","fa-instagram",{"id":13,"url":94,"linktype":31,"fieldtype":15,"cached_url":94},"https:\u002F\u002Fwww.instagram.com\u002Ffoxy_io","Instagram",{"_uid":97,"icon":98,"link":99,"name":101,"component":89},"8f7fe7cf-0dd3-4596-8334-226ea466716a","fa-linkedin",{"id":13,"url":100,"linktype":31,"fieldtype":15,"cached_url":100},"https:\u002F\u002Fwww.linkedin.com\u002Fcompany\u002Ffoxycart.com","LinkedIn",{"_uid":103,"icon":104,"link":105,"name":107,"component":89},"90a675b4-dd97-40b5-be09-00a87223d4c5","fa-youtube",{"id":13,"url":106,"linktype":31,"fieldtype":15,"cached_url":106},"https:\u002F\u002Fwww.youtube.com\u002Fuser\u002Ffoxycart","Youtube",[109,139,184,206],{"_uid":110,"name":111,"items":112,"component":138},"82849945-282f-488c-b18d-a8d2252f514a","Company",[113,120,126,132],{"_uid":114,"link":115,"title":118,"new_tab":24,"component":119},"1f699ab1-938b-4d9d-9825-aabcbe6f57fe",{"id":116,"url":13,"linktype":14,"fieldtype":15,"cached_url":117},"63634293-a749-4226-9439-9f38ee6dcda0","about-us","About Us","footer___menu_items",{"_uid":121,"link":122,"title":125,"new_tab":24,"component":119},"b26b00f1-a0e7-4be2-8ab3-428b8cc841f8",{"id":123,"url":13,"linktype":14,"fieldtype":15,"cached_url":124},"26cb7c55-faed-4a77-a291-1552d4111b3e","how-foxy-works","How Foxy Works",{"_uid":127,"link":128,"title":131,"new_tab":24,"component":119},"b40c68a0-1ceb-4226-9515-6176534f61fe",{"id":129,"url":13,"linktype":14,"fieldtype":15,"cached_url":130},"dc6657d7-7f4f-4c0d-b781-e971b038ee26","for-good","Foxy For Good",{"_uid":133,"link":134,"title":137,"new_tab":24,"component":119},"3ad0c134-bef9-4fff-b891-e09f16109036",{"id":135,"url":13,"linktype":14,"fieldtype":15,"cached_url":136},"23cae210-baf4-4588-9862-d09f4f52ccd2","brand-assets","Brand Assets","footer___section",{"_uid":140,"name":141,"items":142,"component":138},"a6805fa8-ac60-47f1-b8f0-f27aded0afbe","Product",[143,149,155,161,167,173,179],{"_uid":144,"link":145,"title":148,"new_tab":24,"component":119},"b39c8a4e-2383-486f-b76a-11fbb15d8134",{"id":146,"url":13,"linktype":14,"fieldtype":15,"cached_url":147},"bb04690f-fe98-4ce6-80be-05b950f2364f","features\u002F","Features",{"_uid":150,"link":151,"title":154,"new_tab":24,"component":119},"64f8a41f-c181-433d-bc0a-fc94e71ecbf6",{"id":152,"url":13,"linktype":14,"fieldtype":15,"cached_url":153},"c450c58d-761d-48c0-a9af-0b064611689b","pricing","Pricing",{"_uid":156,"link":157,"title":160,"new_tab":24,"component":119},"6e0b287f-fd8c-4146-9e0e-0ab0b5c9ce3c",{"id":158,"url":13,"linktype":14,"fieldtype":15,"cached_url":159},"fab20ad9-e76a-4947-b709-3a6fdfa88028","blog\u002Fcategories\u002Fproduct-updates","Product Updates",{"_uid":162,"link":163,"title":166,"new_tab":24,"component":119},"47e5a074-a6b5-4f1c-8c2f-89a2ae9f83eb",{"id":164,"url":13,"linktype":14,"fieldtype":15,"cached_url":165},"d2c83612-d611-47f3-a3b4-ca7fe08540b8","changelogs\u002F","Changelogs",{"_uid":168,"link":169,"title":172,"new_tab":24,"component":119},"b5c08774-542f-4ffd-b357-c94d674488b9",{"id":170,"url":13,"linktype":14,"fieldtype":15,"cached_url":171},"08876121-0df3-4ed9-aa11-902b3e41cd02","whats-next","What's Next",{"_uid":174,"link":175,"title":178,"new_tab":24,"component":119},"9c2704ed-6d9f-43e1-9e67-c8d91c083288",{"id":176,"url":13,"linktype":14,"fieldtype":15,"cached_url":177},"056a7857-b18f-4025-8f97-91a38fc19bc8","compare\u002F","Compare",{"_uid":180,"link":181,"title":183,"new_tab":24,"component":119},"5f2db35b-674b-406a-8fa7-d246633af9fe",{"id":13,"url":182,"linktype":31,"fieldtype":15,"cached_url":182},"https:\u002F\u002Fadmin.foxy.io\u002Fsign-up","Try Foxy Free",{"_uid":185,"name":186,"items":187,"component":138},"63fa1f29-4252-4640-9922-fe310e69e54a","Security",[188,194,200],{"_uid":189,"link":190,"title":193,"new_tab":24,"component":119},"1158ddb6-9eb0-466f-8eb6-7ca2ae66c8b8",{"id":191,"url":13,"linktype":14,"fieldtype":15,"cached_url":192},"1f58fb2c-8681-4742-b6e8-09999beae9f6","security-contact","Security Contact",{"_uid":195,"link":196,"title":199,"new_tab":24,"component":119},"9a79c54a-6022-4dfd-854b-766f5e4703ba",{"id":197,"url":13,"linktype":14,"fieldtype":15,"cached_url":198},"55cbfcc3-425a-4261-8037-54e919851d2d","pci","PCI Compliance",{"_uid":201,"link":202,"title":205,"new_tab":24,"component":119},"0b85f5b6-9534-4071-b323-b39d053dd4d7",{"id":203,"url":13,"linktype":14,"fieldtype":15,"cached_url":204},"c3ac0fe3-83e2-4879-afbd-d4c83e1590df","help\u002Farticles\u002Four-official-domains-public-code","Domains & Codebases",{"_uid":207,"name":208,"items":209,"component":138},"998ded67-d107-49f4-8154-ca6be51671ec","Support",[210,213,216,219,222],{"_uid":211,"link":212,"title":16,"new_tab":24,"component":119},"594ffd35-3049-4004-bb08-0db568ebd819",{"id":54,"url":13,"linktype":14,"fieldtype":15,"cached_url":55},{"_uid":214,"link":215,"title":32,"new_tab":33,"component":119},"0a1a55ab-a985-4f9d-8b42-26da714d0c1c",{"id":13,"url":30,"linktype":31,"fieldtype":15,"cached_url":30},{"_uid":217,"link":218,"title":38,"new_tab":33,"component":119},"61e0b7c8-aadf-419b-a339-b3ccabc65bf4",{"id":13,"url":37,"linktype":31,"fieldtype":15,"cached_url":37},{"_uid":220,"link":221,"title":43,"new_tab":33,"component":119},"fd67a89e-1c54-4d31-94b5-64be999062d6",{"id":13,"url":42,"linktype":31,"fieldtype":15,"cached_url":42},{"_uid":223,"link":224,"title":49,"new_tab":24,"component":119},"231a6f71-e996-4ad4-b033-d4d5542f34f0",{"id":47,"url":13,"linktype":14,"fieldtype":15,"cached_url":48},"footer","Get started with our *unlimited free trial*.",[228,235],{"_uid":229,"link":230,"text":233,"component":234},"f0b77210-2632-45a2-8436-e57cad84d01a",{"id":231,"url":13,"linktype":14,"fieldtype":15,"cached_url":232},"60ba16a2-c1f4-485f-b978-8d2eeeafbf5a","terms-of-service","Terms of Service","footer___bottom_links",{"_uid":236,"link":237,"text":240,"component":234},"4bd497b0-993f-4b4d-a5b7-8a49c7c8fec9",{"id":238,"url":13,"linktype":14,"fieldtype":15,"cached_url":239},"332302b9-1d18-4016-b9c8-9b33c72d782b","privacy-policy","Privacy Policy","No credit card required.",{"id":13,"url":182,"linktype":31,"fieldtype":15,"cached_url":182},"default-footer","navigation\u002Fdefault-footer",50,[],"11006268-07f9-41e9-96f3-c51fb723399d","2022-09-21T20:39:02.357Z",[],{"name":251,"created_at":252,"published_at":253,"updated_at":254,"id":255,"uuid":256,"content":257,"slug":279,"full_slug":282,"sort_by_date":59,"position":283,"tag_list":284,"is_startpage":24,"parent_id":62,"meta_data":59,"group_id":285,"first_published_at":286,"release_id":59,"lang":65,"path":59,"alternates":287,"default_full_slug":59,"translated_slugs":59},"Search","2024-10-21T22:08:54.973Z","2025-05-26T09:17:25.790Z","2025-05-26T09:17:25.804Z",13592003,"14cbc359-9ac1-4a7a-a8de-ad4ac8ef26d4",{"_uid":258,"name":251,"indices":259,"summary":13,"component":279,"primary_image":280},"5e4a56e8-76f1-4790-b3a7-70f1be97d042",[260,265,269,274],{"key":261,"_uid":262,"icon":13,"name":263,"component":264},"all","c12a3210-7323-4273-8217-5215e52efe84","All","index",{"key":266,"_uid":267,"icon":268,"name":23,"component":264},"help_center_article","5acff080-95e4-44d3-8dcf-1b19720af382","fa-file-alt",{"key":270,"_uid":271,"icon":272,"name":273,"component":264},"help_center_guide","b8fbc206-c083-471e-a1f0-0ebeb90a669d","fa-book","Guides",{"key":275,"_uid":276,"icon":277,"name":278,"component":264},"blog_post","23419e83-2e56-4c4c-8a05-9fd1b3c9a9bd","fa-file-image","Blog Posts","search",{"id":59,"alt":59,"name":13,"focus":59,"title":59,"source":59,"filename":13,"copyright":59,"fieldtype":81,"meta_data":281},{},"navigation\u002Fsearch",60,[],"11e1fd31-95cd-4fc9-b736-8b8910663e6c","2024-10-21T23:17:05.904Z",[],{"name":23,"created_at":289,"published_at":290,"updated_at":291,"id":292,"uuid":21,"content":293,"slug":307,"full_slug":22,"sort_by_date":59,"position":308,"tag_list":309,"is_startpage":33,"parent_id":310,"meta_data":59,"group_id":311,"first_published_at":312,"release_id":59,"lang":65,"path":59,"alternates":313,"default_full_slug":59,"translated_slugs":59},"2022-09-19T14:42:29.685Z","2024-07-30T18:17:22.506Z","2024-07-30T18:17:22.525Z",2660,{"_uid":294,"icon":13,"name":23,"guides":295,"pinned":24,"summary":296,"category":13,"component":297,"blog_posts":298,"content_hub":24,"icon_custom":299,"case_studies":300,"faq_sections":301,"help_articles":302,"featured_guides":303,"mailbox_category":13,"featured_articles":304,"featured_blog_posts":305,"featured_case_studies":306},"d6dae89a-907a-4bf7-82de-fe2ba875ee6e",[],"Get your questions answered with our browsable knowledge base.","help_center_category",[],{"id":59,"alt":59,"name":13,"focus":59,"title":59,"filename":13,"copyright":59,"fieldtype":81},[],[],[],[],[],[],[],"categories",530,[],2658,"19ebcdd2-027f-47f5-9a5b-a8992c959578","2022-09-19T16:24:39.219Z",[],{"name":315,"created_at":316,"published_at":317,"updated_at":318,"id":319,"uuid":320,"content":321,"slug":602,"full_slug":603,"sort_by_date":59,"position":604,"tag_list":605,"is_startpage":24,"parent_id":606,"meta_data":59,"group_id":607,"first_published_at":317,"release_id":59,"lang":65,"path":59,"alternates":608,"default_full_slug":59,"translated_slugs":59},"Set up SSO between the customer portal and checkout","2026-07-16T21:39:50.224Z","2026-07-16T21:56:25.010Z","2026-07-16T21:56:25.025Z",198854206399280,"5c105c21-8ef6-44b9-a0d0-df88448d7ee5",{"_uid":322,"body":323,"name":315,"image":597,"pinned":24,"summary":599,"category":600,"component":266,"related_articles":601},"8b840db3-a495-49ac-bdd3-2ccb44aee2c0",{"type":324,"content":325},"doc",[326,333,340,367,372,377,401,407,489,495,506,530,535,540],{"type":327,"attrs":328,"content":329},"paragraph",{"textAlign":59},[330],{"text":331,"type":332},"By default, a customer who logs in to the customer portal isn’t automatically logged in to checkout. Setting up SSO between the two closes that gap, so customers don’t have to log in twice. How you set this up depends on whether you already use SSO elsewhere on your site.","text",{"type":334,"attrs":335,"content":337},"heading",{"level":336,"textAlign":59},2,[338],{"text":339,"type":332},"Notes before you start",{"type":341,"content":342},"bullet_list",[343,360],{"type":344,"content":345},"list_item",[346],{"type":327,"attrs":347,"content":348},{"textAlign":59},[349,351,358],{"text":350,"type":332},"This requires ",{"text":352,"type":332,"marks":353},"SSO to be enabled",[354],{"type":355,"attrs":356},"link",{"href":357,"uuid":59,"anchor":59,"target":59,"linktype":31},"https:\u002F\u002Ffoxy.io\u002Fhelp\u002Farticles\u002Fenable-the-customer-portal",{"text":359,"type":332}," in your Foxy admin’s advanced settings.",{"type":344,"content":361},[362],{"type":327,"attrs":363,"content":364},{"textAlign":59},[365],{"text":366,"type":332},"If you already use SSO for other purposes (like checking inventory or verifying cart contents), enabling it in the portal bypasses your own endpoint for this flow.",{"type":334,"attrs":368,"content":369},{"level":336,"textAlign":59},[370],{"text":371,"type":332},"Standalone SSO with the portal",{"type":327,"attrs":373,"content":374},{"textAlign":59},[375],{"text":376,"type":332},"Use this approach if you’re not using SSO anywhere else on your site.",{"type":327,"attrs":378,"content":379},{"textAlign":59},[380,382,387,389,393,395,399],{"text":381,"type":332},"When a customer’s session includes SSO (which happens by default with the standard portal setup), a ",{"text":383,"type":332,"marks":384},"GET \u002Fs\u002Fcustomer?sso=true",[385],{"type":386},"code",{"text":388,"type":332}," request returns a ",{"text":390,"type":332,"marks":391},"_links[\"fx:checkout\"].ref",[392],{"type":386},{"text":394,"type":332}," URL that logs the customer into checkout, and sets a cookie named ",{"text":396,"type":332,"marks":397},"fx.customer.sso",[398],{"type":386},{"text":400,"type":332},".",{"type":334,"attrs":402,"content":404},{"level":403,"textAlign":59},3,[405],{"text":406,"type":332},"Steps",{"type":408,"attrs":409,"content":411},"ordered_list",{"order":410},1,[412,425,464],{"type":344,"content":413},[414],{"type":327,"attrs":415,"content":416},{"textAlign":59},[417,419,423],{"text":418,"type":332},"In your Foxy admin, go to the advanced settings page and copy your store secret. If you use the JSON approach to specify unique secrets per feature, copy the ",{"text":420,"type":332,"marks":421},"sso",[422],{"type":386},{"text":424,"type":332}," value specifically.",{"type":344,"content":426},[427],{"type":327,"attrs":428,"content":429},{"textAlign":59},[430,432,436,438,444,446,450,452,456,458,462],{"text":431,"type":332},"Create an SSO URL for a guest (",{"text":433,"type":332,"marks":434},"customer_id=0",[435],{"type":386},{"text":437,"type":332},"). You can use a tool like ",{"text":439,"type":332,"marks":440},"CyberChef",[441],{"type":355,"attrs":442},{"href":443,"uuid":59,"anchor":59,"target":59,"linktype":31},"https:\u002F\u002Fgchq.github.io\u002FCyberChef\u002F#recipe=SHA1()",{"text":445,"type":332}," to generate a SHA1 hash of ",{"text":447,"type":332,"marks":448},"0|1893456000|YOUR_SECRET_HERE",[449],{"type":386},{"text":451,"type":332},", replacing ",{"text":453,"type":332,"marks":454},"YOUR_SECRET_HERE",[455],{"type":386},{"text":457,"type":332}," with your store secret. The output is your ",{"text":459,"type":332,"marks":460},"fc_auth_token",[461],{"type":386},{"text":463,"type":332}," value.",{"type":344,"content":465},[466],{"type":327,"attrs":467,"content":468},{"textAlign":59},[469,471,475,477,481,483,487],{"text":470,"type":332},"Create a new page on your site, at the same domain as the page containing your ",{"text":472,"type":332,"marks":473},"\u003Cfoxy-customer-portal>",[474],{"type":386},{"text":476,"type":332}," element, with the following code. Replace ",{"text":478,"type":332,"marks":479},"YOUR_FOXY_DOMAIN",[480],{"type":386},{"text":482,"type":332}," with your store domain, and ",{"text":484,"type":332,"marks":485},"REPLACE_THIS",[486],{"type":386},{"text":488,"type":332}," with the token from step 2.",{"type":490,"attrs":491,"content":492},"code_block",{"class":59},[493],{"text":494,"type":332},"   \u003C!doctype html>\n   \u003Chtml class=\"no-js\" lang=\"\">\n   \u003Chead>\n       \u003Cmeta charset=\"utf-8\">\n       \u003Ctitle>SSO Redirect\u003C\u002Ftitle>\n       \u003Cmeta name=\"ROBOTS\" CONTENT=\"NOINDEX, NOFOLLOW\">\n       \u003Cscript>\n           function parseJWT(token) {\n               let base64Url = token.split('.')[1];\n               let base64 = base64Url.replace(\u002F-\u002Fg, '+').replace(\u002F_\u002Fg, '\u002F');\n               let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {\n                   return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);\n               }).join(''));\n               return JSON.parse(jsonPayload);\n           }\n           function getSSOUrl() {\n               var value = \"; \" + document.cookie;\n               var parts = value.split(\"; \" + \"fx.customer.sso\" + \"=\");\n               if (parts.length == 2) return decodeURIComponent(parts.pop().split(\";\").shift());\n\n               try {\n                   let sessionStore = JSON.parse(localStorage.getItem(\"session\"));\n                   if (sessionStore && sessionStore.hasOwnProperty(\"jwt\")) {\n                       let sessionData = parseJWT(sessionStore.jwt);\n                       let expires = Math.floor(new Date(sessionStore.date_created).getTime() \u002F 1000) + sessionStore.expires_in;\n                       if (\n                           expires > Math.floor(Date.now() \u002F 1000) &&\n                           sessionData.hasOwnProperty(\"customer_id\") &&\n                           sessionStore.hasOwnProperty(\"sso\")\n                       ) {\n                           return sessionStore.sso;\n                       }\n                   }\n               } catch (error) {\n                   console.log(\"Error trying to get SSO URL:\", error);\n               }\n\n               return false;\n           }\n\n           function getUrlParameter(name) {\n               return new URLSearchParams(location.search).get('fcsid');\n           }\n\n           if (getSSOUrl()) {\n               window.location.replace(getSSOUrl() + \"&fcsid=\" + getUrlParameter(\"fcsid\"));\n           } else {\n               window.location.replace(\"https:\u002F\u002FYOUR_FOXY_DOMAIN\u002Fcheckout?fc_customer_id=0&timestamp=1893456000&fc_auth_token=REPLACE_THIS&fcsid=\" + getUrlParameter(\"fcsid\"));\n           }\n       \u003C\u002Fscript>\n   \u003C\u002Fhead>\n   \u003Cbody>\u003C\u002Fbody>\n   \u003C\u002Fhtml>\n",{"type":327,"attrs":496,"content":497},{"textAlign":59},[498,500,504],{"text":499,"type":332},"This page must be publicly accessible. If you’re inserting this into an existing template instead of using the page as-is, keep only the ",{"text":501,"type":332,"marks":502},"\u003Cscript>",[503],{"type":386},{"text":505,"type":332}," block, make sure the page is set to not be indexed by search engines, and strip out any unnecessary CSS or JavaScript so it loads as fast as possible.",{"type":408,"attrs":507,"content":508},{"order":410},[509,523],{"type":344,"content":510},[511],{"type":327,"attrs":512,"content":513},{"textAlign":59},[514,516,521],{"text":515,"type":332},"In your Foxy admin’s advanced settings, check ",{"text":517,"type":332,"marks":518},"Enable single sign on",[519],{"type":520},"bold",{"text":522,"type":332}," and enter the URL of the page you created in step 3. Save.",{"type":344,"content":524},[525],{"type":327,"attrs":526,"content":527},{"textAlign":59},[528],{"text":529,"type":332},"Test by logging in to the portal, then proceeding to checkout — you should already be logged in.",{"type":334,"attrs":531,"content":532},{"level":336,"textAlign":59},[533],{"text":534,"type":332},"Incorporating portal SSO with an existing SSO endpoint",{"type":327,"attrs":536,"content":537},{"textAlign":59},[538],{"text":539,"type":332},"Use this approach if you already have SSO enabled and configured on your site. There’s no single set of steps here, since integrations vary, but the general approach is:",{"type":341,"content":541},[542,571,590],{"type":344,"content":543},[544],{"type":327,"attrs":545,"content":546},{"textAlign":59},[547,551,553,557,559,563,565,569],{"text":548,"type":332,"marks":549},"Create the portal session and cookie when a customer logs in.",[550],{"type":520},{"text":552,"type":332}," When a customer submits their username and password, make a ",{"text":554,"type":332,"marks":555},"POST \u002Fs\u002Fcustomer\u002Fauthenticate",[556],{"type":386},{"text":558,"type":332}," request with those credentials, then store the JSON response in a ",{"text":560,"type":332,"marks":561},"localStorage",[562],{"type":386},{"text":564,"type":332}," item named ",{"text":566,"type":332,"marks":567},"session",[568],{"type":386},{"text":570,"type":332},". This requires the customer’s Foxy password to stay in sync with your own auth system.",{"type":344,"content":572},[573],{"type":327,"attrs":574,"content":575},{"textAlign":59},[576,580,582,588],{"text":577,"type":332,"marks":578},"If you don’t have access to the customer’s password",[579],{"type":520},{"text":581,"type":332},", use your store’s configured ",{"text":583,"type":332,"marks":584},"UOE password",[585],{"type":355,"attrs":586},{"href":587,"uuid":59,"anchor":59,"target":59,"linktype":31},"https:\u002F\u002Fwiki.foxycart.com\u002Fv\u002F2.0\u002Funified_order_entry",{"text":589,"type":332}," instead. This should only ever be used server-side — never expose it in the browser.",{"type":344,"content":591},[592],{"type":327,"attrs":593,"content":594},{"textAlign":59},[595],{"text":596,"type":332},"Unlike checkout, you likely don’t want to let a customer log in to the portal if they aren’t already logged in to your own system. Instead, redirect them to your login page so they end up fully logged in to your system (rather than just to the Foxy customer portal).",{"id":59,"alt":59,"name":13,"focus":59,"title":59,"source":59,"filename":13,"copyright":59,"fieldtype":81,"meta_data":598},{},"How to keep customers logged in when they move from the customer portal to checkout.","b4ff4108-a4b3-41f7-96cf-7df60b55fff0",[],"set-up-sso-between-the-customer-portal-and-checkout","help\u002Farticles\u002Fset-up-sso-between-the-customer-portal-and-checkout",-3500,[],2659,"b9426f5d-29a8-4409-b72e-3131848e15f0",[],{"html":610,"sections":611,"segments":622},"\u003Cp>By default, a customer who logs in to the customer portal isn’t automatically logged in to checkout. Setting up SSO between the two closes that gap, so customers don’t have to log in twice. How you set this up depends on whether you already use SSO elsewhere on your site.\u003C\u002Fp>\u003Csection id=\"notes-before-you-start\" data-title=\"Notes before you start\" data-title-node=\"H2\">\u003Chr class=\"my-8\" style=\"margin-left: -48px; margin-right: -40vw\">\u003Ch2 data-anchor-id=\"notes-before-you-start\">Notes before you start\u003C\u002Fh2>\u003Cul>\u003Cli>\u003Cp>This requires \u003Ca href=\"https:\u002F\u002Ffoxy.io\u002Fhelp\u002Farticles\u002Fenable-the-customer-portal\" class=\"\">SSO to be enabled\u003C\u002Fa> in your Foxy admin’s advanced settings.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>If you already use SSO for other purposes (like checking inventory or verifying cart contents), enabling it in the portal bypasses your own endpoint for this flow.\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>\u003C\u002Fsection>\u003Csection id=\"standalone-sso-with-the-portal\" data-title=\"Standalone SSO with the portal\" data-title-node=\"H2\">\u003Chr class=\"my-8\" style=\"margin-left: -48px; margin-right: -40vw\">\u003Ch2 data-anchor-id=\"standalone-sso-with-the-portal\">Standalone SSO with the portal\u003C\u002Fh2>\u003Cp>Use this approach if you’re not using SSO anywhere else on your site.\u003C\u002Fp>\u003Cp>When a customer’s session includes SSO (which happens by default with the standard portal setup), a \u003Ccode class=\"badge bg-soft-danger text-danger\">GET \u002Fs\u002Fcustomer?sso=true\u003C\u002Fcode> request returns a \u003Ccode class=\"badge bg-soft-danger text-danger\">_links[&quot;fx:checkout&quot;].ref\u003C\u002Fcode> URL that logs the customer into checkout, and sets a cookie named \u003Ccode class=\"badge bg-soft-danger text-danger\">fx.customer.sso\u003C\u002Fcode>.\u003C\u002Fp>\u003C\u002Fsection>\u003Csection id=\"steps\" data-title=\"Steps\" data-title-node=\"H3\">\u003Ch3 data-anchor-id=\"steps\">Steps\u003C\u002Fh3>\u003Col class=\"step step-icon-sm step-dashed step-border-last-0 mt-3\">\u003Cli class=\"step-item\">\u003Cdiv class=\"step-content-wrapper\">\u003Cspan class=\"step-icon step-icon-soft-primary\">1\u003C\u002Fspan>\u003Cdiv class=\"w-100 overflow-hidden\">\u003Cdiv class=\"step-content mt-2\">\u003Cp>In your Foxy admin, go to the advanced settings page and copy your store secret. If you use the JSON approach to specify unique secrets per feature, copy the \u003Ccode class=\"badge bg-soft-danger text-danger\">sso\u003C\u002Fcode> value specifically.\u003C\u002Fp>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fli>\u003Cli class=\"step-item\">\u003Cdiv class=\"step-content-wrapper\">\u003Cspan class=\"step-icon step-icon-soft-primary\">2\u003C\u002Fspan>\u003Cdiv class=\"w-100 overflow-hidden\">\u003Cdiv class=\"step-content mt-2\">\u003Cp>Create an SSO URL for a guest (\u003Ccode class=\"badge bg-soft-danger text-danger\">customer_id=0\u003C\u002Fcode>). You can use a tool like \u003Ca href=\"https:\u002F\u002Fgchq.github.io\u002FCyberChef\u002F#recipe=SHA1()\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">CyberChef\u003C\u002Fa> to generate a SHA1 hash of \u003Ccode class=\"badge bg-soft-danger text-danger\">0|1893456000|YOUR_SECRET_HERE\u003C\u002Fcode>, replacing \u003Ccode class=\"badge bg-soft-danger text-danger\">YOUR_SECRET_HERE\u003C\u002Fcode> with your store secret. The output is your \u003Ccode class=\"badge bg-soft-danger text-danger\">fc_auth_token\u003C\u002Fcode> value.\u003C\u002Fp>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fli>\u003Cli class=\"step-item\">\u003Cdiv class=\"step-content-wrapper\">\u003Cspan class=\"step-icon step-icon-soft-primary\">3\u003C\u002Fspan>\u003Cdiv class=\"w-100 overflow-hidden\">\u003Cdiv class=\"step-content mt-2\">\u003Cp>Create a new page on your site, at the same domain as the page containing your \u003Ccode class=\"badge bg-soft-danger text-danger\">&lt;foxy-customer-portal&gt;\u003C\u002Fcode> element, with the following code. Replace \u003Ccode class=\"badge bg-soft-danger text-danger\">YOUR_FOXY_DOMAIN\u003C\u002Fcode> with your store domain, and \u003Ccode class=\"badge bg-soft-danger text-danger\">REPLACE_THIS\u003C\u002Fcode> with the token from step 2.\u003C\u002Fp>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fli>\u003C\u002Fol>\u003Cdiv class=\"position-relative w-100 overflow-hidden rounded-2\" data-code-block>\u003Cdiv class=\"d-flex justify-content-end border-bottom\" style=\"background:#2b2c3b;\">\u003Cbutton type=\"button\" class=\"btn btn-link btn-sm text-light\" title=\"Copy\" data-code-button>\u003Cspan data-code-default style=\"\">\u003Ci class=\"fal fa-copy me-2\">\u003C\u002Fi> Copy \u003C\u002Fspan>\u003Cspan class=\"text-success\" data-code-success style=\"display:none;\">\u003Ci class=\"fal fa-check ms-2\">\u003C\u002Fi> Copied \u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cdiv class=\"small\">\u003Cpre class=\"hljs p-2\" data-code-content>   \u003Cspan class=\"hljs-meta\">&lt;!doctype \u003Cspan class=\"hljs-keyword\">html\u003C\u002Fspan>&gt;\u003C\u002Fspan>\n   \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">html\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">class\u003C\u002Fspan>=\u003Cspan class=\"hljs-string\">&quot;no-js&quot;\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">lang\u003C\u002Fspan>=\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C\u002Fspan>&gt;\u003C\u002Fspan>\n   \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">head\u003C\u002Fspan>&gt;\u003C\u002Fspan>\n       \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">meta\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">charset\u003C\u002Fspan>=\u003Cspan class=\"hljs-string\">&quot;utf-8&quot;\u003C\u002Fspan>&gt;\u003C\u002Fspan>\n       \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">title\u003C\u002Fspan>&gt;\u003C\u002Fspan>SSO Redirect\u003Cspan class=\"hljs-tag\">&lt;\u002F\u003Cspan class=\"hljs-name\">title\u003C\u002Fspan>&gt;\u003C\u002Fspan>\n       \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">meta\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">name\u003C\u002Fspan>=\u003Cspan class=\"hljs-string\">&quot;ROBOTS&quot;\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">CONTENT\u003C\u002Fspan>=\u003Cspan class=\"hljs-string\">&quot;NOINDEX, NOFOLLOW&quot;\u003C\u002Fspan>&gt;\u003C\u002Fspan>\n       \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">script\u003C\u002Fspan>&gt;\u003C\u002Fspan>\u003Cspan class=\"language-javascript\">\n           \u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title function_\">parseJWT\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">token\u003C\u002Fspan>) {\n               \u003Cspan class=\"hljs-keyword\">let\u003C\u002Fspan> base64Url = token.\u003Cspan class=\"hljs-title function_\">split\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">&#x27;.&#x27;\u003C\u002Fspan>)[\u003Cspan class=\"hljs-number\">1\u003C\u002Fspan>];\n               \u003Cspan class=\"hljs-keyword\">let\u003C\u002Fspan> base64 = base64Url.\u003Cspan class=\"hljs-title function_\">replace\u003C\u002Fspan>(\u003Cspan class=\"hljs-regexp\">\u002F-\u002Fg\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">&#x27;+&#x27;\u003C\u002Fspan>).\u003Cspan class=\"hljs-title function_\">replace\u003C\u002Fspan>(\u003Cspan class=\"hljs-regexp\">\u002F_\u002Fg\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">&#x27;\u002F&#x27;\u003C\u002Fspan>);\n               \u003Cspan class=\"hljs-keyword\">let\u003C\u002Fspan> jsonPayload = \u003Cspan class=\"hljs-built_in\">decodeURIComponent\u003C\u002Fspan>(\u003Cspan class=\"hljs-title function_\">atob\u003C\u002Fspan>(base64).\u003Cspan class=\"hljs-title function_\">split\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C\u002Fspan>).\u003Cspan class=\"hljs-title function_\">map\u003C\u002Fspan>(\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> (\u003Cspan class=\"hljs-params\">c\u003C\u002Fspan>) {\n                   \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&#x27;%&#x27;\u003C\u002Fspan> + (\u003Cspan class=\"hljs-string\">&#x27;00&#x27;\u003C\u002Fspan> + c.\u003Cspan class=\"hljs-title function_\">charCodeAt\u003C\u002Fspan>(\u003Cspan class=\"hljs-number\">0\u003C\u002Fspan>).\u003Cspan class=\"hljs-title function_\">toString\u003C\u002Fspan>(\u003Cspan class=\"hljs-number\">16\u003C\u002Fspan>)).\u003Cspan class=\"hljs-title function_\">slice\u003C\u002Fspan>(-\u003Cspan class=\"hljs-number\">2\u003C\u002Fspan>);\n               }).\u003Cspan class=\"hljs-title function_\">join\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C\u002Fspan>));\n               \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-title class_\">JSON\u003C\u002Fspan>.\u003Cspan class=\"hljs-title function_\">parse\u003C\u002Fspan>(jsonPayload);\n           }\n           \u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title function_\">getSSOUrl\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003C\u002Fspan>) {\n               \u003Cspan class=\"hljs-keyword\">var\u003C\u002Fspan> value = \u003Cspan class=\"hljs-string\">&quot;; &quot;\u003C\u002Fspan> + \u003Cspan class=\"hljs-variable language_\">document\u003C\u002Fspan>.\u003Cspan class=\"hljs-property\">cookie\u003C\u002Fspan>;\n               \u003Cspan class=\"hljs-keyword\">var\u003C\u002Fspan> parts = value.\u003Cspan class=\"hljs-title function_\">split\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">&quot;; &quot;\u003C\u002Fspan> + \u003Cspan class=\"hljs-string\">&quot;fx.customer.sso&quot;\u003C\u002Fspan> + \u003Cspan class=\"hljs-string\">&quot;=&quot;\u003C\u002Fspan>);\n               \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (parts.\u003Cspan class=\"hljs-property\">length\u003C\u002Fspan> == \u003Cspan class=\"hljs-number\">2\u003C\u002Fspan>) \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">decodeURIComponent\u003C\u002Fspan>(parts.\u003Cspan class=\"hljs-title function_\">pop\u003C\u002Fspan>().\u003Cspan class=\"hljs-title function_\">split\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">&quot;;&quot;\u003C\u002Fspan>).\u003Cspan class=\"hljs-title function_\">shift\u003C\u002Fspan>());\n\n               \u003Cspan class=\"hljs-keyword\">try\u003C\u002Fspan> {\n                   \u003Cspan class=\"hljs-keyword\">let\u003C\u002Fspan> sessionStore = \u003Cspan class=\"hljs-title class_\">JSON\u003C\u002Fspan>.\u003Cspan class=\"hljs-title function_\">parse\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable language_\">localStorage\u003C\u002Fspan>.\u003Cspan class=\"hljs-title function_\">getItem\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">&quot;session&quot;\u003C\u002Fspan>));\n                   \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (sessionStore &amp;&amp; sessionStore.\u003Cspan class=\"hljs-title function_\">hasOwnProperty\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">&quot;jwt&quot;\u003C\u002Fspan>)) {\n                       \u003Cspan class=\"hljs-keyword\">let\u003C\u002Fspan> sessionData = \u003Cspan class=\"hljs-title function_\">parseJWT\u003C\u002Fspan>(sessionStore.\u003Cspan class=\"hljs-property\">jwt\u003C\u002Fspan>);\n                       \u003Cspan class=\"hljs-keyword\">let\u003C\u002Fspan> expires = \u003Cspan class=\"hljs-title class_\">Math\u003C\u002Fspan>.\u003Cspan class=\"hljs-title function_\">floor\u003C\u002Fspan>(\u003Cspan class=\"hljs-keyword\">new\u003C\u002Fspan> \u003Cspan class=\"hljs-title class_\">Date\u003C\u002Fspan>(sessionStore.\u003Cspan class=\"hljs-property\">date_created\u003C\u002Fspan>).\u003Cspan class=\"hljs-title function_\">getTime\u003C\u002Fspan>() \u002F \u003Cspan class=\"hljs-number\">1000\u003C\u002Fspan>) + sessionStore.\u003Cspan class=\"hljs-property\">expires_in\u003C\u002Fspan>;\n                       \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (\n                           expires &gt; \u003Cspan class=\"hljs-title class_\">Math\u003C\u002Fspan>.\u003Cspan class=\"hljs-title function_\">floor\u003C\u002Fspan>(\u003Cspan class=\"hljs-title class_\">Date\u003C\u002Fspan>.\u003Cspan class=\"hljs-title function_\">now\u003C\u002Fspan>() \u002F \u003Cspan class=\"hljs-number\">1000\u003C\u002Fspan>) &amp;&amp;\n                           sessionData.\u003Cspan class=\"hljs-title function_\">hasOwnProperty\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">&quot;customer_id&quot;\u003C\u002Fspan>) &amp;&amp;\n                           sessionStore.\u003Cspan class=\"hljs-title function_\">hasOwnProperty\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">&quot;sso&quot;\u003C\u002Fspan>)\n                       ) {\n                           \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> sessionStore.\u003Cspan class=\"hljs-property\">sso\u003C\u002Fspan>;\n                       }\n                   }\n               } \u003Cspan class=\"hljs-keyword\">catch\u003C\u002Fspan> (error) {\n                   \u003Cspan class=\"hljs-variable language_\">console\u003C\u002Fspan>.\u003Cspan class=\"hljs-title function_\">log\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">&quot;Error trying to get SSO URL:&quot;\u003C\u002Fspan>, error);\n               }\n\n               \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-literal\">false\u003C\u002Fspan>;\n           }\n\n           \u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title function_\">getUrlParameter\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">name\u003C\u002Fspan>) {\n               \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-keyword\">new\u003C\u002Fspan> \u003Cspan class=\"hljs-title class_\">URLSearchParams\u003C\u002Fspan>(location.\u003Cspan class=\"hljs-property\">search\u003C\u002Fspan>).\u003Cspan class=\"hljs-title function_\">get\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">&#x27;fcsid&#x27;\u003C\u002Fspan>);\n           }\n\n           \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (\u003Cspan class=\"hljs-title function_\">getSSOUrl\u003C\u002Fspan>()) {\n               \u003Cspan class=\"hljs-variable language_\">window\u003C\u002Fspan>.\u003Cspan class=\"hljs-property\">location\u003C\u002Fspan>.\u003Cspan class=\"hljs-title function_\">replace\u003C\u002Fspan>(\u003Cspan class=\"hljs-title function_\">getSSOUrl\u003C\u002Fspan>() + \u003Cspan class=\"hljs-string\">&quot;&amp;fcsid=&quot;\u003C\u002Fspan> + \u003Cspan class=\"hljs-title function_\">getUrlParameter\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">&quot;fcsid&quot;\u003C\u002Fspan>));\n           } \u003Cspan class=\"hljs-keyword\">else\u003C\u002Fspan> {\n               \u003Cspan class=\"hljs-variable language_\">window\u003C\u002Fspan>.\u003Cspan class=\"hljs-property\">location\u003C\u002Fspan>.\u003Cspan class=\"hljs-title function_\">replace\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">&quot;https:\u002F\u002FYOUR_FOXY_DOMAIN\u002Fcheckout?fc_customer_id=0&amp;timestamp=1893456000&amp;fc_auth_token=REPLACE_THIS&amp;fcsid=&quot;\u003C\u002Fspan> + \u003Cspan class=\"hljs-title function_\">getUrlParameter\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">&quot;fcsid&quot;\u003C\u002Fspan>));\n           }\n       \u003C\u002Fspan>\u003Cspan class=\"hljs-tag\">&lt;\u002F\u003Cspan class=\"hljs-name\">script\u003C\u002Fspan>&gt;\u003C\u002Fspan>\n   \u003Cspan class=\"hljs-tag\">&lt;\u002F\u003Cspan class=\"hljs-name\">head\u003C\u002Fspan>&gt;\u003C\u002Fspan>\n   \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">body\u003C\u002Fspan>&gt;\u003C\u002Fspan>\u003Cspan class=\"hljs-tag\">&lt;\u002F\u003Cspan class=\"hljs-name\">body\u003C\u002Fspan>&gt;\u003C\u002Fspan>\n   \u003Cspan class=\"hljs-tag\">&lt;\u002F\u003Cspan class=\"hljs-name\">html\u003C\u002Fspan>&gt;\u003C\u002Fspan>\n\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cp>This page must be publicly accessible. If you’re inserting this into an existing template instead of using the page as-is, keep only the \u003Ccode class=\"badge bg-soft-danger text-danger\">&lt;script&gt;\u003C\u002Fcode> block, make sure the page is set to not be indexed by search engines, and strip out any unnecessary CSS or JavaScript so it loads as fast as possible.\u003C\u002Fp>\u003Col class=\"step step-icon-sm step-dashed step-border-last-0 mt-3\">\u003Cli class=\"step-item\">\u003Cdiv class=\"step-content-wrapper\">\u003Cspan class=\"step-icon step-icon-soft-primary\">1\u003C\u002Fspan>\u003Cdiv class=\"w-100 overflow-hidden\">\u003Cdiv class=\"step-content mt-2\">\u003Cp>In your Foxy admin’s advanced settings, check \u003Cstrong>Enable single sign on\u003C\u002Fstrong> and enter the URL of the page you created in step 3. Save.\u003C\u002Fp>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fli>\u003Cli class=\"step-item\">\u003Cdiv class=\"step-content-wrapper\">\u003Cspan class=\"step-icon step-icon-soft-primary\">2\u003C\u002Fspan>\u003Cdiv class=\"w-100 overflow-hidden\">\u003Cdiv class=\"step-content mt-2\">\u003Cp>Test by logging in to the portal, then proceeding to checkout — you should already be logged in.\u003C\u002Fp>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fli>\u003C\u002Fol>\u003C\u002Fsection>\u003Csection id=\"incorporating-portal-sso-with-an-existing-sso-endpoint\" data-title=\"Incorporating portal SSO with an existing SSO endpoint\" data-title-node=\"H2\">\u003Chr class=\"my-8\" style=\"margin-left: -48px; margin-right: -40vw\">\u003Ch2 data-anchor-id=\"incorporating-portal-sso-with-an-existing-sso-endpoint\">Incorporating portal SSO with an existing SSO endpoint\u003C\u002Fh2>\u003Cp>Use this approach if you already have SSO enabled and configured on your site. There’s no single set of steps here, since integrations vary, but the general approach is:\u003C\u002Fp>\u003Cul>\u003Cli>\u003Cp>\u003Cstrong>Create the portal session and cookie when a customer logs in.\u003C\u002Fstrong> When a customer submits their username and password, make a \u003Ccode class=\"badge bg-soft-danger text-danger\">POST \u002Fs\u002Fcustomer\u002Fauthenticate\u003C\u002Fcode> request with those credentials, then store the JSON response in a \u003Ccode class=\"badge bg-soft-danger text-danger\">localStorage\u003C\u002Fcode> item named \u003Ccode class=\"badge bg-soft-danger text-danger\">session\u003C\u002Fcode>. This requires the customer’s Foxy password to stay in sync with your own auth system.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>If you don’t have access to the customer’s password\u003C\u002Fstrong>, use your store’s configured \u003Ca href=\"https:\u002F\u002Fwiki.foxycart.com\u002Fv\u002F2.0\u002Funified_order_entry\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">UOE password\u003C\u002Fa> instead. This should only ever be used server-side — never expose it in the browser.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>Unlike checkout, you likely don’t want to let a customer log in to the portal if they aren’t already logged in to your own system. Instead, redirect them to your login page so they end up fully logged in to your system (rather than just to the Foxy customer portal).\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>\u003C\u002Fsection>",[612,615,617,620],{"id":613,"title":339,"level":614},"notes-before-you-start","H2",{"id":616,"title":371,"level":614},"standalone-sso-with-the-portal",{"id":618,"title":406,"level":619},"steps","H3",{"id":621,"title":534,"level":614},"incorporating-portal-sso-with-an-existing-sso-endpoint",[623],{"type":624,"content":625},"html","\u003Cp>By default, a customer who logs in to the customer portal isn’t automatically logged in to checkout. Setting up SSO between the two closes that gap, so customers don’t have to log in twice. How you set this up depends on whether you already use SSO elsewhere on your site.\u003C\u002Fp>\u003Ch2>Notes before you start\u003C\u002Fh2>\u003Cul>\u003Cli>\u003Cp>This requires \u003Ca href=\"https:\u002F\u002Ffoxy.io\u002Fhelp\u002Farticles\u002Fenable-the-customer-portal\" class=\"\">SSO to be enabled\u003C\u002Fa> in your Foxy admin’s advanced settings.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>If you already use SSO for other purposes (like checking inventory or verifying cart contents), enabling it in the portal bypasses your own endpoint for this flow.\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Standalone SSO with the portal\u003C\u002Fh2>\u003Cp>Use this approach if you’re not using SSO anywhere else on your site.\u003C\u002Fp>\u003Cp>When a customer’s session includes SSO (which happens by default with the standard portal setup), a \u003Ccode class=\"badge bg-soft-danger text-danger\">GET \u002Fs\u002Fcustomer?sso=true\u003C\u002Fcode> request returns a \u003Ccode class=\"badge bg-soft-danger text-danger\">_links[&quot;fx:checkout&quot;].ref\u003C\u002Fcode> URL that logs the customer into checkout, and sets a cookie named \u003Ccode class=\"badge bg-soft-danger text-danger\">fx.customer.sso\u003C\u002Fcode>.\u003C\u002Fp>\u003Ch3>Steps\u003C\u002Fh3>\u003Col order=\"1\">\u003Cli>\u003Cp>In your Foxy admin, go to the advanced settings page and copy your store secret. If you use the JSON approach to specify unique secrets per feature, copy the \u003Ccode class=\"badge bg-soft-danger text-danger\">sso\u003C\u002Fcode> value specifically.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>Create an SSO URL for a guest (\u003Ccode class=\"badge bg-soft-danger text-danger\">customer_id=0\u003C\u002Fcode>). You can use a tool like \u003Ca href=\"https:\u002F\u002Fgchq.github.io\u002FCyberChef\u002F#recipe=SHA1()\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">CyberChef\u003C\u002Fa> to generate a SHA1 hash of \u003Ccode class=\"badge bg-soft-danger text-danger\">0|1893456000|YOUR_SECRET_HERE\u003C\u002Fcode>, replacing \u003Ccode class=\"badge bg-soft-danger text-danger\">YOUR_SECRET_HERE\u003C\u002Fcode> with your store secret. The output is your \u003Ccode class=\"badge bg-soft-danger text-danger\">fc_auth_token\u003C\u002Fcode> value.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>Create a new page on your site, at the same domain as the page containing your \u003Ccode class=\"badge bg-soft-danger text-danger\">&lt;foxy-customer-portal&gt;\u003C\u002Fcode> element, with the following code. Replace \u003Ccode class=\"badge bg-soft-danger text-danger\">YOUR_FOXY_DOMAIN\u003C\u002Fcode> with your store domain, and \u003Ccode class=\"badge bg-soft-danger text-danger\">REPLACE_THIS\u003C\u002Fcode> with the token from step 2.\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Fol>\u003Cpre>\u003Ccode>   &lt;!doctype html&gt;\n   &lt;html class=&quot;no-js&quot; lang=&quot;&quot;&gt;\n   &lt;head&gt;\n       &lt;meta charset=&quot;utf-8&quot;&gt;\n       &lt;title&gt;SSO Redirect&lt;\u002Ftitle&gt;\n       &lt;meta name=&quot;ROBOTS&quot; CONTENT=&quot;NOINDEX, NOFOLLOW&quot;&gt;\n       &lt;script&gt;\n           function parseJWT(token) {\n               let base64Url = token.split(&#039;.&#039;)[1];\n               let base64 = base64Url.replace(\u002F-\u002Fg, &#039;+&#039;).replace(\u002F_\u002Fg, &#039;\u002F&#039;);\n               let jsonPayload = decodeURIComponent(atob(base64).split(&#039;&#039;).map(function (c) {\n                   return &#039;%&#039; + (&#039;00&#039; + c.charCodeAt(0).toString(16)).slice(-2);\n               }).join(&#039;&#039;));\n               return JSON.parse(jsonPayload);\n           }\n           function getSSOUrl() {\n               var value = &quot;; &quot; + document.cookie;\n               var parts = value.split(&quot;; &quot; + &quot;fx.customer.sso&quot; + &quot;=&quot;);\n               if (parts.length == 2) return decodeURIComponent(parts.pop().split(&quot;;&quot;).shift());\n\n               try {\n                   let sessionStore = JSON.parse(localStorage.getItem(&quot;session&quot;));\n                   if (sessionStore &amp;&amp; sessionStore.hasOwnProperty(&quot;jwt&quot;)) {\n                       let sessionData = parseJWT(sessionStore.jwt);\n                       let expires = Math.floor(new Date(sessionStore.date_created).getTime() \u002F 1000) + sessionStore.expires_in;\n                       if (\n                           expires &gt; Math.floor(Date.now() \u002F 1000) &amp;&amp;\n                           sessionData.hasOwnProperty(&quot;customer_id&quot;) &amp;&amp;\n                           sessionStore.hasOwnProperty(&quot;sso&quot;)\n                       ) {\n                           return sessionStore.sso;\n                       }\n                   }\n               } catch (error) {\n                   console.log(&quot;Error trying to get SSO URL:&quot;, error);\n               }\n\n               return false;\n           }\n\n           function getUrlParameter(name) {\n               return new URLSearchParams(location.search).get(&#039;fcsid&#039;);\n           }\n\n           if (getSSOUrl()) {\n               window.location.replace(getSSOUrl() + &quot;&amp;fcsid=&quot; + getUrlParameter(&quot;fcsid&quot;));\n           } else {\n               window.location.replace(&quot;https:\u002F\u002FYOUR_FOXY_DOMAIN\u002Fcheckout?fc_customer_id=0&amp;timestamp=1893456000&amp;fc_auth_token=REPLACE_THIS&amp;fcsid=&quot; + getUrlParameter(&quot;fcsid&quot;));\n           }\n       &lt;\u002Fscript&gt;\n   &lt;\u002Fhead&gt;\n   &lt;body&gt;&lt;\u002Fbody&gt;\n   &lt;\u002Fhtml&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>This page must be publicly accessible. If you’re inserting this into an existing template instead of using the page as-is, keep only the \u003Ccode class=\"badge bg-soft-danger text-danger\">&lt;script&gt;\u003C\u002Fcode> block, make sure the page is set to not be indexed by search engines, and strip out any unnecessary CSS or JavaScript so it loads as fast as possible.\u003C\u002Fp>\u003Col order=\"1\">\u003Cli>\u003Cp>In your Foxy admin’s advanced settings, check \u003Cstrong>Enable single sign on\u003C\u002Fstrong> and enter the URL of the page you created in step 3. Save.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>Test by logging in to the portal, then proceeding to checkout — you should already be logged in.\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Fol>\u003Ch2>Incorporating portal SSO with an existing SSO endpoint\u003C\u002Fh2>\u003Cp>Use this approach if you already have SSO enabled and configured on your site. There’s no single set of steps here, since integrations vary, but the general approach is:\u003C\u002Fp>\u003Cul>\u003Cli>\u003Cp>\u003Cstrong>Create the portal session and cookie when a customer logs in.\u003C\u002Fstrong> When a customer submits their username and password, make a \u003Ccode class=\"badge bg-soft-danger text-danger\">POST \u002Fs\u002Fcustomer\u002Fauthenticate\u003C\u002Fcode> request with those credentials, then store the JSON response in a \u003Ccode class=\"badge bg-soft-danger text-danger\">localStorage\u003C\u002Fcode> item named \u003Ccode class=\"badge bg-soft-danger text-danger\">session\u003C\u002Fcode>. This requires the customer’s Foxy password to stay in sync with your own auth system.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>If you don’t have access to the customer’s password\u003C\u002Fstrong>, use your store’s configured \u003Ca href=\"https:\u002F\u002Fwiki.foxycart.com\u002Fv\u002F2.0\u002Funified_order_entry\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">UOE password\u003C\u002Fa> instead. This should only ever be used server-side — never expose it in the browser.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>Unlike checkout, you likely don’t want to let a customer log in to the portal if they aren’t already logged in to your own system. Instead, redirect them to your login page so they end up fully logged in to your system (rather than just to the Foxy customer portal).\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>",{"name":627,"created_at":628,"published_at":629,"updated_at":630,"id":631,"uuid":47,"content":632,"slug":48,"full_slug":48,"sort_by_date":59,"position":810,"tag_list":811,"is_startpage":24,"parent_id":59,"meta_data":59,"group_id":812,"first_published_at":813,"release_id":59,"lang":65,"path":59,"alternates":814,"default_full_slug":59,"translated_slugs":59},"Contact","2022-09-23T19:56:58.957Z","2025-05-08T18:24:40.382Z","2025-05-08T18:24:40.392Z",3138,{"seo":633,"_uid":636,"title":637,"action":638,"fields":639,"method":786,"columns":787,"subtitle":801,"component":48,"button_text":807,"submit_title":808,"submit_subtitle":809},{"_uid":634,"title":627,"plugin":635,"description":13},"24ff7574-3bcc-48d2-85b5-e529dfea1cc4","meta-fields","8f54f1da-9d8f-49b2-89e7-840e886491cb","We're here to help.","https:\u002F\u002Fusebasin.com\u002Ff\u002F029f48d65402",[640,645,649,757,760,765,780],{"_uid":641,"name":642,"type":332,"label":643,"options":13,"required":33,"component":644,"placeholder":13},"9a70b226-2036-4f90-a052-b3efa61c5896","name","Name","form___field",{"_uid":646,"name":647,"type":647,"label":648,"options":13,"required":33,"component":644,"placeholder":13},"86ba35be-ff43-4a28-8633-14052a8f6622","email","Email Address",{"_uid":650,"name":651,"type":652,"label":653,"options":654,"required":33,"component":644,"conditions":655,"placeholder":13},"3f827475-492c-4f97-aa1e-2386ac263b6c","topic","select","Topic","Presales, Support, Billing, Partnerships, Order Enquiry, Other",[656,711,721,728,736,744,750],{"_uid":657,"equals":658,"fields":659,"component":710},"e21d97dd-e68e-4fa6-ba97-bc40f3041dde","Order Enquiry",[660],{"_uid":661,"body":662,"type":708,"title":13,"component":709},"b64992bc-6d53-48b8-b7a0-d81e5a062e50",{"type":324,"content":663},[664],{"type":327,"content":665},[666,668,675,677,679,680,684,686,691,699,701,706],{"text":667,"type":332},"We are ",{"text":669,"type":332,"marks":670},"Foxy.io",[671],{"type":355,"attrs":672},{"href":673,"uuid":59,"anchor":59,"custom":674,"target":59,"linktype":31},"http:\u002F\u002FFoxy.io",{},{"text":676,"type":332},", an ecommerce platform powering ecommerce for other merchants. We do not sell products, and are unable to assist with questions about order statuses or refunds for any merchants using our platform. Please contact the merchant you ordered from for assistance. If you’d like to report a store using Foxy for fraudulent practices, please select ‘other’ in the subject.",{"type":678},"hard_break",{"type":678},{"text":681,"type":332,"marks":682},"NOTE:",[683],{"type":520},{"text":685,"type":332}," We are ",{"text":687,"type":332,"marks":688},"not ",[689],{"type":690},"italic",{"text":692,"type":332,"marks":693},"Foxy.in",[694,698],{"type":355,"attrs":695},{"href":696,"uuid":59,"anchor":59,"custom":697,"target":59,"linktype":31},"http:\u002F\u002FFoxy.in",{},{"type":690},{"text":700,"type":332},". We are not in any way affiliated with ",{"text":692,"type":332,"marks":702},[703],{"type":355,"attrs":704},{"href":696,"uuid":59,"anchor":59,"custom":705,"target":59,"linktype":31},{},{"text":707,"type":332},", and cannot help in any way with your order from that website.","danger","global___alert","form___condition",{"_uid":712,"equals":713,"fields":714,"component":710},"8765c3e1-25cf-44aa-b8ea-fc6094acf9c3","Presales",[715],{"_uid":716,"name":717,"type":718,"label":13,"options":13,"required":24,"component":644,"conditions":719,"placeholder":13,"default_value":720},"cf464f8e-d643-4f6e-af29-d3abffaf7380","department_email_address","hidden",[],"hello@foxy.io",{"_uid":722,"equals":208,"fields":723,"component":710},"4007b6d8-77e5-421d-bd1e-6f336dd853fb",[724],{"_uid":725,"name":717,"type":718,"label":13,"options":13,"required":24,"component":644,"conditions":726,"placeholder":13,"default_value":727},"7b4c6aa5-a68c-45e0-9ce1-0a36af10c0c2",[],"help@foxy.io",{"_uid":729,"equals":730,"fields":731,"component":710},"1dbb8f11-613d-43cd-9e09-1b94f6e19219","Billing",[732],{"_uid":733,"name":717,"type":718,"label":13,"options":13,"required":24,"component":644,"conditions":734,"placeholder":13,"default_value":735},"a0ac0d1b-bc4f-4a6c-a682-581d450b0b73",[],"help+billing@foxy.io",{"_uid":737,"equals":738,"fields":739,"component":710},"a0a53a50-7172-4a29-ba58-181e38874e12","Partnerships",[740],{"_uid":741,"name":717,"type":718,"label":13,"options":13,"required":24,"component":644,"conditions":742,"placeholder":13,"default_value":743},"7aa011d9-f374-4aed-b5a5-929b54aaf152",[],"partners@foxy.io",{"_uid":745,"equals":658,"fields":746,"component":710},"a4cd431f-25d5-41c7-bfdc-02c908c8fb47",[747],{"_uid":748,"name":717,"type":718,"label":13,"options":13,"required":24,"component":644,"conditions":749,"placeholder":13,"default_value":720},"f5d52168-d6ae-451b-94ee-2ced1cbd28ad",[],{"_uid":751,"equals":752,"fields":753,"component":710},"25aba1ed-eb41-4bbc-aa89-f7a7167ea86e","Other",[754],{"_uid":755,"name":717,"type":718,"label":13,"options":13,"required":24,"component":644,"conditions":756,"placeholder":13,"default_value":720},"f40dfaef-c203-4b71-bf4e-e1b43cef192b",[],{"_uid":758,"component":759},"e9c53a05-f40a-4510-aaf8-bc072a235a0c","form___subject",{"_uid":761,"name":762,"type":763,"label":764,"options":13,"required":33,"component":644,"placeholder":13},"a4c4d385-fff4-4978-99fb-b68cfea623d6","message","textarea","Message",{"_uid":766,"name":767,"type":652,"label":768,"options":769,"required":33,"component":644,"conditions":770,"placeholder":13},"8a3c9f85-f438-427d-9c7a-d7b295a14b5b","existing_user","Are you an existing user?","No, Yes",[771],{"_uid":772,"equals":773,"fields":774,"component":710},"115933d6-262a-4b59-8fa8-579c5ad73de1","Yes",[775],{"_uid":776,"name":777,"type":332,"label":778,"options":13,"required":33,"component":644,"conditions":779,"placeholder":13},"44b6ff23-98f0-4e95-b7f5-c23e06415c2d","subdomain","Store Subdomain",[],{"_uid":781,"name":782,"type":652,"label":783,"options":784,"required":33,"component":644,"conditions":785,"placeholder":13},"922a5cef-3af2-4113-8855-36c7910e3ee3","user_type","What type of user are you?","Developer, Designer, Merchant",[],"POST",[788],{"_uid":789,"text":790,"title":799,"component":800},"7323b90d-a93a-4bf1-baa9-20d0b7ead61b",{"type":324,"content":791},[792],{"type":327,"content":793},[794,796,797],{"text":795,"type":332},"855.369.9227",{"type":678},{"text":798,"type":332},"9:30am-6pm Central M-F","Pre-sales, Sales, & Partnerships","contact___footer_column",{"type":324,"content":802},[803],{"type":327,"content":804},[805],{"text":806,"type":332},"Get in touch to get help from our friendly support team.","Submit","Success!","Your email has been received. We'll get back to you as soon as we can, but it might take a business day. If you don't hear back from us in a timely manner, please check your spam folder to ensure our reply didn't go there.",-80,[],"2fd9fb7d-a48a-4184-acfd-30022d8d6f08","2022-09-23T20:10:45.360Z",[],[288,816],{"name":817,"created_at":818,"published_at":819,"updated_at":820,"id":821,"uuid":600,"content":822,"slug":837,"full_slug":838,"sort_by_date":59,"position":839,"tag_list":840,"is_startpage":24,"parent_id":310,"meta_data":59,"group_id":841,"first_published_at":842,"release_id":59,"lang":65,"path":59,"alternates":843,"default_full_slug":59,"translated_slugs":59},"Customer Portal","2023-01-19T16:18:57.721Z","2026-07-16T21:56:28.934Z","2026-07-16T21:56:28.952Z",28234,{"_uid":823,"icon":824,"name":817,"type":825,"guides":826,"pinned":24,"summary":827,"category":13,"component":297,"blog_posts":828,"content_hub":24,"icon_custom":829,"case_studies":830,"faq_sections":831,"help_articles":832,"featured_guides":833,"mailbox_category":13,"featured_articles":834,"featured_blog_posts":835,"featured_case_studies":836},"6a0c718d-ad6f-47c6-bf8e-3405228bbdfa","fa-sign-in-alt","simple",[],"Allow customers to login, view order history, manage subscriptions, and more.",[],{"id":59,"alt":59,"name":13,"focus":59,"title":59,"filename":13,"copyright":59,"fieldtype":81},[],[],[],[],[],[],[],"customer-portal","help\u002Fcategories\u002Fcustomer-portal",160,[],"abeef712-f641-45ad-938e-c0d7943f4047","2023-01-24T10:16:50.938Z",[],{},1784250051992]