# Delivery Gateway — Integration Guides > Getting started, checkout widget integration, order and shipment how-tos. Includes code samples. This file contains all documentation content in a single document following the llmstxt.org standard. ## Authentication and authorization The Merchant API is available at `https://api.sandbox.deliverygateway.io/graphql/merchant` in the sandbox environment and `https://api.deliverygateway.io/graphql/merchant` in the production environment. To make any request to this single endpoint, you must create an access token using the Bearer Authentication schema. You can manage your access tokens via either the web interface or the API. An access token provides authentication and role-based authorization: each role has its own set of permissions. When creating a token, you must select one or more roles and the corresponding permissions. ## Create Bearer token on the web interface 1. [Log in to the Delivery Gateway admin interface](/admin/get-started/login). 1. Find **Access Tokens** on the left. 1. In the top right corner, click **New Access Tokens**. 1. Set a name and optionally, an expiration date. If you leave the expiration date empty, your token will never expire. For security reasons, we recommend regularly regenerating your tokens. 1. In the **Roles** dropdown menu, select all the roles you need. 1. Optionally, create an allowlist for the token: click **Add** to set IP addresses and HTTP referers that are allowed to send requests. You can add as many as you need: click **Add** again for more input fields. 1. When done, click **Create**. 1. Copy your token from the dialog. Note that if you close the dialog without copying the token, you won't be able to retrieve it again. ## Create Bearer token with the API Create a token with the `createToken` mutation. It requires a token name and the roles assigned to the token. You can set multiple roles in a comma-separated list. ```graphql mutation { createToken( input: { name: "my_new_token", roles: [MERCHANT_CONFIGURATION, MERCHANT_OPERATOR] } ) } ``` You can create an allowlist using the `allowlist` field. Set IP addresses and HTTP referers that are allowed to send requests: ```graphql mutation { createToken( input: { name: "my_new_token", roles: [MERCHANT_CONFIGURATION, MERCHANT_OPERATOR, MERCHANT_WEBHOOK], allowlist: { ips: "192.0.2.1", referers: "https://acmecorp.com" } } ) } ``` --- ## Connect the docs to your AI assistant (MCP) # Connect the docs to your AI assistant These docs are available over the **Model Context Protocol (MCP)**, so your coding assistant can search them directly and answer with links back to the exact section — instead of guessing from stale training data. **Server URL** ```text https://T3F23WL577.algolia.net/mcp/1/pBfsB0jvSvOHvUzkKTVcLA/mcp ``` No API key, no sign-up, no authentication. The connection is **read-only**: it searches our public documentation and nothing else. ## Add it to your client ```bash claude mcp add --transport http dgw-docs \ https://T3F23WL577.algolia.net/mcp/1/pBfsB0jvSvOHvUzkKTVcLA/mcp ``` Verify with `claude mcp list`. 1. Open **Settings → Security and login** and turn on **Developer mode**. 2. Open [ChatGPT Plugins](https://chatgpt.com/plugins) and click the **plus** button. 3. Set the name to **Delivery Gateway Docs** and add a short description. 4. Under **Connection**, enter the MCP server URL: `https://T3F23WL577.algolia.net/mcp/1/pBfsB0jvSvOHvUzkKTVcLA/mcp` 5. Create the connection, then review the discovered tools and metadata. 6. Start a new conversation and add **Delivery Gateway Docs** from the tools menu. :::note Availability Developer mode availability depends on your account and workspace policy. See the [official OpenAI setup guide](https://developers.openai.com/plugins/deploy/connect-chatgpt). ::: 1. Open [Settings → Connectors](https://claude.ai/settings/connectors) and click **Add custom connector**. 2. **Name:** Delivery Gateway Docs 3. **Remote MCP server URL:** `https://T3F23WL577.algolia.net/mcp/1/pBfsB0jvSvOHvUzkKTVcLA/mcp` 4. Leave **Advanced settings** empty, click **Add**, then **Connect**. 5. Enable the connector from the prompt bar. Tools appear in new conversations. :::note If you see a sign-in error The server needs no authentication, but the connector flow may still report that it *couldn't register with the sign-in service*. Press **Connect** again on the existing entry in your connectors list; if it persists, remove the connector and add it back. Adding the same URL twice returns *a server with this URL already exists* — that means the first attempt did create it, so connect to that one rather than adding a new one. ::: Add to `~/.cursor/mcp.json` (or `%USERPROFILE%\.cursor\mcp.json`): ```json { "mcpServers": { "dgw-docs": { "url": "https://T3F23WL577.algolia.net/mcp/1/pBfsB0jvSvOHvUzkKTVcLA/mcp" } } } ``` Or: **Cursor Settings → Tools and MCPs → Add MCP Server**, paste the URL, set Authentication to *none*, then enable it from the prompt bar. Add to `.vscode/mcp.json` in your workspace: ```json { "servers": { "dgw-docs": { "type": "http", "url": "https://T3F23WL577.algolia.net/mcp/1/pBfsB0jvSvOHvUzkKTVcLA/mcp" } } } ``` ## What your assistant gets | Tool | What it does | | --- | --- | | `algolia_search_index_docs` | Searches every published documentation page. Accepts up to five query variations in one call, each with its own facet filters. | | `algolia_search_for_facet_values` | Lists available values for a facet (`type`, `lang`, `version`). Rarely needed directly. | Every hit carries a `url` **and** an `anchor`, so the assistant can link to the exact section rather than the page. :::tip Get the code samples too Code blocks are not part of the search index — a hit tells your assistant *where* the answer lives, not what the snippet says. Deeper section records (heading-only results) may come back with `content: null` for the same reason. Every page is also published as raw Markdown: append `.md` to any docs URL, or point your assistant at [`/llms-full.txt`](/llms-full.txt). Most agents will fetch these on their own once they have the URL. ::: ## Prompts to start with ```text Using the Delivery Gateway docs, walk me through the minimal checkout integration — what goes on the backend versus the frontend? ``` ```text Search the Delivery Gateway docs for how to create a webhook and verify its signature, then show me the createWebhook mutation inputs. ``` ## Plain-text alternative If your tooling has no MCP support, the same content is available as static files: | File | Contents | | --- | --- | | [`/llms.txt`](/llms.txt) | Index of every documentation page | | [`/llms-full.txt`](/llms-full.txt) | Complete documentation in one file | | [`/llms-integration.txt`](/llms-integration.txt) | Getting started and integration guides only | | [`/llms-merchant-api.txt`](/llms-merchant-api.txt) | Merchant API reference only | Any page also returns Markdown if you append `.md` to its URL. ## Limits - **Read-only, documentation only.** The connector cannot reach your account, orders or shipments. For that, use the [Merchant API](/api/merchant/introduction). - **Public content only.** Nothing behind authentication is exposed. - **Search queries reach Algolia.** Tool calls send your query, plus the original prompt that triggered them, to Algolia for search analytics. - **Not a support channel.** For account-specific questions, contact the [Help Center](https://help.deliverygateway.io/). - Answers are generated by your assistant. Verify against the linked page before shipping to production. --- ## Quickstart Delivery Gateway is an all-in-one logistics platform designed to simplify and automate your e-commerce shipping processes. We provide a single, centralized solution that connects your webshop with multiple courier service providers, enabling seamless delivery management from a single interface. Our platform helps you save time, reduce costs, and improve customer satisfaction by offering flexible delivery options and transparent tracking. ## Integrate Delivery Gateway to your platform Delivery Gateway offers two types of integrations: - A lightweight frontend integration: you connect DGW to your website and our Web Plugin will do the rest. - Full backend integration: take advantage of our GraphQL API to manage the entire ordering and shipping process with all the features Delivery Gateway offers. In this quickstart guide, we'll show you a quick frontend integration by setting up a delivery method selector. When your customer wants to place an order, they will be able to select from home delivery or pickup point delivery: when they select one, its available options - providers, locations, and so on - will open in a separate modal. :::tip For all available options, read the [full guide about frontend integration](/dev/how-tos/frontend-integration/set-up-dgw-on-frontend). ::: ### Before you start Before you start the integration process, we recommend familiarizing yourself with the most important parts of Delivery Gateway. Read about: - [The Admin Dashboard](/admin/get-started/dashboard). - [They key concepts of Delivery Gateway](/admin/get-started/key-dgw-concepts). ### Part 1: Get your merchant ID You need the merchant ID to integrate Delivery Gateway to your website. 1. [Log in to the Dashboard](/admin/get-started/login). 1. Select your merchant on the top left corner. 1. Go to **Merchant**. 1. Copy the ID from under the merchant name. ### Part 2: Enable delivery options 1. In the **Merchant** configuration, find **Display**. 1. Enable the delivery types you want to offer. ### Part 3: Connect Delivery Gateway to your website Add the following script to your website where you want to use the Delivery Gateway integration: ```html ``` The script calls the `window.DGWOnLoad` callback (if present) with the global DGW object as its parameter. The global DGW object will also be accessible as `window.DGW`. ### Part 4: Configure the DGW widget Mount an instance of the `DGW` object in a function and call that function: ```js function deliveryMethodSelector(DGW) { DGW.mount({ containerId: "delivery-gateway", merchantId: "5441a8c6-5dfb-4744-b6ae-f0d221d4718c", view: { type: "delivery-method-selection", openSelectedMethodInModal: true, operatorsAsSeparateMethods: true, }, }); } if (window.DGW) { deliveryMethodSelector(window.DGW); } else { window.DGWOnLoad = deliveryMethodSelector; } ``` Replace the following values with your own: - `containerId`: The HTML ID of the container that will contain the Delivery Gateway widget. - `merchantId`: Paste your merchant ID here. Your website should now be able to allow customers to select from different delivery methods. ### Part 5: Next steps To start using Delivery Gateway, you need to configure a few more things: - [Enable at least one provider](/admin/how-tos/provider-config/enable-provider). - [Create a pricing rule](/admin/how-tos/create-pricing). - [Configure sender information](/admin/how-tos/merchant-config/configure-sender-information). - [Create your own store for store pickup](/admin/how-tos/create-stores). ## Get started with the API Delivery Gateway uses a GraphQL API called the Merchant API. The API is fully featured for a robust backend integration. To get started: 1. Learn about GraphQL. 1. Create a Bearer access token. 1. Set up a GraphQL client. 1. Test the Merchant API in a sandbox environment. ### API environments Delivery Gateway offers two environments for you: the sandbox and the production environments. - The sandbox environment allows you to test our API without any real-world consequences. You can access it at the `https://api.sandbox.deliverygateway.io/graphql/merchant`. - The production environment is our public Merchant API endpoint that you can use to configure your Delivery Gateway integrations: `https://api.deliverygateway.io/graphql/merchant`. --- ## About GraphQL Delivery Gateway uses GraphQL for building its API. This guide walks you through the basics of GraphQL. ## About GraphQL GraphQL is a query language and runtime system. Clients send requests to GraphQL services by using the GraphQL query language, and the service returns the data in a response. A GraphQL API has a single endpoint for all data. The GraphQL type system describes the data that can be requested from the API. The collection of those data descriptions is called the GraphQL service's *schema*. To read or write data, the client must form GraphQL requests using the types defined in the service's schema: - Queries: Requests to retrieve data. Essentially, the client is asking for specific fields on pre-defined objects. They're similar to a `GET` request in a REST API. - Mutations: Requests to create and update data. They're similar to a `POST` or `PATCH` method in a REST API. ## Queries A GraphQL query requests data from specific fields of one or more objects defined in the schema of the GraphQL service. The GraphQL request format is similar to JSON but it doesn't use quotation marks for field names. GraphQL services return responses in JSON format. A simple query and response could look something like this: ```graphql title="GraphQL query" query { providers { id name } } ``` ```json title="JSON response" { "data": { "providers": { "id": "RIV", "name": "Red Ivorp" } } } ``` All GraphQL operations start with a root operation type: in this case, it's `query`. From there you specify the selection set of fields you're interested in: in the example, we're requesting the data from the `sender_name` field of the `merchant` object. The request's result will be returned in a top-level `data` key. If the request raised errors, the relevant information will be included in a top-level `errors` key. ## Mutations In a REST API, you send a `POST` request to a specific endpoint to create or update data. In GraphQL, you use mutations. Mutations are sent to a single endpoint and use the `POST` HTTP method. A GraphQL mutation requires: - A mutation field name: for example, `updateMerchantConfiguration`. They are defined in the GraphQL schema. - Input data passed as an argument to the mutation field. This is the data that you create or modify. - A list of fields that should be included in the JSON response. GraphQL nly returns the data you specifically ask for. In the example, we create a new delivery zone for a merchant with the `createZone` mutation and request that the GraphQL API returns the new `id`, `name`, and `country` fields. ```graphql title="GraphQL mutation" mutation { createZone( input: { name: "Hungary", countries: HU } ) { id name countries } } ``` ```json title="JSON response" { "data": { "createZone": { "id": "45678", "name": "Hungary", "countries": [ "HU" ] } } } ``` ## Arguments A GraphQL service can pass arguments to fields: this means that the client must provide a value for the required argument when sending a query or a mutation. For example, you can specify the ID of a provider to query pickup point availability: ```graphql title="GraphQL query" query { shipment(id: 215099) { provider mode } } ``` ```json title="JSON response" { "data": { "shipment": { "provider": "Red Ivorp", "mode": "SENDER_TO_RECIPIENT" } } } ``` ## Variables Variables allow you to reuse the same GraphQL requests with dynamic values. Variables are declared after the `query` or `mutation` keyword, like passing an argument to a function. They always begin with the `$` symbol. A variable declaration works this way: - Declare a `$variableName`. - Specify the type of the variable, for example, `createShipmentInput!`. - Replace the static value in the query or mutation with `$variableName`. ```graphql mutation($input: createShipmentInput!) { createShipment(input: $input) {...} } ``` Define the actual values for the variable in a separate variables dictionary that's usually in a JSON format. ```json { "input": { "provider":"Pro Vider", "referenceId":"12345", "recipient":{ "firstName":"Fictitious", "lastName":"Customer", "language":"EN" }, "destination":{ "pickupPointId":"12345" } } } ``` ## Nested objects In both queries and mutations, you will often need to use nested objects. In GraphQL, nested objects let you query multiple related data points in a single request, instead of using multiple endpoints like in a REST API. For example, you can query the ID and name of all providers in a single request by using nesting: ```graphql title="GraphQL query" query { providers { id name } } ``` Nesting applies to both responses and inputs. Many mutations have nested inputs. For example, the `OrderBillingInput` type requires multiple fields, including name, email, and phone number: ```graphql title="GraphQL mutation" mutation { upsertOrder( input: { billing: { name: "Most Excellent Customer", email: "examplemail@example.org", phone: "00 01 123 4567", vatNumber: "8337961152" isCompany: true } } ) } ``` You can nest within nested objects, too: ```graphql title="GraphQL mutation" mutation { upsertOrder( input: { billing: { name: "Most Excellent Customer", email: "examplemail@example.org", phone: "00 01 123 4567", vatNumber: "8337961152" isCompany: true, address: { country: CA, state: "Ontario" city: "Ottawa", postalCode: "K2C 0A6", addressLine1: "1026 Baseline Rd", addressLine2: "Building B, 4th floor" note: "The receptionist is grumpy" } } } ) } ``` In this example, we added an `address` field that requires the `AddressInput` type. For a valid mutation containing the `address` field, you need to specify multiple fields in a nested object, including country, state, and city. ## Multiple queries in the same request You can submit multiple queries or mutations in a single GraphQL request. These operations can be different or you can also query the field or run the same mutation multiple times with different arguments. To submit multiple queries or mutations: - Declare whether the operation is a query or a mutation. - Give each operation a custom alias and place it before the name of the query or mutation: `custom-alias: updateMerchantConfiguration`. In this example, we create three different pricing rules: ```graphql title="GraphQL mutation" mutation { BasicPricing: createPricing( input: { name: "Basic rule" price: { amount: 5, currency: EUR } } ){ name } HomeDeliveryPricing: createPricing( input: { name: "Home Delivery Pricing" price: { amount: 5, currency: EUR, condition: { isHomeDelivery: true, } } } ){ name } PickupPricing: createPricing( input: { name: "Home Delivery Pricing" price: { amount: 5, currency: EUR, condition: { isPickupPoint: true, } } } ){ name } } ``` --- ## Merchant API Delivery Gateway offers a robust GraphQL API that allows developers to access all core features—like shipment creation, label generation, and status tracking. To get started, check out our API documentation, which covers endpoints, authentication, and integration details. This makes it easy to connect your custom webshop or platform and automate your logistics workflow. ## Authentication All requests to the Merchant API must be authenticated with a valid access token. Include your token as a Bearer token on all API requests. Learn more about [authentication and authorization](/dev/getting-started/authentication). ## API reference Please refer to the [Merchant API reference](/api/merchant/introduction) for detailed information on available queries, mutations, and data types. --- ## SDKs Delivery Gateway provides SDKs to help you integrate our services into your applications quickly and efficiently. ## PHP SDK Our [PHP SDK](https://github.com/deliverygateway/php-sdk) makes it easier for your developers to work with the Merchant API. ### Install the SDK 1. [Install Composer](https://getcomposer.org/download/). 1. Run the following command in a bash shell: ```bash composer require deliverygateway/php-sdk ``` --- ## Set up GraphQL clients As Delivery Gateway uses a GraphQL API with a single endpoint, we recommend setting up a GraphQL client IDE to access it. There are multiple open source IDEs you can use. Check out the full list in the GraphQL organization tool directory: [Tools and libraries](https://graphql.org/community/tools-and-libraries/?tags=client). :::tip Learn more about GraphQL in our introductory guide: [GraphQL](/dev/getting-started/graphql) ::: To set up a GraphQL IDE: 1. Select a client. Popular examples include Altair, Apollo, Insomnia, or Relay. 1. Set the Delivery Gateway Merchant API endpoint in the client: `https://api.deliverygateway.io/graphql/merchant`. 1. Add an authorization header: `Authorization: Bearer `. Replace `` with your personal access token: [Create Bearer access token](/dev/getting-started/authentication). Different clients have different ways of adding the header: for example, some clients offer the option of selecting Bearer from a list of authentication options and you only need to manually input the actual token. 1. Set the client's request method to `POST`. All GraphQL requests, including queries, are POST requests. :::note Some clients offer a GraphQL mode. If it's available, use it. ::: 1. If needed, fetch the schema to render documentation with an introspection query: ``` query IntrospectionQuery { __schema { types { name } } } ``` :::note Most clients automatically fetch the schema and render the documentation in a Docs panel. ::: When done, test the client: run some queries and mutations to make sure everything works as it should. To test things, we recommend using our sandbox environment. --- ## Create webhooks Webhooks allow you to send notifications of Delivery Gateway events to a third-party service. For example, you can set up a webhook to send an event notification when a shipment is created or when a customer updates their address. Our webhooks send a JSON payload, the content of which depends on the triggering event. One webhook is one event: create a webhook for each of the events you need to send notifications about. ## Create a webhook Use the `createWebhook` mutation to create a new webhook. It creates a `Webhook` object. ```graphql mutation { createWebhook(input: {...}) { id url } } ``` To create a webhook, you need three inputs: - `webhook`: The event that triggers the webhook. For the full list, see [WebhookEnum](/api/merchant/types/enums/webhook-enum). - `url`: The service URL that will receive the JSON payload when an event triggers the webhook. - `transport`: The transport type. Currently, only REST is available. ```graphql mutation { createWebhook( input: { webhook: SHIPMENT_CREATED, url: "example.org", transport: REST, } ) { id url } } ``` ## Set a secret key for webhook signature We recommend setting a secret key for webhook signature. It is a shared secret used to prove that a webhook request really came from Delivery Gateway and was not tampered with in transit. The secret key must be configured for the merchant, using the `updateMerchantConfiguration` mutation: ```graphql title="GraphQL mutation" mutation { updateMerchantConfiguration( input: { key: WEBHOOK_SIGNATURE value: Q2hhbmdlVGhpcy1Ub1JhbmRvbVNlY3JldCE= } ) { key value } } --- ## Manage waybills A waybill is a shipping document that contains essential information about the transported shipment. It tells the carrier what is being shipped, who it's from, where it's going, and how it should be handled. ## Create a waybill A waybill on Delivery Gateway requires the following information: - A provider: the company transporting the shipment. - A reference ID: an automatically generated ID assigned by your system. - One or more shipment IDs. You don't have to assign the ID when creating a waybill: you can do so later with the `assignShipmentToWaybill` mutation. First, create at least one shipment. Each shipment will have an autogenerated `id`: you will need to pass this ID to the waybill. Create the waybill with the `createWaybill` mutation. Add the reference ID as a string: ```graphql mutation { createWaybill( input: { referenceId: "123abc", } ) { id } } ``` Set a provider from the list of [available providers](/api/merchant/types/scalars/provider-enum): ```graphql mutation { createWaybill( input: { provider: GLS, referenceId: "123abc", } ) { id } } ``` Optionally, you can assign a shipment ID during creation: ```graphql mutation { createWaybill( input: { provider: BestEx, referenceId: "123abc", shipments: ["24e8ff69-2889-4fbb-9868-b576ac21b95c"] } ) { id } } ``` ## Assign a waybill to a shipment If you didn't add a shipment ID when you created a waybill, you can assign it later with the `assignShipmentToWaybill` mutation. It requires two input fields: the waybill ID and the shipment ID. ```graphql mutation { assignShipmentToWaybill( input: { waybillId: "123abc", shipmentId: "456def", } ) { id } } ``` If you successfully assigned a waybill, you can always query it for the shipment: ```graphql query { shipment(id: "456def") { waybill { id } } } ``` ## Close a waybill After a shipment is successfully delivered (or returned to the sender), you should close the waybill. You need the ID of the waybill as the argument of the `closeWaybill` mutation. In the example, we're closing the waybill and querying which provider it was assigned to and its creation time and closing time. ```graphql title="GraphQL mutation" mutation { closeWaybill(id: "asdf1357") { provider { id } createdAt closedAt } } ``` ## Delete a waybill You can delete a waybill at any time with the `deleteWaybill` mutation. It requires the waybill ID as an argument. ```graphql title="GraphQL mutation" mutation { deleteWaybill(id: "asdf1357") { provider { id } } } ``` --- ## Create custom pickup point You can create your own custom pickup points: these are pickup locations that you, the merchant, operate and control. For example, your own physical stores. ## Create the pickup point To create a custom pickup point, use the `createPickupPoint` mutation. It requires: - `referenceId`: A unique ID that identifies the pickup point. You can use an ID generated by your own system. - `name`: A human-readable name that is shown to customers. - `phone`: A phone number. - `address`: The address of the pickup point. - `location`: The exact coordinates of the pickup point. ### Part 1: Basic information First, we set the id, the name, and the phone number as these are simple strings. ```graphql title="GraphQL mutation" mutation { createPickupPoint( input: { referenceId: "123abc", name: "My Store", phone: "01 234 5678", } ) } ``` ### Part 2: The address To add the address, you need the `addressInput` type. It requires: - `country`: See the [available country codes](/api/merchant/types/enums/country-enum). - `city` - `postalCode` - `addressLine1` So the bare minimum address input looks like this: ```graphql title="GraphQL mutation" mutation { createPickupPoint( input: { referenceId: "123abc", name: "My Store", phone: "01 234 5678", address: { country: HU, city: "Budapest", postalCode: "1061", addressLine1: "Nyugati tér 1." } } ) } ``` - You can add a `state` field: it can be used for any type of administrative subdivision of a country, if you need it. - If the address is longer and more complex, you can add `addressLine2`. - Add a `note` to include additional information about the address. ```graphql title="GraphQL mutation" mutation { createPickupPoint( input: { referenceId: "123abc", name: "My Store", phone: "01 234 5678", address: { country: CA, state: "Ontario" city: "Ottawa", postalCode: "K2C 0A6", addressLine1: "1026 Baseline Rd", addressLine2: "Building B, 4th floor" note: "The receptionist is grumpy" } } ) } ``` ### Part 3: Exact coordinates You must specify the exact location of the custom pickup point with a latitude and longitude value: ```graphql title="GraphQL mutation" mutation { createPickupPoint( input: { referenceId: "123abc", name: "My Store", phone: "01 234 5678", address: { country: HU, city: "Budapest", postalCode: "1061", addressLine1: "Nyugati tér 1." } location: { latitude: 47.50969187518572, longitude: 19.05571832644608 } } ) } ``` ### Part 4: Activate the pickup point To enable the pickup point for customers, you must set the `isActive` boolean to `true`. ```graphql title="GraphQL mutation" mutation { createPickupPoint( input: { referenceId: "123abc", name: "My Store", phone: "01 234 5678", address: { country: HU, city: "Budapest", postalCode: "1061", addressLine1: "Nyugati tér 1." } location: { latitude: 47.50969187518572, longitude: 19.05571832644608 } isActive: true } ) } ``` ### Set opening hours The opening hours of a pickup point is important information for your customers. To set it, you need the `openingHours` field which requires the `PickupPointOpeningHoursInput` type: - It requires a `timezone` in the format [specified in the `TimezoneEnum`](/api/merchant/types/enums/timezone-enum). - An `openingHours` field which requires the `OpeningHourInput` type. Each day is a separate object in an array, with `day`, `start`, and `end` fields. - `day` fields require [the `DayEnum`](/api/merchant/types/enums/day-enum). - `start` and `end` fields both require `hour` and `minute` fields which take integers. ```graphql title="GraphQL mutation" mutation { createPickupPoint( input: { referenceId: "123abc", name: "My Store", phone: "01 234 5678", address: { country: HU, city: "Budapest", postalCode: "1061", addressLine1: "Nyugati tér 1." } location: { latitude: 47.50969187518572, longitude: 19.05571832644608 } isActive: true, openingHours: { timezone: EUROPE_BUDAPEST, openingHours: [ { day: MONDAY, start: { hour: 8, minute: 0 }, end: { hour: 17, minute: 0 } }, { day: TUESDAY, start: { hour: 9, minute: 0 }, end: { hour: 18, minute: 0 } } ] } } ) } ``` ### Additional information You can indicate whether your store is wheelchair accessible with the `hasWheelChairAccess` field. ```graphql title="GraphQL mutation" mutation { createPickupPoint( input: { referenceId: "123abc", name: "My Store", phone: "01 234 5678", address: { country: HU, city: "Budapest", postalCode: "1061", addressLine1: "Nyugati tér 1." } location: { latitude: 47.50969187518572, longitude: 19.05571832644608 } isActive: true, hasWheelChairAccess: true } ) } ``` You can also configure a "cash on delivery" option, allowing customers to pay for their order in the store. The `cashOnDelivery` field accepts two payment methods, `CASH` and `CARD`. To enable both, include them in an array: ```graphql title="GraphQL mutation" mutation { createPickupPoint( input: { referenceId: "123abc", name: "My Store", phone: "01 234 5678", address: { country: HU, city: "Budapest", postalCode: "1061", addressLine1: "Nyugati tér 1." } location: { latitude: 47.50969187518572, longitude: 19.05571832644608 } isActive: true, cashOnDelivery: [ CASH, CARD ] } ) } ``` --- ## Create packaging You can configure packaging information to use for deliveries: set the dimensions of different package types and use them in your shipments to set the physical size of the shipment. When creating a package, you need to set a human-readable name and an identifying handle: ```graphql mutation { createPackaging( input: { name: "Normal", handle: "normal", } ) } ``` To set the size of the package, use the `dimensions` field. Provide all dimension values in meters. Fractions are allowed: ```graphql mutation { createPackaging( input: { name: "Normal", handle: "normal", dimensions: { width: 1.5, length: 5.3, height: 2.2, }, } ) } ``` You must specify whether the created package should be the default option with the `isDefault` field: ```graphql mutation { createPackaging( input: { name: "Normal", handle: "normal", dimensions: { width: 1.5, length: 5.3, height: 2.2, }, isDefault: true } ) { name } } ``` --- ## Create pricing rules Pricing rules are a set of configurations that determine the price of a delivery. You can set conditions and priority to a pricing rule so Delivery Gateway can automatically set the one you need during the order process. Read more about how pricing rules work: [About pricing](/admin/how-tos/create-pricing#about-pricing-rules). You can create and update pricing rules at any point with the API. Delivery Gateway will automatically use your pricing rules unless you directly specify prices during a session. ## Create a pricing rule Use the `createPricing` mutation to create a pricing rule. A "basic" pricing rule has only two requirements: a name and a price. Such a rule will match every possible condition and therefore will be available for all deliveries. As always, the `price` field requires the `amount` and `currency` subfields. ```graphql mutation { createPricing( input: { name: "Basic rule" price: { amount: 5, currency: EUR } } ){ name } } ``` Add the `condition` field to specify possible conditions. The conditions are: - The delivery method. - The pricing zone: the country or countries the price applies to. - The delivery provider: different companies charge different prices. For example, let's set a pricing rule for pickup point delivery in the United States by a provider called BestEx, applicable only to parcel lockers. We must disable this pricing rule for home delivery, specify the available pickup point types, and add the zone. :::note By default, there are no zones in the Delivery Gateway system: you need to create them and use the zone ID here. ::: ```graphql mutation { createPricing( input: { name: "Basic rule" price: { amount: 5, currency: EUR }, condition: { isHomeDelivery: false, isPickupPoint: true, pickupPointTypes: LOCKER, providers: BESTEX, zoneId: "123" } } ){ name } } ``` ## Update a pricing rule You can modify a pricing rule at any time with the `updatePricing` mutation. It requires the `id` and the `name` of an existing pricing rule: ```graphql title="GraphQL mutation" mutation { updatePricing( input: { id: "123abc", name: "My rule", price: { amount: 1200, currency: HUF } } ) { id } } ``` ## Delete a pricing rule To delete a pricing rule, you just need to pass the ID of the rule as an argument to the `deletePricing` mutation: ```graphql title="GraphQL mutation" mutation { deletePricing(id: "123abc") } ``` --- ## Create a shipment Create shipments to and then update it when necessary during its lifecycle. ## Create a shipment When an order is ready to be shipped, create a shipment with the `createShipment` mutation. It creates a `Shipment` object that contains all the relevant information about the shipment. ```graphql title="GraphQL mutation" mutation { createShipment(input: {...}) { id } } ``` The `createShipmentInput` type requires the following fields as a minimum: - `provider`: Specifies a provider with a `ProviderEnum!`. - `referenceId`: The ID of the shipment. - `recipient`: The name and the selected language of the customer who will receive the shipment. - `destination`: The address to where the shipment will be delivered. Depending on the order, this can be home delivery, a pickup point, or a store pickup. In the example, we're creating a shipment that will be delivered using the provider RIV to a pickup point for Fictitious Customer: ```graphql title="GraphQL mutation" mutation { createShipment( input: { provider: "RIV", referenceId: "12345", recipient: { firstName: "Fictitious", lastName: "Customer", language: HU }, destination: { pickupPointId: "12345" } } ) { id } } ``` ### Specify shipment address and location The shipment's `destination` can be a pickup point, an address, and/or a precise location. The simplest way is to specify the pickup point ID: ```graphql title="GraphQL mutation" mutation { createShipment( input: { provider: "RIV", referenceId: "12345", recipient: { firstName: "Fictitious", lastName: "Customer", language: HU }, destination: { pickupPointId: "12345" } } ) { id } } ``` To set the full address, you need the `address` field which requires: - `country`: See the [available country codes](/api/merchant/types/enums/country-enum). - `city` - `postalCode` - `addressLine1` ```graphql title="GraphQL mutation" mutation { createShipment( input: { provider: "RIV", referenceId: "12345", recipient: { firstName: "Fictitious", lastName: "Customer", language: HU }, destination: { address: { country: HU, city: "Budapest", postalCode: "1061", addressLine1: "Nyugati tér 1." } } } ) { id } } ``` - You can add a `state` field: it can be used for any type of administrative subdivision of a country, if you need it. - If the address is longer and more complex, you can add `addressLine2`. - Add a `note` to include additional information about the address. ```graphql title="GraphQL mutation" mutation { createShipment( input: { provider: "RIV", referenceId: "12345", recipient: { firstName: "Fictitious", lastName: "Customer", language: HU }, destination: { address: { country: CA, state: "Ontario" city: "Ottawa", postalCode: "K2C 0A6", addressLine1: "1026 Baseline Rd", addressLine2: "Building B, 4th floor" note: "The receptionist is grumpy" } } } ) { id } } ``` You can specify a precise location with the `location` field that requires a `latitude` and a `longitude` fields: ```graphql title="GraphQL mutation" mutation { createShipment( input: { provider: "RIV", referenceId: "12345", recipient: { firstName: "Fictitious", lastName: "Customer", language: HU }, destination: { location: { latitude: 12.000245, longitude: 23.101214 } } } ) { id } } ``` ### Shipment recipient The shipment recipient is the customer who will receive the shipment. The `createShipment` mutation requires its name and language as a minimum but you can add additional contact information: email and phone number, both as strings. ```graphql title="GraphQL mutation" mutation { createShipment( input: { [...] recipient: { firstName: "Fictitious", lastName: "Customer", language: HU, email: "example_customer@example.org", phone: "00 01 234 5678" }, } ) { id } } ``` ### Shipment sender You can specify a sender for your shipment with the `sender` field. It is an optional field: it allows you to pass the name, email, phone number, and the bank account number of the shipment's sender. The field requires the `name` field only. ```graphql title="GraphQL mutation" mutation { createShipment( input: { [...] sender: { firstName: "Fictitious", lastName: "Sender", email: "example_customer@example.org", phone: "00 01 234 5678", bankAccountNumber: "HU99111122223333444400000000" }, } ) { id } } ``` ### Shipment origin You can set an origin for the shipment. This can be a specific address or a pickup point ID, or even exact coordinates, depending on the shipment mode. The `origin` field uses the [`ShipmentOriginInput` type](/api/merchant/types/inputs/shipment-origin-input). In the example, we're setting an address with an exact location. ```graphql title="GraphQL mutation" mutation { createShipment( input: { [...] origin: { address: { country: HU, city: "Budapest", postalCode: "1061", addressLine1: "Nyugati tér 1." }, location: { latitude: 12.000245, longitude: 23.101214 } } } ) { id } } ``` ### Add a waybill to a shipment You can add a waybill to your shipment when creating it. It requires an existing waybill ID. :::note You can assign a waybill to your shipment later with the `assignShipmentToWaybill` mutation. ::: ```graphql title="GraphQL mutation" mutation { createShipment( input: { provider: "RIV", referenceId: "12345", recipient: { firstName: "Fictitious", lastName: "Customer", language: HU }, destination: { pickupPointId: "12345" }, waybillId: "abc123" } ) { id } } ``` ### Add parcels to a shipment You can specify the exact contents of a shipment with the `parcels` field. It requires: - A `referenceId`: A unique identifier for the parcel. - A `weight` field: The weight of the parcel in kilograms. Accepts a float as a value. ```graphql title="GraphQL mutation" mutation { createShipment( input: { provider: "RIV", referenceId: "12345", recipient: { firstName: "Fictitious", lastName: "Customer", language: HU }, destination: { pickupPointId: "12345" }, parcels: { referenceId: "asdf4567", weight: 1.5 } } ) { id } } ``` #### Parcel dimensions You can specify the dimensions of the parcel: length, width, and height, all in meters. ```graphql title="GraphQL mutation" mutation { createShipment( input: { provider: "RIV", referenceId: "12345", recipient: { firstName: "Fictitious", lastName: "Customer", language: HU }, destination: { pickupPointId: "12345" }, parcels: { referenceId: "asdf4567", weight: 1.5, dimensions: { width: 0.5, height: 0.5, length: 0.7 } } } ) { id } } ``` #### Parcel payment If the recipient must pay for their parcel on delivery, set the `cashOnDelivery` field. It requires an `amount` and a `currency` field: ```graphql title="GraphQL mutation" mutation { createShipment( input: { provider: "RIV", referenceId: "12345", recipient: { firstName: "Fictitious", lastName: "Customer", language: HU }, destination: { pickupPointId: "12345" }, parcels: { referenceId: "asdf4567", weight: 1.5, cashOnDelivery: { amount: 1500, currency: HUF } } } ) { id } } ``` ## Update the shipment information Use the `updateShipment` mutation to modify an existing shipment. When updating a shipment, you must set the shipment mode in the `mode` field. It can be one of three options: - Sender to recipient: The shipment is sent from the merchant to the customer. - Recipient to sender: The shipment is sent from the customer to the merchant. For example, the customer returns a previously ordered item. - Third-party to third-party: For example, a fulfillment center shipping to a logistics provider. ```graphql title="GraphQL mutation" mutation { updateShipment( input: { id: "12345" referenceId: "12345", recipient: { firstName: "Fictitious", lastName: "Customer", language: HU }, destination: { pickupPointId: "12345" }, mode: SENDER_TO_RECIPIENT } ) { id status { status } } } ``` The `updateShipment` mutation lets you modify all fields that you can set with the `createShipment` input. --- ## Create zones If your webshop delivers to more than one country, you can create zones. A zone consists of one or more countries and you can apply specific configurations, such as pricing rules, for each zone. ## Create a zone Create zones with the `createZone` mutation: it requires a name, and an array of countries. Refer to the countries by their country code: [CountryEnum](/api/merchant/types/enums/country-enum). ```graphql mutation { createZone( input: { name: "Zone 1", countries: [HU, SK] } ) { id } } ``` The mutation returns an automatically generated an ID that you can use to refer to the zone: ```json { "data": { "createZone": { "id": "69e70342-e740-4e67-83b3-9c5efabadff2" } } } ``` ## Delete a zone To delete a zone, you just need to pass the ID of the zone as an argument to the `deleteZone` mutation: ```graphql title="GraphQL mutation" mutation { deleteZone(id: "123abc") } ``` --- ## Create an address selector and profile address list Delivery Gateway provides two views for working with home delivery addresses: - `address-selection` lets users select an existing address or enter a new one as part of a delivery flow. You can render it inline or open it in a modal. - `profile-page-address-list` is an address management view that you can embed in a user profile page. It lets users create, edit, and delete their saved addresses. Both views require a container element and either a merchant ID or a session ID when calling `DGW.mount(opts)`. ## Create an address selector Set the `type` property of `view` to `address-selection`. The optional `openInModal` property opens the selector in a modal, while `hideMainLoadingIndicator` hides the page-level loading indicator during initialization and after selection. ```js window.DGW.mount({ merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", containerId: "address-selector", view: { type: "address-selection", openInModal: true, hideMainLoadingIndicator: true, }, onAddressSelected: (result) => { console.log("Selected address:", result); }, }); ``` ### Validate the selected address Use the optional `onAddressSelected` callback to validate the address and recipient data. If the callback returns a `Promise`, the Web Plugin waits for it. When `isValid` is `false`, the selector shows the recipient form again and displays the supplied field errors. This example validates the user's email address with a custom `isEmailValid` function: ```js window.DGW.mount({ merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", containerId: "address-selector", view: { type: "address-selection", }, onAddressSelected: (result) => { if (!isEmailValid(result.recipient.email)) { return Promise.resolve({ isValid: false, errors: { email: "Oops, your email address does not appear to be valid!", }, }); } return Promise.resolve({isValid: true}); }, }); ``` ## Add an address list to a profile page Set the `type` property of `view` to `profile-page-address-list` to embed an address management interface in a user profile page. Users can create new addresses and edit or delete their existing ones without leaving the page. For authenticated customers, pass a session ID created using the Merchant API. This connects the view to the customer's saved addresses. :::important Saved addresses only work with a session created using the Merchant API. Mounting the view with only a merchant ID creates a guest session, so its addresses are not persisted for future sessions. ::: ```js window.DGW.mount({ sessionId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", containerId: "profile-address-list", view: { type: "profile-page-address-list", }, }); ``` You can use callbacks such as `onAddressCreated`, `onAddressUpdated`, and `onAddressDeleted` to react to changes made in the profile address list. For all available properties and callbacks of the `opts` object, check [DGW.mount(opts)](/dev/reference/dgw-mount-opts-properties). ## Complete example The following page demonstrates both views. When the page opens, it creates a temporary session through the Public API with three sample addresses. It then uses the returned session ID to open the address selector in a modal and render the profile address list inline. The [Public API](/api/public/introduction) does not require a Merchant Bearer token and is suitable for this browser-based demo. For persistent customer addresses in a production profile page, create the session through your backend using the Merchant API. ```html

