Both sides previous revisionPrevious revisionNext revision | Previous revision |
v:2.0:customer_portal [2023/11/23 20:42] – [Standalone SSO with the Portal] adam | v:2.0:customer_portal [2025/06/25 15:23] (current) – [Incorporating the Customer Portal SSO with an Existing SSO Endpoint] adam |
---|
====== Customer Portal ====== | ====== Customer Portal ====== |
| |
===== BETA Setup Instructions ===== | ===== Setup Instructions ===== |
<WRAP center round info 60%> | |
Note that the customer portal is currently in public beta. Please [[https://airtable.com/shruOtVjh0UYJmifs|complete this form to request access]] to have it enabled for your store before following the following steps. | |
</WRAP> | ==== Enabling the portal ==== |
| |
| The customer portal can be enabled from the Foxy admin at [[https://admin.foxy.io|admin.foxy.io]]. Navigate to the Settings > Customer Portal section where you can configure the portal for your store. |
| |
| You need to specify an allowlist of domains where the portal is able to be utilised. Note that all domains have to begin with ''%%https://%%'', and when adding a primary domain, we recommend adding both the domain with and without the ''www.'' subdomain (for example, ''%%https://mydomain.com%%'' and ''%%https://www.mydomain.com%%''). If you're adding a subdomain already (like ''%%https://customer.mydomain.com%%'') then that doesn't need a ''www.'' prefixed version. |
| |
| You can also configure additional options for the portal: |
| |
Also note that our portal functionality requires modern browsers. This excludes IE11 and non-Chromium Edge. | * SSO (single sign-on) - enable this option if you want to allow customers who are logged in to the portal to be automatically logged in to your website (requires some additional configuration, see that below) |
| * Customer registration - enable this option to allow customers to create a new account directly on the login form, as opposed to completing a purchase through the checkout |
| * Frequency changes for subscriptions - enabling this option allows customer to changes the frequency of their subscriptions. You can define rules for what options a customer can change a subscription too, depending what subscription it is. |
| * Next payment date changes for subscriptions - if enabled, customers will be able to modify the next date of their subscription. This can be limited based on rules to restrict how far or to what days a customer can change the next date to. |
| * Session lifespan - allows you to define how long a customer can remain logged in to the portal for before being automatically logged out |
| * JWT shared secret - this secret is used to sign the tokens returned as part of authenticating with the portal. Changing this secret will invalidate any active authenticated sessions on the customer portal. Unless you have specific needs here, you can let this value be set automatically. |
| |
==== Beta Instructions ==== | ==== Setup Instructions ==== |
| |
You can [[http://foxy.io/examples/customer-portal-demo|see an example of our customer portal element on our website here]]. | You can [[http://foxy.io/examples/customer-portal-demo|see an example of our customer portal element on our website here]]. |
The CDN url's for the customer portal is set to the stable release and will update according to the ''@1'' release tag. If you want to try the bleeding-edge beta releases, you can switch the URL's to use ''elements@beta'' instead of ''elements@1'', but we don't recommend that for production situations. | The CDN url's for the customer portal is set to the stable release and will update according to the ''@1'' release tag. If you want to try the bleeding-edge beta releases, you can switch the URL's to use ''elements@beta'' instead of ''elements@1'', but we don't recommend that for production situations. |
| |
It's also possible to use third-party CDN's, such as jsdeliver and unpkg, if desired: | <WRAP center round info 95%> |
| **If you are customising your instance of the customer portal such as adding custom elements or translations**, we would recommend locking to a specific version of the portal instead of using the ''@1'' release tag. |
| |
| To do that, you would specify the specific release instead of ''@1'', for example ''@1.28.0'' in the two URL's from the code above. You can confirm the latest releases by [[https://github.com/Foxy/foxy-elements/releases|viewing the releases on the Elements GitHub repository here]], and also subscribe to that repository to get updates as they're released |
| </WRAP> |
| |
| If you //really// want to, it's also possible to use third-party CDN's, such as jsdeliver, though we recommend our own unless you have a compelling reason: |
| |
== jsDeliver == | == jsDeliver == |
</code> | </code> |
| |
== unpkg == | |
<code> | |
https://unpkg.com/@foxy.io/elements@1/dist/cdn/foxy-customer-portal.js | |
https://unpkg.com/@foxy.io/elements@1/dist/cdn/translations | |
</code> | |
| |
=== Styling === | ==== Styling ==== |
If you want to customise the styles of your portal to better match your branding, you can do that by including a style block after the ''script'' tag shown above. You can customize your styles at [[https://demo.vaadin.com/lumo-editor/]]. | If you want to customise the styles of your portal to better match your branding, you can do that by including a style block after the ''script'' tag shown above. You can customize your styles at [[https://demo.vaadin.com/lumo-editor/]]. |
| |
If you want to include the styles in the ''head'' of your page, you can do that by changing the ''html'' style declaration to instead be targeting '':root''. | If you want to include the styles in the ''head'' of your page, you can do that by changing the ''html'' style declaration to instead be targeting '':root''. |
| |
=== Advanced customisation === | ==== Languages ==== |
| |
| Languages are handled separately for the customer portal than for the cart/checkout/receipt, and so aren't managed via the Foxy administration. Instead, you can specify a ''lang'' attribute on the ''foxy-customer-portal'' HTML element. We currently support the following language codes: ''en'', ''es'', ''de'', ''pl'', ''zh-HK'', ''se'', ''nl'', ''fr''. As an example, to set your customer portal to French, it would look like this (with your store domain of course): |
| |
| <code html> |
| <foxy-customer-portal base="https://YOUR_FOXY_STORE.foxycart.com/s/customer/" lang="fr"></foxy-customer-portal> |
| </code> |
| |
| === Customising language strings === |
| |
| If you need to adjust some individual language strings within your portal installation beyond our default strings, you can do that with some customisations to your portal page. There are two changes that need to be made, one to the HTML element, and then adding some additional javascript to define your customisations. |
| |
| To the ''foxy-customer-portal'' HTML element, you will need to define a namespace ''ns'' element, with a value of ''my-portal customer-portal''. (You can specify a different value than ''my-portal'' if you want, you'll just need to remember that in the next portion for the javascript.) That would make the HTML tag look like this: |
| |
| <code html> |
| <foxy-customer-portal base="https://YOUR_FOXY_STORE.foxycart.com/s/customer/" ns="my-portal customer-portal"></foxy-customer-portal> |
| </code> |
| |
| Then in your javascript, you define lines for each language string you want to customise, specifically after this line in the existing javascript from the installation instructions above: |
| |
| <code javascript> |
| I18nElement.onResourceFetch((ns, lang) => fetch(`${i18nBase}/${ns}/${lang}.json`)); |
| </code> |
| |
| The javascript line to customise a language string takes the following format: |
| |
| <code javascript> |
| I18nElement.i18next.addResource('en', 'my-portal', 'STRING_IDENTIFIER', 'My New String'); |
| </code> |
| |
| - The first argument (''en'') is the language code that contains the string you're updating |
| - The second argument (''my-portal'') matches the custom namespace defined in the ''ns'' attribute |
| - The third argument (''STRING_IDENTIFIER'') matches the string that you're wanting to update from the language file (details on that below) |
| - The fourth argument (''My New String'') defines your own version of the language string that you want to use instead |
| |
| To find the string identifier, you can [[https://github.com/Foxy/foxy-elements/tree/main/src/static/translations/customer-portal|reference the language strings for the customer portal element on the Github repository here]]. After opening the specific language you are replacing a string for, you will find all the strings in a JSON structure. By finding the language string there, you can then create the string identifier to match to it, which begins with ''customer-portal'', followed by the nested object keys and the language string key, separated by periods. |
| |
| For example, let's replace the "Get temporary password" language string to be "Forgot password?" instead. In the ''en'' [[https://github.com/Foxy/foxy-elements/blob/main/src/static/translations/customer-portal/en.json|language file]], that string is located in this portion of the document: |
| |
| <code json> |
| "sign-in-form": { |
| "email": "Email", |
| "invalid_credential_error": "Incorrect email or password. Please check your credentials and try again.", |
| "password": "Password", |
| "recover_access": "Get temporary password", |
| "sign_in": "Sign in", |
| "sign_in_hint": "Please enter your email and password", |
| "sign_up": "Create account", |
| "unknown_error": "An unknown error has occured. Please try again later.", |
| "v8n_invalid_email": "Invalid email", |
| "v8n_required": "Required", |
| "spinner": { |
| "loading_busy": "Loading", |
| "loading_error": "Failed to load" |
| } |
| } |
| </code> |
| |
| That would make the string identifier as ''customer-portal.sign-in-form.recover_access'', and the line of javascript added into the customer portal page would look like this: |
| |
| <code javascript> |
| I18nElement.i18next.addResource('en', 'my-portal', 'customer-portal.sign-in-form.recover_access', 'Forgot Password?'); |
| </code> |
| |
| Note that some language strings are nested in multiple objects, so ensure you include each nested key to reach the desired language string in the identifier you use. As an example, the "Loading" string above would be ''customer-portal.sign-in-form.spinner.loading_busy''. |
| |
| You can include as many language customisations as you need, but each different string is a distinct line of javascript. |
| |
| ==== Advanced customisation ==== |
| |
You can see additional demos and examples at [[https://elements.foxy.dev/?path=/story/other-customerportal--playground|elements.foxy.dev]] for configuration options and demo code. | You can see additional demos and examples at [[https://elements.foxy.dev/?path=/story/other-customerportal--playground|elements.foxy.dev]] for configuration options and demo code. |
If you've already got SSO enabled and configured on your Foxy store, you'll need to handle things separately. We can't give step-by-step instructions, as there are countless ways to handle SSO, but here are the general ideas: | If you've already got SSO enabled and configured on your Foxy store, you'll need to handle things separately. We can't give step-by-step instructions, as there are countless ways to handle SSO, but here are the general ideas: |
| |
* **Create the customer portal session + cookie when a customer logs in.** So when a customer enters their username and password, you can make a quick ''POST /s/customer/authenticate'' request with their entered username + password. Set the ''fx.customer'' cookie with the value you receive. Note that this approach requires the Foxy password to be synced with your own auth system. | * **Create the customer portal session + cookie when a customer logs in.** So when a customer enters their username and password, you can make a quick ''POST /s/customer/authenticate'' request as documented below with their entered username + password. Set a localstorage item named ''session'' with a stringified version of the JSON from the successful response. Note that this approach requires the Foxy password to be synced with your own auth system. |
* **If you don't have access to the customer's password...** You can use your store's configured [[.:unified_order_entry|UOE password]] password. (This should //only ever// be serverside, as you should never share that password in the browser.) | * **If you don't have access to the customer's password...** You can use your store's configured [[.:unified_order_entry|UOE password]] password. (This should //only ever// be serverside, as you should never share that password in the browser.) |
* Unlike the checkout, you likely would not want to allow login to the portal if the customer's not already logged into your system. Instead, redirect the customer to your login page so they'll be fully logged in (instead of logged into the Foxy customer portal, but not to your system or the checkout). | * Unlike the checkout, you likely would not want to allow login to the portal if the customer's not already logged into your system. Instead, redirect the customer to your login page so they'll be fully logged in (instead of logged into the Foxy customer portal, but not to your system or the checkout). |