JTL Wawi

JTL Wawi is an ERP system designed for small and medium-sized businesses, especially those operating online stores. It integrates with multiple sales channels, manages inventory, orders, shipping, and offers financial reporting and customizability.

Features summary

The platform integration with JTL Wawi offers the following features:

  • Search order: Allow consumers to find their order in the Returnless return form.
  • Create return: Returns are processed directly within JTL Wawi. This feature is available in JTL Wawi 1.10.10 or later.

The integration with JTL Wawi is only available from version 1.9.0 and higher.

How to install

The connection with JTL Wawi is set up via the JTL Wawi API. In order for the Returnless platform to be able to reach the API, some steps are required.

Get a JTL API pilot program license

The API of JTL Wawi is currently in Open-Beta-Phase. This means a pilot program license is needed. To get this license, follow the steps provided in the Lizenz für JTL-Wawi API buchen guide.

Start API-REST server

Once you have arranged the API pilot program license, the API-REST server can be set up. To do so, follow the steps provided in the API-REST-Server starten guide.

In the API tool, select the correct profile. When setting the IP address, make sure to select the Lokale IP-Adresse des Rechners option. The port can be set to the default.

Expose the API

With the API server started, the API should be exposed so that other platforms outside of your JTL server are able to communicate with it. To do so, make sure the port you provided in the Start API-REST server step is made available to the network in the Firewall settings of your JTL server.

The API should be reachable via a URL. Make sure to save this URL as you will need it in the next step.



If you need more information regarding the REST API of JTL, we can also suggest to watch this video:



Connect your JTL Wawi to Returnless

With the API set up and exposed, the connection between Returnless and JTL Wawi can be set up. Follow the below steps:

  1. In your JTL server, open the new interface (Beta) of JTL-Wawi. If you cannot find the icon on your desktop, open JTL-Wawi via the program path C:/Program Files (x86)/JTL-Software/JTL-SharpWawi.exe    .

  2. Log in to the Returnless panel and navigate to Settings > Integrations page.

  3. Click on the Add new integration button in the e-commerce platform section.
  4. Select the JTL Wawi integration. A modal will open, which will guide you through the connection steps.!
  5. In step 1, specify a title and description for the integration. Also provide the API URL which you saved in the Expose the API step. Once provided, click next.jtl-wawi-step1.png
  6. In step 2, the app registration flow is started. In JTL Wawi (Beta) you can open it by going to Admin > JTL Wawi API > App-Registrierungen.

    By clicking on Hinzufugen > Weiter you should see the following screen:

  7. Proceed to step 3 in Returnless. In JTL you will see the following screen:

  8. When proceeding in JTL, the scopes will be shown. The required scopes are already marked for your convenience. The optional scopes can be enabled. We recommend to select all optional scopes so that your integration will contain all newest features when new features are added.

  9. Complete the steps in JTL Wawi. Once the JTL Wawi flow is completed, click on Verify integration in Returnless. The integration is now set up.

General settings

After the integration is set up, the version of your JTL Wawi is shown in the platform version setting. If this version is not shown, make sure to click on Refresh integration data.

How to use features

By default, all features will be disabled for the integration. Make sure to activate the features you wish to use.

Activate features

In order to start using a feature, make sure to enable the integration in a return form.

To view the feature settings, follow these steps:

  1. Login to your Return panel
  2. Navigate to Settings > Return forms and open the settings of the applicable return form.
  3. Go to the Integrations tab.

Here you will be able to define the default search integration and enable features.

Default search integration

Only a single integration will be used as the main source for the orders. If consumers need to look up the order in JTL Wawi, make sure to set this in the default search integration setting. Doing this will automatically enable the Search order feature in the integration features overview for the integration.

Enable features

Other features can be toggled in the same overview. Scroll down to the JTL Wawi section. Here you will see all available features and whether they are on or off. If you want to enable or disable a feature you can change it here and then click on Save.

Search order

only available with JTL Wawi version 1.9.0.0 and up

With the search order feature, consumers will be able to find their order in the Returnless return form by using their order number.

As the JTL Wawi integration does not have support for images yet, consumers will not be able to see product images in the return form when using this integration as the default search integration.

Search order settings

Setting Description Options
Validation method What field should the consumer fill in when looking up the order Email address, Postal code
Order search field Which field in JTL Wawi represents the order number that is known by the consumer. External order number, Order number
Allowed item types Which item types will be shown in the return form. The selected item types will be shown. Any item that does not have the given item type, will not be shown in the return form. item (default), Blank, Shipping, Coupon , Voucher, Payment, Shipping surcharge, New customer coupon, Cash on Delivery, Shipping surcharge item, Packing, Gift for free, Trusted shops, Interest premium, Processing fee, Carton, Return delivery, Multi purpose voucher, Multi purpose voucher digital, Single purpose voucher, Single purpose voucher digital, Single purpose voucher redemption