Address selector


      

Profile page address list

Creating demo session...

``` ## Try it now When this page opens, it creates one temporary Public API session containing three sample addresses: **Home**, **Office**, and **Weekend house**. Both demos below use the returned session ID, so changes made in either view apply to the same demo session. ### Address selector Open the modal selector and enter or select an address: {() => } ### Profile page address list Create, edit, or delete addresses in the inline profile view: {() => } --- ## Create a delivery method selector Set up a delivery method selector for the Delivery Gateway embedded UI: the selector allows your customers to choose between the available delivery methods, such as home delivery, pickup point delivery, or store pickup. Your delivery method selector will display all delivery methods that you enabled for your Delivery Gateway merchant. Define the delivery method selector with the `view` field of `DGW.mount(opts)`: - As always, you need to define the container element and pass either the merchant ID or a session ID to the DGW instance. - Set the `type` property of `view` to `delivery-method-selection`. ```js window.DGW.mount({ containerId: "delivery-gateway", merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", view: { type: "delivery-method-selection", }, }); ``` When the customer selects a delivery method, the next steps - such as setting a delivery address or selecting a pickup point - can either open in a modal or in place. Use the `openSelectedMethodInModal` boolean to define the behavior: ```js window.DGW.mount({ containerId: "delivery-gateway", merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", view: { type: "delivery-method-selection", openSelectedMethodInModal: true, }, }); ``` For pickup point delivery, you can present each operator as a separate checkbox at the initial method selection: customers can immediately select a specific operator. Then the customer selects a location: the options are filtered to the selected operator. You can define this behavior with the `operatorsAsSeparateMethods` field: ```js window.DGW.mount({ containerId: "delivery-gateway", merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", view: { type: "delivery-method-selection", operatorsAsSeparateMethods, true, }, }); ``` For home delivery, you can display the icons of the available providers on the delivery method selector with `showHomeDeliveryOperatorIcons`: ```js window.DGW.mount({ containerId: "delivery-gateway", merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", view: { type: "delivery-method-selection", showHomeDeliveryOperatorIcons: true, }, }); ``` For all available properties of the `opts` object, check [DGW.mount(opts)](/dev/reference/dgw-mount-opts-properties). ## Complete example You can copy this full HTML example into your own page: ```html
``` ## Try it now You can try the same example directly on this page: {() => } --- ## Create a location verification view Use the location verification view when you already have a delivery location and want the customer to confirm or adjust the exact coordinates on the map. - As always, define the container element and pass either the merchant ID or a session ID to the DGW instance. - Set the `type` property of `view` to `location-verification`. - Pass `initialLocation` with the default latitude and longitude shown on the map. ```js window.DGW.mount({ merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", container: document.getElementById("delivery-gateway"), view: { type: "location-verification", initialLocation: { latitude: 47.4979, longitude: 19.0402, }, }, }); ``` The view is interactive by default. Use `onLocationChange` if you want to store the coordinates selected by the customer: ```js window.DGW.mount({ merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", container: document.getElementById("delivery-gateway"), view: { type: "location-verification", initialLocation: { latitude: 47.4979, longitude: 19.0402, }, zoomLevel: 16, onLocationChange: (latitude, longitude) => { updateDeliveryLocation({ latitude, longitude }); }, }, }); ``` Use `interactive: false` to render a static Mapbox image instead of the interactive map. This reduces map loading delay and cost when the customer only needs to inspect the location. ```js window.DGW.mount({ merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", container: document.getElementById("delivery-gateway"), view: { type: "location-verification", initialLocation: { latitude: 47.4979, longitude: 19.0402, }, interactive: false, zoomLevel: 16, }, }); ``` Static mode uses the same map style and zoom level as the interactive map. The image size is calculated from the rendered map container and the custom React marker is displayed over the image, so switching between static and interactive mode stays visually consistent. Use `hideInterface: true` if you want to keep the interactive map but hide the message and action containers: ```js window.DGW.mount({ merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", container: document.getElementById("delivery-gateway"), view: { type: "location-verification", initialLocation: { latitude: 47.4979, longitude: 19.0402, }, hideInterface: true, }, }); ``` You can toggle a mounted location verification view between interactive and static mode with `DGW.execute`: ```js window.DGW.execute("location-verification.toggleInteractive", false); window.DGW.execute("location-verification.toggleInteractive", true); window.DGW.execute("location-verification.toggleInteractive"); ``` The second argument is optional. Pass `true` to force interactive mode, `false` to force static mode, or omit it to toggle the current mode. The Web Plugin also dispatches an event whenever the visible location verification message changes: ```js window.addEventListener("api.deliverygateway.io/location-verification-message", (event) => { console.log(event.detail.messageKey); }); ``` `event.detail.messageKey` is one of `initial`, `thankYou`, or `tooFarAway`. For all available properties of the `opts` object, check [DGW.mount(opts)](/dev/reference/dgw-mount-opts-properties). ## Complete example The location verification view is embedded directly into its container. The following complete HTML example renders the interactive map inline and displays the coordinates selected by the customer: ```html

