> Portal Navigation: > > - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version. > - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages). > - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`). > - Top-level index of all portals: https://dev.wix.com/docs/llms.txt > - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt ## Resource: Add Self-hosted Service Plugin Extensions with the SDK ## Article: Add Self-hosted Service Plugin Extensions with the SDK ## Article Link: https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/self-hosting/supported-extensions/backend-extensions/add-self-hosted-service-plugin-extensions-with-the-sdk.md ## Article Content: # Add Self-hosted Service Plugin Extensions with the SDK Add a [service plugin](https://dev.wix.com/docs/build-apps/develop-your-app/extensions/backend-extensions/service-plugins/about-service-plugin-extensions.md) (formerly SPI) extension to your app in your [app's dashboard](https://manage.wix.com/account/custom-apps) to extend the functionality of a Wix site. With service plugins, your app can: + **Inject custom logic into existing Wix app flows:** For example, a typical eCommerce checkout process does not allow a site owner to add additional fees that are unrelated to specific line items. Your app can use the [Additional Fees service plugin](https://dev.wix.com/docs/sdk/backend-modules/ecom/service-plugins/additional-fees/introduction.md) to add extra fees, like gift wrap charges or a fee for fragile items, to the Wix checkout flow. + **Introduce entirely new flows to Wix sites:** For example, when a site owner sets up a Wix store, there are a limited number of payment and shipping rates service providers to choose from. Your app can use the [Shipping Rates service plugin](https://dev.wix.com/docs/sdk/backend-modules/ecom/service-plugins/shipping-rates/introduction.md) to offer additional 3rd-party shipping rates providers currently unavailable to Wix sites. If you prefer to host your app on Wix, you can [add a service plugin extension with the CLI](https://dev.wix.com/docs/wix-cli/guides/extensions/backend-extensions/service-plugins/add-service-plugin-extensions.md). Follow these steps to implement a self-hosted service plugin with the [Wix JavaScript SDK](https://dev.wix.com/docs/sdk.md): ## Step 1 | Add a service plugin extension to your app Add a service plugin extension to your app in your app's dashboard as follows: 1. Select an app from the [Custom Apps page](https://manage.wix.com/account/custom-apps) in your Wix Studio workspace. 1. Go to the Extensions page, and click **+ Create Extension**. ![Create extension](https://wixmp-833713b177cebf373f611808.wixmp.com/images/19c148e0783a374c3da242e7a33c0cce.png) 1. Filter by tag, or search to find the extension you want to add. 1. Select the relevant extension and click **+ Create**. 1. In the JSON editor, configure the parameters by referencing the **Documentation** section on the right side of the page. For each parameter, add the parameter name and value in the JSON editor. ![screenshot of json editor](https://wixmp-833713b177cebf373f611808.wixmp.com/images/5ac20a0893bef135b62812157515b7bd.png) 1. Click **Save**. ## Step 2 | Retrieve your app's ID and public key To implement a self-hosted service plugin, you'll need to retrieve these credentials from your app's dashboard: + **App ID:** Find this in your app's **OAuth** page in your app's dashboard. + **Public key:** Learn how to [retrieve your app's public key in your app's dashboard](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/self-hosting/webhooks/handle-events-with-webhooks-for-self-hosting-using-the-java-script-sdk.md). ## Step 3 | Import modules and create a client In your app code, import the Wix client and service plugin modules you need, then call [`createClient()`](https://dev.wix.com/docs/sdk/core-modules/sdk/wix-client.md) with the [`AppStrategy`](https://dev.wix.com/docs/sdk/core-modules/sdk/app-strategy.md) auth strategy to create a client for making authenticated calls to Wix APIs: ```js import { createClient } from '@wix/sdk'; import { } from '@wix//service-plugins'; const wixClient = createClient({ auth: AppStrategy({ appId: , // Your app's ID publicKey: , // Your app's public key }), modules: { } }); ``` Make sure you: + Import the correct module for your service plugin and pass it in `modules` when creating the client. + Provide the app ID and public key you retrieved in the previous step. ## Step 4 | Define handler functions Now it's time to add your custom business logic. Do this by calling `provideHandlers()` and passing it an object containing handler functions for each service plugin functionality you need: ```js wixClient..provideHandlers({ : async (payload) => { const { request, metadata } = payload; // Add your logic here }, : async (payload) => { const { request, metadata } = payload; // Add your logic here } }); ``` For example, to implement the [Shipping Rates](https://dev.wix.com/docs/sdk/backend-modules/ecom/service-plugins/shipping-rates/introduction.md) service plugin, define the [`getShippingRates()`](https://dev.wix.com/docs/sdk/backend-modules/ecom/service-plugins/shipping-rates/get-shipping-rates.md) handler function as follows: ```js wixClient.shippingRates.provideHandlers({ getShippingRates: async (payload) => { const { request, metadata } = payload; // Add your logic here } }); ``` When a site action triggers one of these functions, Wix passes the function a `payload` object containing the following properties: + `request`: Details related to the specific service and action. + `metadata`: Information about the context of the request, such as the App Instance ID, site currency, language, and identity of the user who triggered the request. To find the handler functions a service plugin supports, and the precise structure of the `request` and `metadata` objects for each handler function, see the [reference documentation](https://dev.wix.com/docs/sdk.md). ## Step 5 | Expose an endpoint Define a route to handle `POST` requests from Wix. Use the `/*` wildcard to enable the endpoint to catch all requests to all sub-paths. In your route handler, call `process()` and pass it the request. This function takes care of the following for you: + It decodes the JWT-encrypted requests. + Based on the sub-path of the request, it triggers a call to the correct handler function you defined with `provideHandlers()` and passes it the request payload. For example, if you are using [Express](https://expressjs.com/), you can implement the endpoint simply as follows, regardless of which handler functions you defined: ```js express.post('/plugins-and-webhooks/*', (req, res) => { wixClient.process(req); }); ``` ## Full code example Here's an example of implementing this code for a shipping rates service plugin: ```js // Import the Wix client and service plugin modules import { createClient } from '@wix/sdk'; import { shippingRates } from '@wix/ecom/service-plugins' const wixClient = createClient({ auth: { appId: , publicKey: }, modules: { shippingRates } }); // Define handler functions with your custom logic wixClient.shippingRates.provideHandlers({ getShippingRates: async (payload: GetShippingRatesEnvelope) => { const { request, metadata } = payload; // Add your logic here } }); // Implement a router to process all requests and trigger calls to your handler functions express.post('/plugins-and-webhooks/*', (req, res) => { wixClient.process(req); }); ``` ## See also + [About service plugin extensions](https://dev.wix.com/docs/build-apps/develop-your-app/extensions/backend-extensions/service-plugins/about-service-plugin-extensions.md) + [List of available service plugins](https://dev.wix.com/docs/velo/articles/api-overview/service-plugins-spis.md#available-service-plugins) + [Add a service plugin with the CLI](https://dev.wix.com/docs/wix-cli/guides/extensions/backend-extensions/service-plugins/add-service-plugin-extensions.md)