Create return


Important: When using JTL Wawi 1.10 in combination with fulfilment network, the create return  action can trigger a bug in JTL Wawi that will cause a problem with syncing data between JTL Wawi and Fulfilment network. This issue has been resolved in JTL Wawi version 1.11. We strongly advise to update to JTL Wawi 1.11 before using the create return feature when also using fulfilment network.


To start using the create return feature, JTL Wawi 1.10.10.0 or later is required. If you previously connected your JTL Wawi with a version that is lower than 1.10.10, you need to set up the integration again so that the correct scope can be provided.

The create return feature creates a return in JTL for all items that have a Qty received that is higher than 0. When triggering the feature again, a new return will be created which does not consider the previously created return.

The created return will get status Announced and be linked to a Warehouse in JTL Wawi. To make sure the correct warehouse is linked, a mapping is provided.

The return reasons for each item in the return will be mapped to the return reasons in JTL Wawi. A mapping is provided in the settings to make sure the correct return reason is used.

Create return settings

Setting Description Options
Default warehouse The warehouse that should be passed to which the return is being sent as the default when the mapping is not set up. A list of warehouses that have been set up in JTL Wawi
Default return reasons Which return reason should be passed in the created return as the default when the mapping is not set up. A list of return reasons that have been set up in JTL Wawi

If the warehouses or return reasons in your JTL Wawi have changed, click Refresh integration data to fetch the current available warehouses and return reasons in JTL Wawi.

Mapping

It is possible to map a specific return address, return reason and return status to the counterpart in JTL Wawi. For this, a mapping is provided. If the mapping record is empty, the default setting is used as fallback.

Status update JTL > Returnless

With the status update feature, whenever a return statuses changes in JTL Wawi, the status of the associated return in Returnless will be updated. This is useful when you want to use JTL WMS for handling the package in the warehouse, but want to use Returnless to handle the refund flow. To use this feature, follow the steps below.

  1. Go to your platform integrations (Settings > integrations) and click on the JTL integration
  2. In the Mapping section, click on Return statuses and map assign which JTL status should be set to which Returnless status.
  3. Scroll down to the Webhook URL section. Here, a webhook URL is shown. Make sure to store this as you will need it again in step 7.
  4. Next, a workflow needs to be created in JTL Wawi. To do this, execute an SQL query in your JTL Wawi database. The query can be found below step 8.
  5. Open your JTL Wawi. In the top menu, navigate to Returns > Return status/Returns workflows

  1. In the overview, your return statuses are shown. For each return status, a workflow section exists. Click on the workflow section. Here you should see a workflow called GeneratedWebHook. Click on it.
  2. In the Actions section of the workflow, an event is shown (web request). Change the URL of that action to the Webhook URL you copied in step 3.
  3. Repeat step 6 and 7 for each return status that needs to be updated in Returnless as well.

Database query for step 3


IMPORTANT: this query is provided by JTL and should be considered as an example. Executing this query on your database is at your own risk.


Before executing the query, make sure a back-up is created of the database.

DELETE FROM dbo.tOptions
WHERE cKey = 'Workflow.WebhookUrl';
 
INSERT INTO dbo.tOptions (
    cKey,
    cValue
)
VALUES (
    N'Workflow.WebhookUrl',
    N'<URL>'
);
 
 
IF EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'CustomWorkflows._CreateWorkflowForStatus') AND type IN (N'P', N'PC'))
    DROP PROCEDURE CustomWorkflows._CreateWorkflowForStatus;
 
CREATE PROCEDURE CustomWorkflows._CreateWorkflowForStatus
    @kRMStatus INT
AS
BEGIN
    SET NOCOUNT ON;
 
    DECLARE
        @nEvent     INT,
        @kWorkflow  INT,
        @XmlContent XML,
        @nextPos    INT;
 
    SET @XmlContent = N'
<jtlAktion xmlns="jtlCore.Workflows.Aktionen"
           xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:a="http://schemas.datacontract.org/2004/07/jtlCore.Workflows.Aktionen"
           i:type="a:jtlAktionWebRequest">
  <CancelOnError>false</CancelOnError>
  <WawiVersion>1.10.12.0</WawiVersion>
  <a:Parameters i:nil="true" />
  <a:UseDotLiquidParameters>false</a:UseDotLiquidParameters>
  <a:Body>{% capture query -%}
SELECT specversion,
       type,
       source,
       id,
       time,
       datacontenttype,
       apiVersion,
       data
FROM CustomWorkflows.ReturnStatusUpdatedEvent
WHERE cRetoureNr = ''{{ Vorgang.Retourennummer }}''
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER;
{% endcapture -%}
{{ query | DirectQueryScalar }}</a:Body>
  <a:Header>Content-Type: application/json</a:Header>
  <a:Method>2</a:Method>
  <a:NodePath />
  <a:SetWert>false</a:SetWert>
  <a:UriString>{% capture query -%}