Verify delivery location

Latitude: 47.497900, longitude: 19.040200

``` ## Try it now The location verification view below is embedded directly into this page. Move the map to adjust the marker's coordinates: {() => } --- ## Create a pickup point selector When a customer selects pickup point delivery, they need to select an exact location. Configure the pickup point selector on the Delivery Gateway embedded UI with the `view` field of `DGW.mount(opts)`: - As always, you need to define the container element and pass either the merchant ID or a session ID to the DGW instance. - Set the `type` property of `view` to `pickup-point-selection`. ```js window.DGW.mount({ merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", container: document.getElementById("delivery-gateway"), view: { type: "pickup-point-selection", }, }); ``` You can configure the pickup point selector to always open in a modal: set `openInModal` to `true`. For example, you can use this setting to open a pickup point selection modal in response to a button click. :::tip We recommend setting `hideMainLoadingIndicator` to `true` as well: this hides the main loading indicator normally visible during initialization and after a pickup point has been selected. ::: ```js window.DGW.mount({ merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", container: document.getElementById("delivery-gateway"), view: { type: "pickup-point-selection", openInModal: true, hideMainLoadingIndicator: true, }, }); ``` You can filter for operators with `selectedOperatorFilters`: it takes an array of operator names which you can find on the [Admin Dashboard](/admin/get-started/dashboard). The map on the selector will only show the locations of the operators in the array. ```js window.DGW.mount({ merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", container: document.getElementById("delivery-gateway"), view: { type: "pickup-point-selection", openInModal: true, hideMainLoadingIndicator: true, selectedOperatorFilters: ["GLS", "DPD"], }, }); ``` For all available properties of the `opts` object, check [DGW.mount(opts)](/dev/reference/dgw-mount-opts-properties). ## Complete example You can copy this full HTML example into your own page: ```html
``` ## Try it now You can try the same example directly on this page: {() => } --- ## Example configurations for the embedded UI You can create many different types of DGW configurations, depending on what your webshop and ordering process needs. Check out our example configurations to familiarize yourself with the available options. - [Render a delivery method selector](#render-a-delivery-method-selector-with-custom-email-validation) - [Open a pickup point selection modal in response to a button click](#open-a-pickup-point-selection-modal-in-response-to-a-button-click) - [Integrate an address selector to a profile page](#integrate-an-address-selector-to-a-profile-page) - [Render a location verification view](#render-a-location-verification-view) ### Render a delivery method selector with custom email validation Set up a function that checks if an email is valid and another that manages addresses: ```js function isEmailValid(email) { // Merchant custom email validation. return true; } function handleAddress(address) { // Display, save, etc. the selected address. } ``` Mount a DGW instance: - In `containerID`, add the ID of the HTML element containing the instance. - Set the `merchantID`: you can find it in the **Merchant** menu of the Delivery Gateway admin interface. With this, the web plugin will automatically obtain the session ID for your instance. - In the `view`object, set `type` to `delivery-method-selection`. - Set `openSelectedMethodInModal` to `true` to open the pickup point selector and address selector components in a modal window. - Set `operatorsAsSeparateMethods` to `true` to render all pickup point providers as separate checkboxes. ```js const instance = DGW.mount({ containerId: "delivery-gateway", merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", view: { type: "delivery-method-selection", openSelectedMethodInModal: true, operatorsAsSeparateMethods: true, }, }); ``` For all available properties of the `opts` object, check [DGW.mount(opts)](/dev/reference/dgw-mount-opts-properties). Set up email validation within the instance using the previously created functions and the `onAddressSelected` and `recipient`properties: ```js const instance = DGW.mount({ [...] onAddressSelected: (result) => { if (!isEmailValid(result.recipient.email)) { return Promise.resolve({ isValid: false, errors: { email: "Oops, your email address does not appear to be valid!", }, }); } handleAddress(result); }, recipient: { email: "account@domain.tld", }, }); ``` Unmount the session if the user cancels the process. ```js const instance = DGW.mount({ [...] }); cancelButton.onclick = () => { instance.unmount(); } ``` Your full configuration could look something like this: ```js function isEmailValid(email) { // Merchant custom email validation. return true; } function handleAddress(address) { // Display, save etc. the selected address. } const instance = DGW.mount({ containerId: "delivery-gateway", merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", view: { type: "delivery-method-selection", openSelectedMethodInModal: true, operatorsAsSeparateMethods: true, }, onAddressSelected: (result) => { if (!isEmailValid(result.recipient.email)) { return Promise.resolve({ isValid: false, errors: { email: "Oops, your email address does not appear to be valid!", }, }); } handleAddress(result); }, recipient: { email: "account@domain.tld", }, }); cancelButton.onclick = () => { instance.unmount(); } ``` ### Open a pickup point selection modal in response to a button click Mount a DGW instance with the following basic properties: - `merchantId`: Get the merchant ID from the Delivery Gateway admin interface. With this, the web plugin will automatically obtain the session ID for your instance. - `container`: Add the HTML element that will contain your instance. In the example, we're using `document.getElementById` to return the HTML element we need. ```js window.DGW.mount({ merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", container: document.getElementById("delivery-gateway"), }); ``` In the `view` property, add the following fields: - `type: "pickup-point-selection"`: Adds the pickup point selector to the view. - `openInModal: true`: The pickup point selector modal will open immediately. - `hideMainLoadingIndicator: true`: Hides the main loading indicator. - `ownShopFilterSelected: true`: The filter for your own shops will be selected by default. - `selectedOperatorFilters: ["Operator1", "Operator2", "Operator3"]`: These operators will be selected in the operator filter panel by default. ```js window.DGW.mount({ merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", container: document.getElementById("delivery-gateway"), view: { type: "pickup-point-selection", openInModal: true, hideMainLoadingIndicator: true, ownShopFilterSelected: true, selectedOperatorFilters: ["Operator1", "Operator2", "Operator3"], }, }); ``` Create a function that handles customer addresses called `handleAddress`. Add the `onAddressSelected: handleAddress` callback. It is called when the user has selected a pickup point. ```js function handleAddress(address) { // Display, save etc. the selected address. } window.DGW.mount({ merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", container: document.getElementById("delivery-gateway"), view: { type: "pickup-point-selection", openInModal: true, hideMainLoadingIndicator: true, ownShopFilterSelected: true, selectedOperatorFilters: ["Operator1", "Operator2", "Operator3"], }, onAddressSelected: handleAddress }); ``` ### Integrate an address selector to a profile page Create and call a function that mounts an instance with the address selector. ```js function mountAddressSelector(DGW) { DGW.mount({ containerId: "address-selector", merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", view: { type: "profile-page-addresses", }, }); } if (window.DGW) { mountAddressSelector(window.DGW); } else { window.DGWOnLoad = mountAddressSelector; } ``` ### Render a location verification view Use the location verification view when you already have delivery coordinates and want the customer to confirm or adjust the exact location. ```js const instance = DGW.mount({ containerId: "delivery-gateway", merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", view: { type: "location-verification", initialLocation: { latitude: 47.4979, longitude: 19.0402, }, zoomLevel: 16, interactive: true, onLocationChange: (latitude, longitude) => { updateDeliveryLocation({ latitude, longitude }); }, }, }); window.addEventListener("api.deliverygateway.io/location-verification-message", (event) => { console.log(event.detail.messageKey); }); window.DGW.execute("location-verification.toggleInteractive", false); window.DGW.execute("location-verification.toggleInteractive", true); ``` Set `interactive` to `false` to render a static Mapbox image. Static mode uses the same map style and zoom level, calculates the image size from the rendered map container, and displays the custom React marker over the image. --- ## Manage sessions for frontend integration There are two ways to provide a session ID when using the Delivery Gateway embedded UI: - Use your merchant ID - Pass the session ID from a backend service. For a lightweight frontend integration, we recommend using the merchant ID: you pass it to the DGW instance and our Web Plugin will initalize the instance: ```js const instance = DGW.mount({ containerId: "delivery-gateway", merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", }); ``` For all available properties of the `opts` object, check [DGW.mount(opts)](/dev/reference/dgw-mount-opts-properties). Get the merchant ID from either: - The [Admin Dashboard](/admin/get-started/dashboard). - The Merchant API. To make sure that only authorized entities can use your merchant ID to initialize Delivery Gateway sessions with the Web Plugin, set up allowed HTTP referrers: [HTTP referrers for the embedded UI](/admin/how-tos/merchant-config/configure-http-referrers). --- ## Connect Delivery Gateway to your frontend ## About the frontend integration Connect Delivery Gateway features to your webshop using a frontend integration. This uses the Delivery Gateway SDK and enables to use of features such as DGW's delivery method selector, the interactive map-based pickup point selector, or the custom address pinpointing feature. Frontend initialization works like this: - You set up DGW in your own platform's frontend. - The web plugin handles creating a DGW session and passing it to the frontend logic. Note that when using frontend initialization for your sessions, certain settings can't be overridden for the session. They are applied according to the merchant configuration or the customer's browser settings. | Setting | Data source | |--------------------------------------------------------|------------------------| | Currency | Merchant configuration | | Language | Customer browser | | Authenticated customer (addresses) | Not available | | Pickup point delivery settings (enablement, pricing) | Merchant configuration | | Home delivery settings (enablement, pricing) | Merchant configuration | To set up DGW using vanilla Javascript, you need to: 1. Include the standalone DGW script. 1. Mount DGW instances using `DGW.mount`. :::note For React applications, we recommend using our official React bindings, available at `delivery-gateway-react-bindings`. They come with Typescript typings, which are also available separately in the `delivery-gateway-typings` package. ::: ## Enable the DGW object To implement DGW features, you need to enable access to the DGW object. The first step is to include the standalone Delivery Gateway script on every page where you want to use Delivery Gateway. ```html ``` Please note that Delivery Gateway's standalone script is available in multiple languages. Make sure to select the one that best suits your needs. For example, if you want to use the Dutch version of the script, you would include it like this: ```html ``` The script calls the `window.DGWOnLoad` callback (if present) with the global `DGW` object as its parameter. The global `DGW` object will also be accessible as `window.DGW`. You can use the following pattern to make sure the `DGW` object is available: ```js function mountDeliveryGateway(DGW) { // Initialize Delivery Gateway using DGW.mount(...); } if (window.DGW) { mountDeliveryGateway(window.DGW); } else { window.DGWOnLoad = mountDeliveryGateway; } ``` ## Mount DGW instances to HTML containers Mounting a Delivery Gateway instance means creating a DGW configuration that implements a DGW feature in your page. For example, you can set up a delivery method selector that is presented to users when they place an order. The `DGW` object exposes `.mount(opts)` to mount a DGW instance in a specified container, and `.execute(command, ...args)` to send commands to mounted DGW views. The `.mount(opts)` method returns a `DgwInstance` object. ```js window.DGW.mount({}) ``` The `opts` object of the `.mount()` method must contain properties that fully define the instance and its configuration. This includes the id of the HTML container that will contain the instance, the session ID for the instance user, and the view to be displayed. ```js window.DGW.mount({ merchantId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", containerId: "delivery-gateway", view: { type: } }) ``` The returned `DgwInstance` object contains the following fields: - `unmount(): void` Immediately unmounts the instance, removing all content from the container. - `isMounted(): boolean` Returns a boolean indicating whether the instance is still mounted. For all available properties of the `opts` object, check [DGW.mount(opts)](/dev/reference/dgw-mount-opts-properties). ## Configure the embedded UI - [Create a delivery method selector](create-delivery-selector) - [Create a pickup point selector](create-pickup-point-selector) - [Create an address selector](create-address-selector) - [Create a location verification view](create-location-verification) - [Example configurations](example-configurations) --- ## Configure delivery options for merchant You can configure delivery options for your merchants. This means: - Enabling the different delivery types. - Adding default information for the different delivery types. ## Enable delivery types Enabling a given delivery type means that customers can select it when placing an order. Delivery options need to be enabled for the merchant, as well as each provider. Use the `updateMerchantConfigurations` mutation. Its input field takes an array of objects that each need a key and a value. - For home delivery, the key is `HOME_DELIVERY_ENABLED`. - For pickup point delivery, the key is `PICKUP_POINT_ENABLED`. ```graphql title="GraphQL mutation" mutation { updateMerchantConfigurations( input: [{ key: HOME_DELIVERY_ENABLED, value: "true", }, { key: PICKUP_POINT_ENABLED, value: "true" }] ) { key value } } ``` ## Set delivery information Delivery information is additional text that is shown on the Delivery Gateway embedded UI when selecting a delivery method. You can specify different information for home delivery and pickup point delivery. Use the `updateMerchantConfigurations` mutation. Its input field takes an array of objects that each need a provider ID, a key, and a value. - For home delivery information, the key is `HOME_DELIVERY_INFORMATION`. - For pickup point delivery information, the key is `PICKUP_POINT_INFORMATION`. ```graphql title="GraphQL mutation" mutation { updateMerchantConfigurations( input: [{ key: HOME_DELIVERY_INFORMATION, value: "24 hour availability!", }, { key: PICKUP_POINT_INFORMATION, value: "We have over 1500 locations", }] ) { key value } } ``` --- ## Configure sender information For each merchant, we recommend configuring default sender information, such as your name, email, and address. You can set up Delivery Gateway to always send shipments with the default sender which makes the process much simpler. Use the `updateMerchantConfigurations` mutation to set up default sender information with the following keys: * `SENDER_ADDRESS_LINE1` * `SENDER_ADDRESS_LINE2` * `SENDER_CITY` * `SENDER_COUNTRY` * `SENDER_EMAIL` * `SENDER_NAME` * `SENDER_PHONE` * `SENDER_POSTAL_CODE` * `SENDER_STATE` :::note You can set these up on the Admin Dashboard, too. For each setting and their description, see [Merchant reference](/admin/reference/merchant#general-settings). ::: For example, to configure the default name and email address for your sender: ```graphql mutation { updateMerchantConfigurations( input: [{ key: SENDER_NAME, value: "Shoppiest Shop", }, { key: SENDER_EMAIL, value: "shoppiestshop@shoppiest.com", }] ) { key value } } ``` --- ## HTTP referrers for the embedded UI You can restrict access to the Delivery Gateway embedded UI: define allowed HTTP referrers to make sure only authorized platforms and services can integrate the UI with your merchant ID. :::warning We strongly recommend setting allowed HTTP referrers. Without it, anyone with access to your merchant ID can set up the Delivery Gateway frontend integration using your account. ::: To set up allowed HTTP referrers, use the `updateMerchantConfiguration` mutation with the `UI_ALLOWED_REFERRERS` key. :::note You can use a wildcard character for subdomain and path: for example, `https://*.beta.deliverygateway.io/*` ::: ```graphql mutation { updateMerchantConfiguration( input: { key: UI_ALLOWED_REFERRERS, value: "https://*.beta.deliverygateway.io/*" }, ) { key value } } --- ## Configure operators Operators manage pickup point locations. On Delivery Gateway, you can configure two things for the available operators: a title that allows easier identification and a priority. Use the `updateOperatorConfigurations` mutation to modify these settings for an operator. It requires: - An `operator`: you can see the available options at [OperatorEnum](/api/merchant/types/enums/operator-enum#values). - A `key` and a `value` field for each setting: the respective keys are `PRIORITY` and `TITLE`. ```graphql title="GraphQL mutation" mutation { updateOperatorConfigurations( input: [ { operator: MOE, key: PRIORITY, value: "1" }, { operator: MOE, key: TITLE, value: "Most Excellent Operator" } ] ) } ``` --- ## Add payment and billing information to an order ## Add payment information Add payment information to an order with the `payment` field that takes the `OrderPaymentInput` type. You need to specify: - A payment `method`. The field requires a string: you can pass the value from your system. - The payment `status`: you can check [the available options in `PaymentStatusEnum`](/api/merchant/types/enums/payment-status-enum). ```graphql title="GraphQL mutation" mutation { upsertOrder( input: { referenceId: "123456", createdAt: $date, payment: { method: "card" status: PENDING } } ) } ``` If the customer wants to pay for the order upon delivery, set the `cashOnDelivery` field which requires a `MoneyInput` type: ```graphql title="GraphQL mutation" mutation { upsertOrder( input: { referenceId: "123456", createdAt: $date, cashOnDelivery: { amount: 13599, currency: HUF } } ) } ``` When the order is paid, change the payment status and add the date of payment: the `paidAt` field requires a date in the `Y-m-d\TH:i:sP` format. ```graphql title="GraphQL mutation" mutation { upsertOrder( input: { referenceId: "123456", createdAt: $date, payment: { method: "card" status: PAID, paidAt: "2026-01-17T14:32:10+01:00" } } ) } ``` ## Add billing information When creating or updating an order, you can add billing information with the `billing` field of the `upsertOrder` mutation. You can provide: - A name - An email address - A phone number - An address - A VAT number, if applicable With the `isCompany` field, you can also specify if the bill will be paid by a company or a private individual. ```graphql title="GraphQL mutation" mutation { upsertOrder( input: { referenceId: "123456", createdAt: $date, billing: { name: "Most Excellent Customer", email: "examplemail@example.org", phone: "00 01 123 4567", vatNumber: "8337961152" isCompany: true } } ) } ``` To add the address, as a minimum you need: - `country`: See the [available country codes](/api/merchant/types/enums/country-enum). - `city` - `postalCode` - `addressLine1` In addition: - You can add a `state` field: it can be used for any type of administrative subdivision of a country, if you need it. - If the address is longer and more complex, you can add `addressLine2`. - Add a `note` to include additional information about the address. ```graphql title="GraphQL mutation" mutation { upsertOrder( input: { referenceId: "123456", createdAt: $date, billing: { name: "Most Excellent Customer", email: "examplemail@example.org", phone: "00 01 123 4567", vatNumber: "8337961152" isCompany: true, address: { country: CA, state: "Ontario" city: "Ottawa", postalCode: "K2C 0A6", addressLine1: "1026 Baseline Rd", addressLine2: "Building B, 4th floor" note: "The receptionist is grumpy" } } } ) } ``` --- ## Add shipping information to an order Add shipping information to an order with the `shipping` field. It requires the `OrderShippingInput` input type which provides fields for all relevant shipping information. You can specify: - The customer information, such as name, email, and phone. - A delivery method: check [ShippingMethodEnum](/api/merchant/types/enums/shipping-method-enum) for the options. - A provider that will perform the delivery. - The shipment [status](/api/merchant/types/enums/shipment-status-enum). In addition, if the selected delivery method is pickup point delivery, you can add a pickup point ID. ```graphql mutation { upsertOrder( input: { [...], shipping: { name: "Example Customer", email: "ec@example.org", phone: "0036701234567", method: PICKUP_POINT, provider: "Red Ivorp", status: IN_PROGRESS, } } ) } ``` Iff the selected delivery method is pickup point delivery, you can add a pickup point ID. That's where the order will be shipped to: ```graphql mutation { upsertOrder( input: { [...], shipping: { name: "Example Customer", email: "ec@example.org", phone: "0036701234567", pickupPointId: "123abc", method: PICKUP_POINT, provider: "Red Ivorp", status: IN_PROGRESS, } } ) } ``` For home delivery, add an address. An address requires [a country code](/api/merchant/types/enums/country-enum), a city, a postal code, and an address: :::note You can pass the address from the `customer` field of a session: [Manage authenticated customers](/dev/how-tos/sessions/authenticate-customers). ::: ```graphql mutation { upsertOrder( input: { [...], shipping: { name: "Example Customer", email: "ec@example.org", phone: "0036701234567", pickupPointId: "123abc", method: HOME_DELIVERY, provider: "Red Ivorp", status: IN_PROGRESS, address: { country: GB, city: "Manchester" postalCode: "M16 0RA" addressLine1: "Sir Matt Busby Way" } } } ) } ``` --- ## Create an order ## About orders An order is a customer's request to purchase one or more products and have them delivered via a specified method. With the Delivery Gateway backend integration, you can create orders, assign all the relevant information to them, and manage them throughout the order's lifecycle. An order requires the following data: - A reference ID: an automatically generated ID assigned by your system. - When the order was created. - The total price of the order. You must specify both the net and gross values. - The items included in the order. ### Order items You can pass extensive information about items in a given order to the Merchant API. The `OrderItemInput` type allows assigning different identifiers such as a name, a reference ID or an SKU. You can specify categories for your items (for example, "Electronics"), and variants (for example, 128 GB or 256 GB smartphone models). #### Global identifiers Delivery Gateway enables the use of global identifier standards in your orders: for example, GTIN, EAN, or ISBN. These are available under the `globalIdentifiers` field of the `upsertOrder` mutation. #### Item price Item price is calculated from the unit price and quantity of each item. The unit price consists of the net price, gross price, and the VAT value. You can calculate the total price of items from the unit price and quantity of each item. When setting a quantity, you can select the unit: piece, kilogramm, liter, or other. ## Create an order Create and update orders with the `upsertOrder` mutation. ### Part 1: Assign an ID First, assign the order an ID and set the time of its creation: - Generate an ID and pass it to `referenceId`. - Pass the time in `Y-m-d\TH:i:sP` format to `createdAt`. ```graphql title="GraphQL mutation" mutation { upsertOrder( input: { referenceId: "123456", createdAt: $date } ) } ``` ### Part 2: Add items Add the items to the order. If you have multiple items, include them as an array. Each item must have a name, a unit price, a quantity, and a total price. - The `unit` field sets the unit price. The `net` and `gross` subfields both require an amount and a currency and you also need to specify the VAT in the `vat` subfield. - The `quantity` field requires `count` which takes a float, and `type` which defines the measurement. In addition to the pre-defined values, you can set it to `OTHER` and specify ta custom type with the `typeOther` field. - The `total`, like the unit prices, requires both a net and a gross amount. The total price should be calculated as the unit price multiplied by the item quantity. ```graphql title="GraphQL mutation" mutation ( $netPrice: # calculated net price of order $grossPrice: # calculated gross price of order ){ upsertOrder( input: { referenceId: "123456", createdAt: "2025-12-10\\CET16:17:52+01:00", items: { name: "HAL-9000" unit: { net: { amount: 55000, currency: HUF }, vat: 27, gross: { amount: 69850, currency: HUF } } quantity: { count: 1, type: PIECE } total: { net: { amount: $netPrice currency: HUF }, gross: { amount: $grossPrice currency: HUF } } isShipping: true, isPayment: true, isDiscount: false }, } ) } ``` ### Part 3: Calculate the total The final total price of the order is set in the `total` field. This also requires a `net` and a `gross` subfields. You can calculate the total price by adding all unit price totals. ```graphql title="GraphQL mutation" mutation ( $netPrice: # calculated net price of order $grossPrice: # calculated gross price of order $totalnetPrice: # a calculated total net price of all items $totalgrossPrice: # a calculated total gross price of all items ){ upsertOrder( input: { referenceId: "123456", createdAt: "2025-12-10\\CET16:17:52+01:00", total: { net: { amount: 55000, currency: HUF } gross: { amount: 69850, currency: HUF } }, items: [{ name: "HAL-9000" unit: { net: { amount: 55000, currency: HUF }, vat: 27, gross: { amount: 69850, currency: HUF } } quantity: { count: 1, type: PIECE } total: { net: { amount: $netPrice currency: HUF }, gross: { amount: $grossPrice currency: HUF } } isShipping: true, isPayment: true, isDiscount: false }, ] } ) } ``` ## Assign a customer and a session to an order The `upsertOrder` mutation allows assigning a customer ID and a session ID to an order, allowing your system to easily associate an order with a registered customer. You need a `sessionId` and a `customerId`: - The `sessionId` field is automatically generated by the Delivery Gateway API when initializing a session. - The `customerId` is generated by your own system. ```graphql title="GraphQL mutation" mutation { upsertOrder( input: { referenceId: "123456", createdAt: $date, customerId: "efgh4567", sessionId: "asdf-efht-1345-2346" } ) } ``` --- ## End-to-End Checkout Integration ## Overview This guide describes the complete flow for integrating Delivery Gateway into your webshop checkout process. It covers the entire journey from the backend session creation through frontend widget integration to order and shipment management. ## Architecture The integration involves four main components: - **User/Customer**: Initiates the checkout process - **Frontend (Webshop)**: Frontend client running on the browser - **Frontend (Delivery Gateway Widget)**: Handles delivery method selection and address management - **Backend (Webshop)**: Your backend system - **Backend (Delivery Gateway)**: Processes sessions, orders, and shipments ### Integration Sequence ```mermaid sequenceDiagram participant User participant Frontend as Frontend
(Webshop) participant DGWFrontend as Frontend
(DGW Widget) participant Backend as Backend
(Webshop) participant DGWBackend as Backend
(DGW) User->>Frontend: I need delivery Frontend->>Backend: Request session creation Backend->>DGWBackend: createSession() DGWBackend-->>Backend: session id Backend-->>Frontend: session id Frontend->>DGWFrontend: initialize DGW.mount() with sessionId DGWFrontend->>User: Display delivery options User->>DGWFrontend: Select delivery method DGWFrontend-->>Frontend: onSelection callback Frontend->>Backend: Confirm delivery selection Backend->>DGWBackend: Query session DGWBackend-->>Backend: Selected delivery details Backend-->>Frontend: Delivery confirmed Frontend->>User: Ready for payment User->>Frontend: Submit order Frontend->>Backend: Create order Backend->>DGWBackend: upsertOrder() DGWBackend-->>Backend: order id Backend->>DGWBackend: createShipment() DGWBackend-->>Backend: shipment id + label URL Backend-->>Frontend: Order confirmation Frontend-->>User: Show shipment details DGWBackend->>Backend: SHIPMENT_UPDATED webhook Backend-->>User: Status updates ``` ## Step 1: Create a Session on the Backend When a customer reaches the shipping method selection step in your checkout, initiate a session from your backend. ### Why start with a session? Creating a session allows you to: - Associate delivery options and pricing with a specific customer journey - Pass custom data (such as shipping costs) to the frontend widget - Obtain a `sessionId` that connects the frontend interactions to your backend ### Create a session Use the `createSession` mutation to create a new session: ```graphql title="GraphQL mutation" mutation { createSession(input: { # Optional: pass delivery options and pricing items: [ { name: "Standard Delivery" price: { net: { amount: 1000, currency: HUF } gross: { amount: 1270, currency: HUF } vat: 27 } } ] }) { session { id } } } ``` **Response:** ```json { "data": { "createSession": { "session": { "id": "session_abc123xyz" } } } } ``` Store the `sessionId` to use in the next steps. **Reference:** [Create Session](/dev/how-tos/sessions/create-session) ## Step 2: Load the Delivery Gateway Frontend SDK On your checkout page, load the Delivery Gateway JavaScript SDK: ```html ``` For details on SDK setup, see: [Set Up DGW on Frontend](/dev/how-tos/frontend-integration/set-up-dgw-on-frontend) ## Step 3: Render the Delivery Selection Widget When a customer reaches the delivery method selection step, render the appropriate widget based on their choice. ### For store/pickup point delivery If the customer selects "Store Pickup" or "Pickup Point Delivery": ```javascript window.DGW.mount({ sessionId: 'session_abc123xyz', type: 'pickup-point-selection', ownShopFilterSelected: true, // true for your own stores, false for third-party pickup points container: '#dgw-widget', onAddressSelected: (data) => { console.log('Selected pickup point:', data); } }); ``` **Reference:** [Create Pickup Point Selector](/dev/how-tos/frontend-integration/create-pickup-point-selector) ### For home delivery If the customer selects home delivery and needs to enter or modify their address: ```javascript window.DGW.mount({ sessionId: 'session_abc123xyz', type: 'address-selection', container: '#dgw-widget', onAddressSelected: (data) => { console.log('Selected address:', data); } }); ``` **Reference:** [Create Address Selector](/dev/how-tos/frontend-integration/create-address-selector) ## Step 4: Handle Widget Callbacks When a customer completes their selection in the widget, the callback is triggered with the selected delivery information. `onAddressSelected`: Triggered when the customer successfully selects a delivery method and location. The callback receives an object containing: - Selected delivery method details - Pickup point or address information - Session metadata **Reference:** [Callback Options](/dev/reference/dgw-mount-opts-properties#callback-options) ### Store the delivery details While you receive delivery information in the frontend callback, **we strongly recommend querying the session from your backend** for security reasons. This prevents tampering with delivery data. ```javascript // In your frontend callback, you might show a confirmation // But verify on the backend: onAddressSelected: (data) => { fetch('/your-api/confirm-delivery-selection', { method: 'POST', body: JSON.stringify({ sessionId: 'session_abc123xyz' }) }); } ``` On your backend, retrieve the verified session data: ```graphql title="GraphQL query" query { session(id: "session_abc123xyz") { id selectedDeliveryMethod { id name } selectedPickupPoint { id name address } selectedAddress { street city postalCode country } pricing { net { amount, currency } gross { amount, currency } vat } } } ``` Store the delivery method, pickup point, or address in your checkout data. **Reference:** [Query Session](/dev/reference/dgw-mount-opts-properties#query-session) ## Step 5: Create an Order When the order is finalized and ready to be shipped, create an order in Delivery Gateway. We recommend that your **ERP system creates the order** rather than the webshop, since this keeps order creation logic in one place. ### Using the upsertOrder mutation ```graphql title="GraphQL mutation" mutation { upsertOrder(input: { referenceId: "order_12345" createdAt: "2025-04-16T14:30:00+02:00" items: [ { name: "Product Name" sku: "SKU-001" quantity: { count: 1, type: PIECE } unit: { net: { amount: 10000, currency: HUF } gross: { amount: 12700, currency: HUF } vat: 27 } total: { net: { amount: 10000, currency: HUF } gross: { amount: 12700, currency: HUF } } isShipping: true isPayment: true } ] total: { net: { amount: 10000, currency: HUF } gross: { amount: 12700, currency: HUF } } }) { order { id referenceId status } } } ``` **Reference:** [Create an Order](/dev/how-tos/orders/create-an-order) ## Step 6: Create a Shipment Once your order is created and ready to ship, create a shipment. You can either: 1. **Pass order data within the shipment creation** (recommended for simple workflows) 2. **Create the order first, then reference it** (recommended for complex workflows) ### Creating a shipment with inline order data ```graphql title="GraphQL mutation" mutation { createShipment(input: { order: { referenceId: "order_12345" # ... order data } selectedDeliveryMethod: "pickup-point" pickupPointId: "pp_xyz789" sender: { name: "Your Shop Name" address: { street: "123 Main St" city: "Budapest" postalCode: "1011" country: "HU" } email: "shop@example.com" phone: "+36-1-234-5678" } }) { shipment { id status parcels { label { url } } } } } ``` **The response includes the parcel label URL:** ```json { "data": { "createShipment": { "shipment": { "id": "shipment_abc123", "status": "PENDING", "parcels": [ { "label": { "url": "https://dgw-labels.example.com/label_xyz789.pdf" } } ] } } } } ``` Retrieve and store the label URL for printing or sending to the customer. **Reference:** [Create Shipment](/dev/how-tos/orders/create-shipment) ## Step 7: Monitor Shipment Status Track shipment status using one of two methods: ### Option 1: Webhooks (Recommended) Subscribe to `SHIPMENT_UPDATED` webhooks to receive real-time status updates without polling: ```json { "event": "SHIPMENT_UPDATED", "data": { "shipmentId": "shipment_abc123", "status": "PICKED_UP", "updatedAt": "2025-04-16T15:45:00+02:00" } } ``` You can configure webhooks: - **Via code**: Subscribe programmatically during integration - **Via Admin Panel**: Set up once, then automatically receive updates for all shipments **Reference:** [Configure Webhooks](/dev/how-tos/configure-webhooks) ### Option 2: Polling Query the shipment status on-demand: ```graphql title="GraphQL query" query { shipment(id: "shipment_abc123") { id status trackingNumber estimatedDeliveryDate parcels { id status tracking { url number } } } } ``` Use polling only if you cannot use webhooks. Webhooks reduce server load and provide faster updates. **Reference:** [Query Shipment](/dev/reference/dgw-shipment-queries) ## Complete Flow Summary 1. **Backend initiates**: Create a session with delivery options and pricing 2. **Frontend renders**: Load the SDK and display the widget 3. **Customer selects**: Chooses delivery method and location via widget 4. **Backend verifies**: Query the session to confirm the delivery selection 5. **Backend prepares**: Store delivery details in your checkout 6. **ERP creates**: Generate the finalized order 7. **Backend ships**: Create a shipment and retrieve the label URL 8. **Monitor**: Track shipment status via webhooks or polling ## Best Practices - **Security**: Always verify delivery selections on your backend before proceeding with orders - **Order creation**: Have your ERP system create orders to centralize order management logic - **Webhooks**: Use webhooks for real-time shipment status updates instead of polling - **Labels**: Retrieve and securely store label URLs immediately after shipment creation - **Error handling**: Implement proper error handling for each step (session creation, widget interaction, order/shipment creation) --- ## Configure delivery options for providers You can configure delivery options separately for each provider. This includes: - Enabling home delivery and pickup point delivery. - Setting information for both delivery types. :::note You can perform all these actions in the Delivery Gateway Admin Dashboard. ::: ## Enable the provider Your customers can only select a specific provider if it is enabled. To enable the provider, use the `updateProviderConfigurations` mutation and set the `AVAILABLE` key to `true`: ```graphql title="GraphQL mutation" mutation { updateProviderConfigurations( input: [{ provider: BEST_PROV, key: AVAILABLE, value: "true", },] ) { key value } } ``` ## Enable delivery types Enabling a given delivery type means that customers can select it when placing an order. You need to enable delivery options for each provider. Use the `updateProviderConfigurations` mutation. Its input field takes an array of objects that each need a provider ID, a key, and a value. - For home delivery, the key is `HOME_DELIVERY_AVAILABLE`. - For pickup point delivery, the key is `PICKUP_POINT_AVAILABLE`. To enable both: ```graphql title="GraphQL mutation" mutation { updateProviderConfigurations( input: [{ provider: BEST_PROV, key: HOME_DELIVERY_AVAILABLE, value: "true", }, { provider: BEST_PROV, key: PICKUP_POINT_AVAILABLE, value: "true" }] ) { key value } } ``` ## Set delivery information Delivery information is additional text that is shown on the Delivery Gateway embedded UI when selecting a provider. You can specify different information for home delivery and pickup point delivery. Use the `updateProviderConfigurations` mutation. Its input field takes an array of objects that each need a provider ID, a key, and a value. - For home delivery information, the key is `HOME_DELIVERY_INFORMATION`. - For pickup point delivery information, the key is `PICKUP_POINT_INFORMATION`. ```graphql title="GraphQL mutation" mutation { updateProviderConfigurations( input: [{ provider: BEST_PROV, key: HOME_DELIVERY_INFORMATION, value: "24 hour availability!", }, { provider: BEST_PROV, key: PICKUP_POINT_INFORMATION, value: "We have over 1500 locations" }] ) { key value } } ``` --- ## Configure required address fields You can set different address requirements for each provider. Address requirements define what information the customer must provide when selecting a delivery method and a provider. You can set the required information separately for home delivery and for pickup point delivery. ```graphql mutation { updateProviderConfigurations( input: [{ provider: "GLS", key: REQUIRED_ADDRESS_FIELDS_FOR_HOME_DELIVERY, value: "first_name,last_name,email,phone,country,city,postal_code,address_line1,address_line2,location", }, { provider: "GLS", key: REQUIRED_ADDRESS_FIELDS_FOR_PICKUP_POINT_DELIVERY, value: "first_name,last_name,email,phone", }] ) { key value } } ``` --- ## Enable a provider To make providers available for customers, you need authentication data. The exact requirements differ based on the provider. For example, a provider might need a merchant API key, a merchant tracking API key, a customer ID and a client ID. You can configure these with the `updateProviderConfigurations` mutation. ```graphql title="GraphQL mutation" mutation { updateProviderConfigurations( input: [ { provider: BestProv, key: API_KEY, value: "12315789-abcdefg", }, { provider: BestProv, key: TRACKING_API_KEY, value: "12315789-abcdefg", }, { provider: BestProv, key: CUSTOMER_ID, value: "abc123" }, { provider: BestProv, key: CLIENT_ID, value: "abc123" },] ) { provider key value } } ``` Check out the required data for each provider: [Required credentials](/admin/reference/providers). In addition, you must set the provider to available: ```graphql title="GraphQL mutation" mutation { updateProviderConfigurations( input: [{ provider: BEST_PROV, key: AVAILABLE, value: "true", },] ) { key value } } ``` --- ## Add parcel information to session There are two ways of passing parcel information to a session: - Create a packaging and set it as the default. - Add parcel information during the session. If you create a default packaging and you don't provide parcel details during a session, the default packaging will be used. To add packaging information during session creation, use the `parcels` field. It requires two fields: - `weight`: The weight of the parcel in kilogramms. The field takes a float as a value. - `dimensions`: The length, width, and height of the parcel in meters. Takes floats as values. ```graphql mutation { session( input: { parcels: { weight: 2, dimensions: { width: 1.5, length: 2, height: 0.5 } } } ) { id, parcels { weight } } } ``` You can add additional costs to your parcels: - Add insurance costs for parcel insurance. - Add a cash on delivery cost. :::note All the relevant fields require [the `Money` object type](/api/merchant/types/objects/money), with the amount and the currency specified. ::: ```graphql mutation { session( input: { parcels: { weight: 2, dimensions: { width: 1.5, length: 2, height: 0.5 }, cashOnDelivery: { amount: 1.5, currency: EUR }, insurance: { amount: 5, currency: EUR } } } ) { id, parcels { weight } } } ``` --- ## Manage authenticated customers Authenticated customers can access additional features during a session, such managing customer addresses. To enable it, generate a `referenceId` string in your backend system for authenticated customers. When creating or updating the session, add the `customer` input field and identify the customer with the `referenceId` field. ```graphql mutation { session( input: { id: "4fa5697b-2c7f-44ff-973a-6238f26e473c" customer: { referenceId: "123abc" } } ) { id } } ``` ```curl curl 'https://api.deliverygateway.io/graphql/merchant' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Connection: keep-alive' -H 'Authorization: ' --data-binary '{"query":"mutation {\n session(\n input: {\n id: \"4fa5697b-2c7f-44ff-973a-6238f26e473c\"\n customer: {\n referenceId: \"123abc\"\n }\n }\n )\n {\n id\n }\n}","variables":{}}' --compressed ``` You can set an already existing address to the customer. To do that, the address also needs a `referenceId` to identify it. You can also give it a custom label with the `label` field which takes a string: ```graphql mutation { session( input: { id: "4fa5697b-2c7f-44ff-973a-6238f26e473c" customer: { referenceId: "123abc", addresses: [{ referenceId: "address123xyz", label: "Custom label for Address 123 XYZ", }] } } ) { id } } ``` Each address has three components: - Recipient: The name of the addressee, the communication language, and their email address and phone number. - Address: The actual postal address, including country, city, and street. - Location: The precise location, defined by latitude and longitude coordinates. This is optional by default but you can configure your merchant to always require it from customers. Both latitude and longitude values take floats as values: ```graphql mutation { session( input: { id: "4fa5697b-2c7f-44ff-973a-6238f26e473c" customer: { referenceId: "123abc", addresses: [{ referenceId: "address123xyz", label: "Custom label for Address 123 XYZ", recipient: { firstName: String! lastName: String! # Communication language for the addressee. language: LanguageEnum! email: String phone: String } address: { country: CountryEnum! state: String city: String! postalCode: String! addressLine1: String! addressLine2: String note: String } location: { latitude: Float! longitude: Float! } }] } } ) { id } } ``` --- ## Create and update a session Create a session with the `session` mutation. A bare minimum session requires no inputs and returns its automatically generated ID: ```graphql mutation { session( input: { } ) { id } } ``` When you need to update an existing session, you just need the `id` to retrieve it: ```graphql mutation { session( input: { id: "72f1b7aa-ae56-4c84-b289-863f33e7c219" } ) { id } } ``` The `SessionInput` type allows you to configure session details. By default, currency is configured in the merchant configuration, while the language is defined by the OS or browser locale. To override them, set a currency and a language for the session: ```graphql mutation { session( input: { currency: EUR, language: EN } ) { id } } ``` --- ## Manage delivery methods During a session, you can override the pre-configured delivery method settings. You can enable or disable home delivery and pickup point delivery, select different providers, or set up new pricing configurations. ## Enable a delivery method during a session By default, the merchant configuration determines if pickup point delivery or home delivery is available for a customer. You can override the setting when creating or updating a session by using `enabled` which takes a boolean: ```graphql mutation { session( input: { pickupPoint: { enabled: true } } ) { id } } ``` ```graphql mutation { session( input: { homeDelivery: { enabled: true } } ) { id } } ``` ## Enable specific providers Provider availability is defined by the provider configuration. You can override it during a session with the `providers` field, both for home delivery and pickup point delivery. If the `provider` field is not used or left blank, all enabled providers will be available. To check the list of available providers, see [ProviderEnum](/api/merchant/types/scalars/provider-enum). ```graphql mutation { session( input: { pickupPoint: { enabled: true, provider: "Red Ivorp" } } ) { id } } ``` ```graphql mutation { session( input: { homeDelivery: { enabled: true, provider: "Red Ivorp" } } ) { id } } ``` ## Enforce precise location for home delivery You can ask the customer to check and provide an exact location, with coordinates. By default, you can configure this in the merchant configuration but you can override the setting here. To enable it, set the `location` field of `homeDelivery` to `true`. ```graphql mutation { session( input: { homeDelivery: { enabled: true, location: true } } ) { id } } ``` ## Set recipient details for pickup point delivery Pickup point delivery requires recipient details such as name, language, email address and phone number. You can set this information in the `recipient` field of `pickupPoint` during a session. Unless all the information is available, Delivery Gateway will ask the customer to provide the details. :::note Authenticated customers can use saved addresses. In this case, you don't need to handle recipient details separately. See [Manage authenticated customers](/dev/how-tos/sessions/authenticate-customers) for details. ::: The `recipient` field's subfields all take strings, with the exception of language. For the list of available languages, see [LanguageEnum](/api/merchant/types/enums/language-enum). ```graphql mutation { session( input: { pickupPoint: { recipient: { firstName: true, lastName: true, language: email: phone: } } } ) { id } } ``` --- ## Update pricing during a session ### Update pricing for all delivery types You can update pricing information during a session, instead of using the pre-configured pricing rules. Use the `price` field when creating and/or updating a session: ```graphql mutation { session( input: { price: [{}] } ) { id } } ``` The `SessionPriceInput` type has two fields: `provider` and `price`. The `provider` field allows you to select a provider to whom the session pricing applies. If left blank, it will apply to all available providers. To check the list of available providers, see [ProviderEnum](/api/merchant/types/scalars/provider-enum). ```graphql mutation { session( input: { price: [{ provider: "Red Ivorp" }] } ) { id } } ``` To update the price, set the currency and the amount in the `price` field. In this example, the new price of €4.5 will apply to the provider Red Ivorp. ```graphql mutation { session( input: { price: [{ provider: "Red Ivorp", price: { currency: EUR, amount: 4.5, } }] } ) { id } } ``` ### Update pricing for a specific delivery type Instead of updating pricing for all deliveries, you can create a new pricing for either home delivery or pickup point delivery. The `price` field is available for both `homeDelivery` and `pickupPoint`: ```graphql title="Price of home delivery" mutation { session( input: { homeDelivery: { enabled: true, price: [{ price: { amount: 4, currency: USD } }] } } ) { id } } ``` ```graphql title="Price of pickup point delivery" mutation { session( input: { pickupPoint: { enabled: true, price: [{ price: { amount: 4, currency: USD } }] } } ) { id } } ``` --- ## Roles and permissions reference | Role | Permissions | Description | |------|-------------|-------------| | `merchant:token` | - `merchant:token:create`- `merchant:token:list`- `merchant:token:delete` | Create, list, and delete [Bearer access tokens](/dev/getting-started/authentication). | | `merchant:provider` | - `merchant:provider:list` | List the available providers. | | `merchant:operator` | - `merchant:operator:list` | List the available operators. | | `merchant:configuration` | - `merchant:configuration:list`- `merchant:configuration:get`- `merchant:configuration:update` | View and update everything in the [merchant configuration](/admin/how-tos/merchant-config). See the [available settings](/admin/reference/merchant). | | `merchant:webhook` | - `merchant:webhook:create`- `merchant:webhook:list`- `merchant:webhook:get`- `merchant:webhook:update`- `merchant:webhook:delete` | Create, list, update, and delete [webhooks](/dev/how-tos/configure-webhooks). | | `merchant:shipment` | - `merchant:shipment:create`- `merchant:shipment:list`- `merchant:shipment:get`- `merchant:shipment:update`- `merchant:shipment:delete` | Create, list update, and delete [shipments](/dev/how-tos/create-shipment). | | `merchant:waybill` | - `merchant:waybill:create`- `merchant:waybill:list`- `merchant:waybill:get`- `merchant:waybill:update`- `merchant:waybill:delete` | Create, list, update, and delete waybills. | | `merchant:session` | - `merchant:session:create`- `merchant:session:get` | Initialize a new Delivery Gateway session and retrieve an existing session's data. | | `merchant:zone` | - `merchant:zone:create`- `merchant:zone:list`- `merchant:zone:get`- `merchant:zone:update`- `merchant:zone:delete` | Create, list, update, and delete [geographical zones](/admin/how-tos/create-zones). | | `merchant:pricing` | - `merchant:pricing:create`- `merchant:pricing:list`- `merchant:pricing:get`- `merchant:pricing:update`- `merchant:pricing:delete` | Create, list, update, and delete [pricing rules](/admin/how-tos/create-pricing). | | `merchant:theme` | - `merchant:theme:create`- `merchant:theme:list`- `merchant:theme:get`- `merchant:theme:update`- `merchant:theme:delete` | Create, list, update, and delete [themes](/admin/how-tos/integrations/theming). | | `merchant:packaging` | - `merchant:packaging:create`- `merchant:packaging:list`- `merchant:packaging:get`- `merchant:packaging:update`- `merchant:packaging:delete` | Create, list, update, and delete [packagings](/admin/how-tos/create-packaging) | --- ## DGW.mount Usage: `DGW.mount(opts)`; ## Mount Initialization Options Use these options when calling DGW.mount(opts). ### Core options | Parameter | Type | Required | Description | |---|---|---|---| | containerId | string | Conditionally | ID of the container element where the plugin will be rendered. Use this or container. | | container | HTMLElement | Conditionally | Direct DOM element where the plugin will be rendered. Use this or containerId. | | portalRootContainer | HTMLDivElement | No | Custom portal root for modals and overlays. Useful if you need popups rendered into a specific DOM subtree. | | overrideThemeVars | DgwThemeVars | No | Runtime theme variable overrides (brand color, rounding, font family). | | view | DgwView | Yes | Defines which plugin view is rendered. | | sessionId | string | Conditionally | Existing session ID to load. Use this or merchantId. | | merchantId | string | Conditionally | Merchant ID for plugin-managed session creation. Use this or sessionId. | | themeHandle | string | No | Applies a configured theme by handle. | | sessionInitOpts | CreateSessionInput | No | Session creation payload used with merchant-based initialization. | | disableShadowDOM | boolean | No | Disables Shadow DOM encapsulation so host page styles can affect plugin internals more directly. | ### Callback options | Parameter | Description | |---|---| | onAddressSelected | Triggered when user selects an address or pickup point. Can return validation result to block/allow continuation. | | onAddressSelectionSucceeded | Triggered after a successful address or pickup selection flow. | | onAddressBeforeCreate | Called before creating an address. Can modify flow data (for example referenceId). | | onAddressCreated | Called after an address is created. | | onAddressBeforeUpdate | Called before updating an address. Can modify flow data (for example referenceId). | | onAddressUpdated | Called after an address is updated. | | onAddressDeleted | Called after an address is deleted. | | onSessionLoaded | Called when session data has finished loading. | | onClosed | Called when the plugin UI is closed (for example modal close). | ### Theme override object (overrideThemeVars) | Field | Type | Description | |---|---|---| | brand_color | string \| null | Primary brand color override. | | surface_rounding | rounded \| square \| null | Controls surface corner style. | | button_rounding | full \| default \| square \| null | Controls button corner style. | | font_family | string \| null | Global font family override. | ## View-specific options ### delivery-method-selection | Parameter | Type | Required | Description | |---|---|---|---| | type | delivery-method-selection | Yes | Selects the delivery method selector view. | | openSelectedMethodInModal | boolean | No | Opens pickup/address step in modal instead of inline flow. | | operatorsAsSeparateMethods | boolean | No | Renders pickup operators as separate delivery method options. | | showHomeDeliveryOperatorIcons | boolean | No | Displays operator icons for home delivery methods. | | homeDeliveryOverride | object | No | Customizes home-delivery selection behavior. | | homeDeliveryOverride.onSelect | `() => boolean \| Promise \| undefined` | No | Intercepts selection and can allow/deny custom logic. | | homeDeliveryOverride.initialSelected | boolean | No | Sets initial selected state for home-delivery override flow. | | customPickupPointAsSeparateMethod | boolean | No | Renders custom pickup points (merchant's stores) as separate delivery method options in the delivery method selection step. | | showFiltersByDefault | boolean | No | Controls whether the filter sidebar is open by default (default: `false`) | ### pickup-point-selection | Parameter | Type | Required | Description | |---|---|---|---| | type | pickup-point-selection | Yes | Selects standalone pickup point selector view. | | openInModal | boolean | No | Opens selector in modal mode. | | hideMainLoadingIndicator | boolean | No | Hides main loading indicator during init and post-selection states. | | selectedOperatorFilters | OperatorEnum[] | No | Preselects operator filters. | | ownShopFilterSelected | boolean | No | Preselects own-shop filter. | | showFiltersByDefault | boolean | No | Controls whether the filter sidebar is open by default (default: `false`) | ### address-selection | Parameter | Type | Required | Description | |---|---|---|---| | type | address-selection | Yes | Selects standalone address selector view. | | openInModal | boolean | No | Opens selector in modal mode. | | hideMainLoadingIndicator | boolean | No | Hides main loading indicator. | ### location-verification | Parameter | Type | Required | Description | |---|---|---|---| | type | location-verification | Yes | Selects standalone location verification view. | | initialLocation | `{ latitude: number; longitude: number }` | Yes | Default location shown on the map. | | interactive | boolean | No | Shows the interactive Mapbox map when `true`, or a static Mapbox image when `false`. Default: `true`. | | zoomLevel | number | No | Sets the zoom level for both the interactive map and static image. Values are clamped to the Mapbox range `0`-`22`. | | hideInterface | boolean | No | Hides the message and action containers in interactive mode. Default: `false`. | | onLocationChange | `(latitude: number, longitude: number) => void` | No | Called when the user changes the selected location in interactive mode. | Static mode uses the same map style as the interactive map, calculates the image size from the rendered map container, and displays the custom marker over the image. ### profile-page-address-list | Parameter | Type | Required | Description | |---|---|---|---| | type | profile-page-address-list | Yes | Renders profile address management page/list view. | ## Related DGW API | Method | Signature | Description | |---|---|---| | preloadSession | `preloadSession({ apiUrl, sessionId, merchantId, sessionInitOpts }): Promise` | Preloads session-related data before mount to reduce perceived latency on first open. | | getI18nLanguage | getI18nLanguage(): HU \| EN \| NL | Returns the active plugin language code. | | execute | `execute(command, ...args): void` | Sends a command to mounted DGW views. | ### Supported execute commands | Command | Arguments | Description | |---|---|---| | location-verification.toggleInteractive | `interactive?: boolean` | Toggles mounted location verification views between interactive and static mode. Pass `true` to force interactive mode, `false` to force static mode, or omit the argument to toggle the current mode. | ## Browser events | Event name | Detail | Description | |---|---|---| | api.deliverygateway.io/location-verification-message | `{ messageKey: "initial" \| "thankYou" \| "tooFarAway" }` | Dispatched whenever the location verification message changes. | ### The returned DGW instance fields | Field name and format | Type | Description | |---|---|---| | unmount() | `() => void` | Immediately unmounts the instance, removing all content from the container. | | isMounted() | `() => boolean` | Returns a boolean indicating whether the instance is still mounted. | --- ## Shipment statuses The following shipment statuses are available in the `ShipmentStatusEnum` type: - `WAITING_FOR_COLLECTION`: The provider has accepted the shipment and they're expecting its arrival. - `IN_PROGRESS`: The delivery is underway. - `DELIVERING`: The shipment is either with the courier or it is being transported to a pickup point. - `RECEIVABLE`: You can pick up the shipment at a pickup point. - `DELIVERED`: The final status: the recipient has received the shipment. - `FAILING`: The delivery can't be successfully completed. Usually this means the shipment is getting sent back to the sender. - `FAILED`: The delivery failed. The `reason` field will contain the nature of the problem. --- ## Merchant In the Delivery Gateway system, the merchant is your e-commerce platform or platforms. That is to say, the merchant is the entity that accepts orders from customers and contracts with logistics providers to deliver those orders. The merchant configuration provides a set of default settings for a number of Delivery Gateway features. It allows you to provide information that can be reused for any delivery. ## The merchant ID The merchant ID is your merchant's unique identifier. It is automatically generated when you register a new merchant, and it is used to identify the merchant to the Web Plugin and the Merchant API. The easiest, most convenient way of accessing Delivery Gateway features is to use a lightweight frontend integration, utilizing our embedded UI: you can use the merchant ID to connect your merchant to the integration. For more information, check out [Frontend integration](/dev/how-tos/frontend-integration). For backend integration, the Merchant API also uses the ID to identify your merchant. You can query it in the `id` field of the `Merchant` object type. :::important You can't change your merchant ID. ::: ## Merchant configuration :::note This section is about merchant configuration via the Merchant API. For information on how to configure your merchant in the Admin dashboard, see [Merchant configuration](/admin/how-tos/merchant-config). ::: With the Merchant API, you can create and update your merchant configuration via the `Merchant` object type. Merchant configuration queries and mutations both have two required fields for each configuration object: - `key`: The enumerator for a given configuration option: [MerchantConfigurationEnum](/api/merchant/types/enums/merchant-configuration-enum). - `value`: The value of that configuration option. For example, you can configure a default currency for your merchant. The `key` field in the configuration is `CURRENCY`. The `value` field will contain the currency code of your preferred currency. To query the `Merchant` object type, you can use the `me` keyword. Let's query the currency with the `configuration` field that takes a `key` argument: ```graphql title="GraphQL query" query { me { configuration(key: CURRENCY) { key value } } } ``` ```json title="JSON response" { "data": { "me": { "configuration": { "key": "CURRENCY", "value": "EUR" } } } } ``` You can also query multiple or even all merchant configurations with the `configurations` field. Both `configuration` and `configurations` has, in addition to `key` and `value`, subfields for the default value and the description of the configuration option. Let's list all the options: ```graphql title="GraphQL query" query { me { configurations { key description value default } } } ``` ```json title="JSON response" { "data": { "me": { "configurations": [ { "key": "UI_ALLOWED_REFERRERS", "description": "Allowed HTTP referrers for embedded UI", "value": "", "default": null }, { "key": "SENDER_NAME", "description": "Default sender name for shipments", "value": "Ny Shop's Name", "default": null }, { "key": "FORCE_DEFAULT_SENDER", "description": "Always send shipment with the default sender", "value": "true", "default": "false" }, { "key": "SENDER_EMAIL", "description": "Default sender email for shipments", "value": "example@email.com", "default": null }, ] } } } ``` You can update the merchant configuration at any time with the `updateMerchantConfiguration` mutation. It allows you to update one setting at a time. Let's change the currency to USD: ```graphql title="GraphQL mutation" mutation { updateMerchantConfiguration( input: { key: CURRENCY, value: "USD", } ) { key value } } ``` ```json title="JSON response" { "data": { "updateMerchantConfiguration": { "key": "CURRENCY", "value": "USD" } } } ``` --- ## Providers A provider is a logistics provider: a company that provides shipping and delivery, including home delivery and pickup point delivery. Delivery Gateway connects e-commerce platforms - called merchants in our system - with providers, allowing a seamless connection to all your partners via a single platform. ## Providers vs operators Providers and operators both play an important part in the Delivery Gateway ecosystem but they are quite different. Providers are the companies that ship your products: they deliver to the customer's address or to a pickup location. Operators, on the other hand, manage delivery pickup location such as parcel lockers or physical stores. A company can be a provider and an operator at the same time: for example, several providers have their own parcel locker system. ## Provider configuration :::note This section is about provider configuration via the Merchant API. For information on how to configure your merchant in the Admin dashboard, see [Provider configuration](/admin/how-tos/provider-config). ::: Delivery Gateway offers a large number of providers. After providing the right credentials, you can enable any of them to use for deliveries. You can also add custom providers. With the Merchant API, you can create and update your provider configuration via the `Provider` object type. Each provider can be configured separately, based on their `id`: ```graphql title="GraphQL query" query { providers { id name icon isEnabled isAvailable } } ``` ```json title="JSON response" { "data": { "providers": [ { "id": "Best Prov Inc" }, { "id": "Second Best Prov Inc" }, ] } } ``` Provider configuration works similarly to the merchant configuration: the `configurations` field takes a `ProviderConfiguration` object type with two required subfields: - `key`: The enumerator for a given configuration option, for example, `PICKUP_POINT_INFORMATION`. Check the available options here: [ProviderConfigurationEnum](/api/merchant/types/enums/provider-configuration-enum). - `value`: The value of that configuration option. For example, the text of the pickup point information. You can query the configuration of every provider: ```graphql title="GraphQL query" query { providers { id configurations { key value } } } ``` ```json title="JSON response" { "data": { "providers": [ { "id": "BEST_PROV", "configurations": [ { "key": "TITLE", "value": "Best Provider Inc" }, { "key": "AVAILABLE", "value": "false" }, { "key": "FORCE_AVAILABLE", "value": "false" }, { "key": "HOME_DELIVERY_AVAILABLE", "value": "true" }, { "key": "PICKUP_POINT_AVAILABLE", "value": "true" }, ] }, ] } } ``` You can also update the provider configuration using these key-value pairs with the `updateProviderConfiguration` and the `updateProviderConfigurations` types, depending on whether you want to update multiple settings. For example, here's how you can use `updateProviderConfigurations` to update two settings at the same time. The `input` field needs: - A `provider` subfield, in addition to `key` and `value`, to identify the provider. It takes an `id` value from the `Provider` object type. - An array with all the configuration options you wish to update. ```graphql title="GraphQL mutation" mutation { updateProviderConfigurations( input: [{ provider: BEST_PROV, key: AVAILABLE, value: "true", }, { provider: BEST_PROV, key: PICKUP_POINT_INFORMATION, value: "0-24 parcel locker service" }] ) { key value } } ``` ```json title="JSON response" { "data": { "updateProviderConfigurations": [ { "key": "AVAILABLE", "value": "true" }, { "key": "PICKUP_POINT_INFORMATION", "value": "0-24 parcel locker service" } ] } } ``` --- ## Sessions ## About sessions When a user tells Delivery Gateway they need a delivery, DGW creates a session. A session is the process of setting up a delivery, from selecting the delivery method to providing the user details and then confirming the delivery. - Lightweight frontend integration: When only the Delivery Gateway frontend is integrated to your e-commerce platform, our Web Plugin creates and manages sessions. - Full backend integration: Your e-commerce platform's backend is connected to the Delivery Gateway backend and uses the Merchant API to handle sessions. The full integration sequence looks like this: ```mermaid sequenceDiagram participant U as User participant FM as Frontend (merchant) participant DF as Delivery Gateway (frontend) participant BM as Backend (merchant) participant DB as Delivery Gateway (backend) U ->> FM: I need a delivery FM ->> BM: Clickreate Delivery Gateway session for user BM ->> DB: Create session DB -->> BM: Session id BM -->> FM: Session id FM ->> DF: Initialize DF ->> BM: Get delivery options BM -->> DF: U ->> FM: Set delivery details FM ->> BM: Save delivery details BM -->> FM: U ->> FM: User is ready FM ->> BM: Submit BM ->> DB: Get delivery details DB -->> BM: BM -->> FM: Save ``` ## Session ID The session ID is the main identifying information of a session. It is automatically generated whenever you create a new session. To update an existing session, you always need the session ID. ## Session details During a full session, the session is updated with the necessary information regarding one or more deliveries. It can receive default settings from the merchant configuration and provider configuration, but you can individually override each and every one of these settings during the process. For example, the currency of the session determines which currency is shown to display prices during the session. The default currency is the one specified in the merchant configuration. Similarly, you can configure the language of the session: the default value is that of the browser or OS locale. You can also update pricing for a session, overriding any of the pre-configured pricing rules. For example, you can create special promotions or offer free shipping by updating the pricing value. ### Authenticated customers A Delivery Gateway session doesn't require customer authentication: a session can be executed in a full with an anonymous user. However, authenticating a customer has several potential benefits, such as saving and reusing addresses, or offering previously selected pickup points. An authenticated customer is referred to by its reference ID. This is generated and assigned to the customer by your system. During a session, an authenticated customer can create, update, and delete their address information, including email address and phone number. ### Delivery options By default, the merchant configuration and the provider configurations determine what delivery methods and which providers are available for a session. However, you can always override these settings during a session: for example, you can enable home delivery even if it's disabled by default, or disable a provider that is otherwise available.