SELECT cValue FROM dbo.tOptions WHERE cKey =''Workflow.WebhookUrl''
{% endcapture -%}
{{ query | DirectQueryScalar }}</a:UriString>
  <a:UseDotLiquidBody>true</a:UseDotLiquidBody>
  <a:UseDotLiquidHeader>true</a:UseDotLiquidHeader>
  <a:UseDotLiquidUriString>true</a:UseDotLiquidUriString>
  <a:WaitForResponse>false</a:WaitForResponse>
  <a:WriteHeaderValues>false</a:WriteHeaderValues>
</jtlAktion>';
 
    BEGIN TRY
        BEGIN TRANSACTION;
 
        -- 2.1 Determine or assign nEvent
        SELECT @nEvent = rwf.nEvent
        FROM dbo.tRMStatus AS s
        JOIN dbo.tRMStatusWorkflow AS rwf
          ON rwf.kRMStatus = s.kRMStatus
        WHERE s.kRMStatus = @kRMStatus;
 
        IF @nEvent IS NULL
        BEGIN
            SELECT @nEvent = ISNULL(MAX(nEvent), 0) + 1
            FROM dbo.tRMStatusWorkflow;
        END
 
        -- 2.2 Early exit: existing webhook action?
        SELECT TOP 1 @kWorkflow = rw.kWorkflow
        FROM dbo.tRMStatusWorkflow AS rw
        JOIN dbo.tWorkflowAktion  AS wa
          ON wa.kWorkflow = rw.kWorkflow
        WHERE rw.kRMStatus = @kRMStatus
          AND rw.nEvent    = @nEvent
          AND wa.cName     = '#GeneratedWebHook#';
 
        IF @kWorkflow IS NOT NULL
        BEGIN
            COMMIT TRANSACTION;
            SELECT @kWorkflow AS kWorkflow;
            RETURN;
        END
 
        -- 2.3 Insert into tWorkflow
        INSERT INTO dbo.tWorkflow (
            cName, nEvent, nObjekt, nVerknuepfung, nPos, nTyp, nApplikation,
            nSchedulerOptions, dtSchedulerTime, nSchedulerHour, nSchedulerMinute,
            nSchedulerDayValue, nSchedulerMonthValue
        )
        VALUES (
            'CallWebhook',
            @nEvent,
            15,
            0,
            2,
            0,
            15,
            0,
            NULL,
            0,
            0,
            0,
            0
        );
 
        SET @kWorkflow = SCOPE_IDENTITY();
 
        -- 2.4 Map status → workflow if new
        IF NOT EXISTS (
            SELECT 1
            FROM dbo.tRMStatusWorkflow
            WHERE kRMStatus = @kRMStatus
              AND nEvent    = @nEvent
              AND kWorkflow = @kWorkflow
        )
        BEGIN
            INSERT INTO dbo.tRMStatusWorkflow (
                kRMStatus, kWorkflow, nTyp, nEvent
            )
            VALUES (
                @kRMStatus,
                @kWorkflow,
                1,
                @nEvent
            );
        END
 
        -- 2.5 Determine next action position
        SELECT @nextPos = ISNULL(MAX(nPos), -1) + 1
        FROM dbo.tWorkflowAktion
        WHERE kWorkflow = @kWorkflow;
 
        -- 2.6 Insert the webhook action
        INSERT INTO dbo.tWorkflowAktion (
            kWorkflow, xXmlObjekt, nPos, cName
        )
        VALUES (
            @kWorkflow,
            @XmlContent,
            @nextPos,
            '#GeneratedWebHook#'
        );
 
        COMMIT TRANSACTION;
        SELECT @kWorkflow AS kWorkflow;
        RETURN;
 
    END TRY
    BEGIN CATCH
        ROLLBACK TRANSACTION;
        THROW;
    END CATCH
END;
 
IF OBJECT_ID('CustomWorkflows.ReturnStatusUpdatedEvent', 'V') IS NOT NULL
    DROP VIEW CustomWorkflows.ReturnStatusUpdatedEvent;
 
CREATE VIEW CustomWorkflows.ReturnStatusUpdatedEvent
AS
SELECT
    '1.0'                                                   AS specversion,
    'de.jtl-software.retoure.status.updated'                AS type,
    'Wawi'                                                  AS source,
    CAST(t.kRMRetoure AS VARCHAR(36))                       AS id,
    FORMAT(                                                 
        SYSDATETIMEOFFSET(),
        'yyyy-MM-dd''T''HH:mm:ss.fffK'
    )                                                       AS time,
    'application/json'                                      AS datacontenttype,
    '1'                                                     AS apiVersion,
    JSON_QUERY(
      (
        SELECT
          t2.kRMRetoure       AS Id,
          t2.kRMStatus        AS StateId,
          t2.kKunde           AS CustomerId,
          t2.cRetoureNr       AS Number,
          t2.cExternalNumber  AS ExternalNumber
        FROM dbo.tRMRetoure AS t2
        WHERE t2.kRMRetoure = t.kRMRetoure
        FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
      )
    )                                                       AS data,
    t.cRetoureNr                                            AS cRetoureNr
FROM dbo.tRMRetoure AS t;
 
DECLARE @kRMStatus INT;
 
DECLARE status_cursor CURSOR LOCAL FAST_FORWARD FOR
    SELECT kRMStatus
    FROM dbo.tRMStatus
    WHERE kRMStatus NOT IN (
        SELECT RmStatus.kRMStatus
        FROM dbo.tRMStatus AS RmStatus
        LEFT JOIN dbo.tRMStatusWorkflow AS RmWorkflow
          ON RmWorkflow.kRMStatus = RmStatus.kRMStatus
          AND RmWorkflow.nTyp = 1
        LEFT JOIN dbo.tWorkflow AS Workflow
          ON Workflow.kWorkflow = RmWorkflow.kWorkflow
        LEFT JOIN dbo.tWorkflowAktion AS Aktion
          ON Aktion.kWorkflow = Workflow.kWorkflow
          AND Aktion.cName = '#GeneratedWebHook#'
        WHERE Aktion.cName IS NOT NULL
    );
 
OPEN status_cursor;
FETCH NEXT FROM status_cursor INTO @kRMStatus;
 
WHILE @@FETCH_STATUS = 0
BEGIN
    EXEC CustomWorkflows._CreateWorkflowForStatus @kRMStatus;
    FETCH NEXT FROM status_cursor INTO @kRMStatus;
END
 
CLOSE status_cursor;
DEALLOCATE status_cursor;
 
IF OBJECT_ID('dbo.trg_RMStatus_AfterInsert', 'TR') IS NOT NULL
    DROP TRIGGER dbo.trg_RMStatus_AfterInsert;
 
CREATE TRIGGER dbo.trg_RMStatus_AfterInsert
ON dbo.tRMStatus
AFTER INSERT
AS
BEGIN
    SET NOCOUNT ON;
 
    DECLARE @kRMStatus INT;
 
    DECLARE status_cursor CURSOR LOCAL FAST_FORWARD FOR
        SELECT kRMStatus
        FROM inserted;
 
    OPEN status_cursor;
    FETCH NEXT FROM status_cursor INTO @kRMStatus;
 
    WHILE @@FETCH_STATUS = 0
    BEGIN
        EXEC CustomWorkflows._CreateWorkflowForStatus @kRMStatus;
        FETCH NEXT FROM status_cursor INTO @kRMStatus;
    END
 
    CLOSE status_cursor;
    DEALLOCATE status_cursor;
END;

Automatic refund of returns

In order for refunds to be automatically created for returns, a workflow can be set up in JTL Wawi. This workflow will create a refund for all returns that have been created by Returnless using the Create return action.

To set up the workflow, follow these steps which have been provided by JTL:


IMPORTANT: these queries have been provided by JTL and should be considered as an example. Executing the queries on your database is at your own risk.


Before executing the queries, make sure a back-up is created of the database.

  1. Execute query 1
USE [eazybusiness]
GO
/****** Object:  StoredProcedure [CustomWorkflows].[spRetoureGutschreiben]    Script Date: 12.12.2025 11:57:43 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [CustomWorkflows].[spRetoureGutschreiben]
@kRMRetourePos INT
AS
BEGIN
   UPDATE dbo.tRMRetourePos
   SET    dbo.tRMRetourePos.nGutschreiben = 1
   WHERE  dbo.tRMRetourePos.kRMRetourePos= @kRMRetourePos;
END
  1. execute query 2
INSERT INTO CustomWorkflows.tWorkflowObjects
(
   nObjekt,
   cName,
   cPkColumn
)
VALUES
(   14,   -- nObjekt - int
   N'RetourenPos', -- cName - nvarchar(100)
   N'kRMRetourePos'  -- cPkColumn - nvarchar(100)
   )
  1. Restart JTL-Wawi completely after running the SQL queries
  2. Navigate to Return Workflow Settings. In JTL-Wawi, go to Retoure > Retourenstatus / Retouren Workflow  . Then, select the desired status (e.g., Eingetroffen or Erledigt).
  3. Click on the Workflow tab and create a new workflow. Define the trigger (status change) and add conditions if desired.
  4. Add the action to create an invoice under RetourenPosition  
  5. Activate and Save the workflow
Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.

Still need help? Contact Us Contact Us