Libraries tagged by Service Unavailable
crowdstar/exponential-backoff
12575 Downloads
Prevent overloading an unavailable service by doubling the timeout each iteration.
m-michalis/boxnow-api
345 Downloads
Document describes the API description for partners in order to create and track delivery requests. ## Revision history |Date|Author|Description|Version| |-|-|-|-| |2024-09-26|Hoffmann, P.| Add P466 error code |1.65| |2024-09-25|Filatov, R.| Add P465 error for /api/{v1,v2}/delivery-requests:checkAddressDelivery |1.64| |2024-08-13|Hoffmann, P.| Update `shippingRegions` in /api/v1/entrusted-partners response. |1.63| |2024-07-22|Hoffmann, P.| Add `shippingRegions` and `phoneNumber` to /api/v1/entrusted-partners response. |1.62| |2024-07-11|Filatov, R.| Add P461, P462, P464 errors for ArcGIS validations to /api/v2/delivery-requests:checkAddressDelivery |1.61| |2024-07-08|Hoffmann, P.| Add `email` and `phoneNumber` to /api/v1/entrusted-partners response. Add `originContactEmail` and `originContactNumber` to /api/v1/delivery-requests:fromCsv request body |1.60| |2024-05-23|Balagazova, K.| Add lost parcel event |1.59| |2024-04-08|Hoffmann, P.| Add declareDeliveryPartnerReturn |1.58| |2024-03-15|Šmolík, J.| Add generate upload label link |1.57| |2024-02-02|Šmolík, J.| Add location id to /api/v1/parcels events |1.56| |2023-11-15|Filatov, R.| Add P422, P423, P424 error codes |1.55| |2023-11-13|Filatov, R.| Add new `/api/v2/delivery-requests:checkAddressDelivery` endpoint switched to ArcGIS |1.54| |2023-11-08|Filatov, R.| Add `customerReturnsMaxAllowedSize` for /api/v1/entrusted-partners |1.53| |2023-06-10|Filatov, R.| Add `weight` min/max validation (error cde P421) and always round it to 2 decimals on /api/v1/delivery-requests:customerReturns|1.52| |2023-05-10|Balagazova, K.| Forbid usage of `q` parameter of `api/v1/parcels` for partner server accounts |1.51| |2023-04-28|Hoffmann, P.| Remove `X-Overwrite-Date` request header from /api/v1/delivery-requests and /api/v1/entrusted-partners |1.50| |2023-04-28|Azizov, J.| Add P442 error code |1.49| |2023-04-12|Balagazova, K.|Add `limit` field and automatic ordering by distance to /api/v1/destinations |1.48| |2023-04-04|Balagazova K.| Add `showRecipientInformation` field to /api/v1/delivery-requests /api/v1/delivery-requests:fromCsv |1.47| |2023-02-23|Balagazova K.| Add customer information to the webhook message |1.46| |2022-11-29|Azizov J.| Add Webhook schema and an example endpoint |1.45| |2022-11-28|Vala J.| Add partner permission to /entrusted-partners response |1.44| |2022-11-24|Vala J.| Add partner permission `addressAsDestination`, `codAddressAsDestination`. Validate partner permission for delivery to address and cod payment use for delivery to address when creating delivery request |1.43| |2022-11-14|Vala J.| Add `X-Overwrite-Date` request header for delivery request to test Croatian currency conversion, only testeable on dev |1.42| |2022-10-21|Vala J.| Add validation error code to /api/v1/simple-delivery-requests /api/v1/delivery-requests /api/v1/delivery-requests:customerReturns |1.41| |2022-09-22|Šmolík, J.|Add accepted-to-locker parcel event |1.40| |2022-09-08|Šmolík J.| Add support for user to choose partner they want to work with |1.39| |2022-08-10|Šmolík J.| Add /labels:search to download PDF labels for defined criteria |1.38| |2022-08-08|Azizov. J.| Add `region` field to /destinations and /origins endpoints |1.37| |2022-07-27|Vala J.| Add EP for listing shipping label data of parcels order /api/v1/delivery-requests/{orderNumber}/label |1.36| |2022-07-27|Vala J.| Add EP for listing shipping label data of parcel /api/v1/parcels/{id}/label |1.35| |2022-07-22|Vala J.| Add destination_public_id column to csv export of parcels |1.34| |2022-07-08|Vala J.| Add exportCsvUrl to headers ['X-export-url-csv'] to response from /api/v1/parcelsAdd endpoint to export parcels to csv file /ui/v1/parcels.csv |1.33| |2022-06-27|Vala J.| Add width and printerModel query parameters for zpl shipping labels for /api/v1/delivery-requests/{orderNumber}/label.{type} and /api/v1/parcels/{id}/label.{type} |1.32| |2022-06-17|Šmolík, J.| Allow to select return location for delivery request |1.31| |2022-05-25|Vala, J.| Add single labelUrlPdf to headers ['X-labels-url-pdf'] in response from /api/v1/delivery-requests:fromCsv |1.30| |2022-05-25|Vala, J.| Add EP to handle csv import orders printing of shipping label /ui/v1/delivery-requests/{orderImportsNumber}/label.pdf |1.29| |2022-05-20|Vala, J.| Add possibility to overwrite 4 rows in shipping label sender info to /api/v1/delivery-requests endpoint |1.28| |2022-05-04|Azizov, J.| Add state and created filters to to /api/v1/parcels endpoint |1.27| |2022-05-03|Azizov, J.| Add possibility to search parcels to /api/v1/parcels endpoint |1.26| |2022-04-27|Azizov, J.| Add /api/v1/delivery-requests:customerReturns for customer returns delivery requests |1.25| |2022-04-26|Vala, J.| Add createTime, updateTime to parcel list response |1.24| |2022-04-21|Šmolík, J.| Add payment info to parcels |1.23| |2022-02-22|Azizov, J.| Add P408 and P409 error codes |1.22| |2022-02-22|Azizov, J.| Add notifySMSOnAccepted to DeliveryRequest |1.21| |2022-02-01|Šmolík, J.| Add check address delivery endpointAdd /api/v1/simple-delivery-requests for simpler delivery creation |1.20| |2022-01-20|Šmolík, J.| Add P405, P406 and P407 error codes |1.19| |2022-01-10|Šmolík, J.| Add CSV import endpointAdd JWT custom claims descriptionMove 403 error codes to own section |1.18| |2021-12-23|Šmolík, J.| Add new endpoint to confirm AnyAPM delivery of a parcelPartition error codes by HTTP status response |1.17| |2021-12-16|Šmolík, J.| Add new error code P403 |1.16| |2021-12-09|Šmolík, J.| Add new error codes P401, P402 |1.15| |2021-11-30|Šmolík, J.| Add delivery request origin, destination and items fields description |1.14| |2021-11-11|Šmolík, J.| Add endpoint for parcel delivery cancellation |1.13| |2021-11-09|Šmolík, J.| Add X403 error code spec |1.12| |2021-10-14|Šmolík, J.| Add Accepted for return event |1.11| |2021-10-05|Šmolík, J.| Make DeliveryRequest.items required |1.10| |2021-09-22|Šmolík, J.| Add canceled event state and event|1.9| |2021-09-17|Šmolík, J.| Add PDF label URLs to parcels response |1.8 |2021-09-13|Šmolík, J.| Update parcel state enum valuesRemove history event displayName, add type|1.7 |2021-08-25|Azizov, J.| Add possibility to print labels for all parcels in orderMake contact information of origin optional in delivery request|1.6 |2021-08-02|Azizov, J.| Add items metadata to parcel |1.5| |2021-07-15|Šmolík, J.| Add destination expected delivery time |1.4| |2021-06-23|Šmolík, J.| Update money value fields description |1.3| |2021-06-21|Šmolík, J.| Update Requesting a delivery textAdd `name` filter to origins and destinations Rename delivery request code of description to plain descriptionAdd more specific info to value amount fieldsUpdate address country to match ISO CodeUpdate address postal code formattingUpdate origin/destination for delivery requestRemove height, length, width from order itemAdd events to parcel infoUpdate delivery request responseUpdate order number descriptionAdd parcel id filter to /parcelsAdd message to errorMake contact name requiredAdd delivery partner parcel idsRemove order items' code and status |1.2| |2021-06-14|Šmolík, J.| Add a todo to specify client notification type after accepting the order. Let the partner choose to receive an email when successful delivery request is made. Remove `typeOfOrder` from delivery request.Add option to select delivery partner for pickupMake item weight in the order optionalMake origin contact email requiredAdd support to add sender's name when making delivery requestRemove landmark and code from addressAdd new error code or partners not eligible to create COD delivery requestsAdd support to filter destinations/origins by typeAdd support to send compartment size for order item, required for APM originMake `typeOfService` optional |1.1| |2021-06-09|Šmolík, J.|Initial version|1.0| # Setup Register your company through our support. We are going to need - Company name - List of Phone numbers for SMS OTP authentication of people who'll you want to have access to the Partner CMS - List of addresses for pickup points - where do we pickup your order for delivery You will get in return - `OAUTH_CLIENT_ID` - OAuth2 Client ID for authenticating with the Partner API. Keep it safe. Value may vary for each environment. - `OAUTH_CLIENT_SECRET` - OAuth2 Client Secret for authenticating with the Partner API. Keep it safe. Value may vary for each environment. - `API_URL` - Base URL for Partner API ## Environments Product offers multiple environments - Sandbox - For you to test the integration. Limited functionality. - Production - Connected to real end-users. Use with care. Environment setting summary: | Value \ Env | Sandbox | Production | |---|---|---| | `API_URL` | N/A | N/A | | `OAUTH_CLIENT_SECRET` | Contact Support | Contact Support | | `OAUTH_CLIENT_ID` | Contact Support | Contact Support | # API ## Authentication Authentication is based on OAuth2 standard, Client Credentials grant. Token endpoint `/auth-sessions`, see examples below. Client ID and Secret MUST be passed to you from BoxNow support in advance. In order to use the API, you MUST attach the access token to Authorization header as a Bearer token. ### Custom JWT claims You can find additional user information in custom claims under namespace key `https://boxnow.gr`. For example ```json { "iat": 1641980553, "exp": 1641984153, "https://boxnow.gr": { "permission": { "warehouseAsOrigin": true, "anyApmAsOrigin": true, "anyApmToSameApmDelivery": true, "anyApmToSameApmDeliveryWithoutConfirmation": true, "depotAsOrigin": true } } } ``` ## Listing available destinations You can skip this if you don't want to deliver your order to one of our APMs. Use `/destinations` to list available APM locations we can deliver the goods to. You will refer to these records by `id` when requesting delivery later on. ## What can influence `/destinations` endpoint response - Only APMs with `Box Now Ready` state are considered - APMs must be available for your required package size (see: '#/components/parameters/LocationRequiredSize') ## Requesting a delivery Create a delivery request to delivery your order to the client. Use `/delivery-requests` endpoint for this operation. Once a successful request delivery is made - (optional) we send you an email notifying about successful delivery request creation, if you choose to receive this email - you should fetch the PDF label for each of the parcel from `/parcels/{id}/label.pdf`, print it and stick it to the parcel/s - we send a courier to pick up the labeled parcel/s - we notify the client via email that we have accepted the order from you and its being delivered by us ## Modifying a delivery request After a delivery request is successfully made, you can alter some parts of it later on. Use `/delivery-requests/{id}` endpoint for these modifications. ## Checking on the deliveries You can list parcel related to your delivery requests via `/parcels` endpoint. ## Error codes ### Description of codes for `400 Bad Request` responses - `P400` - Invalid request data. Make sure are sending the request according to this documentation. - `P401` - Invalid request origin location reference. Make sure you are referencing a valid location ID from Origins endpoint or valid address. - `P402` - Invalid request destination location reference. Make sure you are referencing a valid location ID from Destinations endpoint or valid address. - `P403` - You are not allowed to use AnyAPM-SameAPM delivery. Contact support if you believe this is a mistake. - `P404` - Invalid import CSV. See error contents for additional info. - `P405` - Invalid phone number. Make sure you are sending the phone number in full international format, e.g. +30 xx x xxx xxxx. - `C404` - Invalid phone number. Make sure you are sending the phone number in full international format, e.g. +30 xx x xxx xxxx. - `P406` - Invalid compartment/parcel size. Make sure you are sending one of required sizes 1, 2 or 3. Size is required when sending from AnyAPM directly. - `P407` - Invalid country code. Make sure you are sending country code in ISO 3166-1 alpha-2 format, e.g. GR. - `P408` - Invalid amountToBeCollected amount. Make sure you are sending amount in the valid range of (0, 5000> - `P409` - Invalid delivery partner reference. Make sure you are referencing a valid delivery partner ID from Delivery partners endpoint. - `P410` - Order number conflict. You are trying to create a delivery request for order ID that has already been created. Choose another order id. - `P411` - You are not eligible to use Cash-on-delivery payment type. Use another payment type or contact our support. - `P412` - You are not allowed to create customer returns deliveries. Contact support if you believe this is a mistake. - `P413` - Invalid return location reference. Make sure you are referencing a valid location warehouse ID from Origins endpoint or valid address. - `P415` - You are not allowed to create delivery to home address. Contact support if you believe this is a mistake. - `P416` - You are not allowed to use COD payment for delivery to home address. Contact support if you believe this is a mistake. - `P417` - You are not allowed to use `q` parameter. It is forbidden for server partner accounts. - `P420` - Parcel not ready for cancel. You can cancel only new, undelivered, or parcels that are not returned or lost. Make sure parcel is in transit and try again. - `P421` - Invalid parcel weight. Make sure you are sending value between 0 and 10^6. - `P422` - Address not found. Try to call just with postal code and country. - `P423` - Nearby locker not found. - `P424` - Invalid region format. Please ensure the format includes a language code followed by a country code in ISO 3166-1 alpha-2 format, separated by a hyphen, e.g. el-GR, or region exists in context. - `P425` - Parcel not ready to declare a delivery partner return. Make sure parcel is not in any of the following states in order to declare a delivery partner return: 'canceled-return', 'lost', 'canceled', 'returned', 'expired-return'. - `P426` - Parcel not eligible to declare a delivery partner return. Parcel needs to use a delivery partner in order to declare a return. - `P430` - Parcel not ready for AnyAPM confirmation. Parcel is probably already confirmed or being delivered. Contact support if you believe this is a mistake. - `P440` - Ambiguous partner. Your account is linked to multiple partners and is unclear on whose behalf you want to perform this action. Send `X-PartnerID` header with ID of the partner you want to manage. You can get list of available Partner IDs from /entrusted-partners endpoint. - `P441` - Invalid X-PartnerID header. Value you provided for X-PartnerID header is either invalid or references partner you don't have access to. Make sure you are sending ID from /entrusted-partners endpoint. - `P442` - Invalid limit query parameter. The query limit for this API has been exceeded. Please reduce the size of your query (max allowed is 100). - `P460` - Parcel not eligible for external destination delivery. Delivery request destination.deliveryPartnerId is not set. - `P461` - Invalid street. Make sure the length is not more than 100 characters. - `P462` - Invalid city. Make sure the length is not more than 50 characters. - `P464` - Invalid postal code. Make sure the length is not more than 20 characters. ### Description of codes for `403 Forbidden` responses - `X403` - Account disabled. Your account had been disabled, contact support. - `P414` - Unauthorized parcel access. You are trying to access information to parcel/s that don't belong to you. Make sure you are requesting information for parcels you have access to. - `P465` - Partner doesn't have access for checking delivery addresses. - `P466` - You are not allowed to create a delivery request because your account has an overdue flag and you are not a vip partner. ### Description of codes for `503 Service Unavailable` responses | Code | Description | |---|---| | `P600` | Locker bridge communication failed. There has been some error when communicating with the locker bridge. Try again later or contact support. | | `P610` | Geolocation API failed. There has been some error when translating address to gps coordinates. Try again later or contact support. |
xiidea/ez-maintenance
143 Downloads
A handy library to handle site maintenance situation
kruegge82/weclapp
5 Downloads
# Getting Started API Version: [v1](v1.html) The weclapp REST API lets you integrate weclapp with other applications or services. The specification for this version can be downloaded here: | Format | Public | |---------------------------------|----------------------------------------------------------------------------------| | swagger JSON | Download | | OpenApi 3 JSON | Download | | OpenApi 3 YAML (with user docs) | Download | ## What should I know before starting? Our API is continuously being developed and improved, but we are still trying to keep it as stable as possible. We try to only have changes that are backwards compatible: usually the changes are only additions, e.g. new resources are implemented or new properties are added to existing resources. Sometimes breaking changes cannot be avoided, e.g. when a new feature requires an incompatible change to the underlying data model, all those changes will be documented in the change log. ## Security and Authentication You must be a verified user to make API requests. You can authorize against the API with an API token. The token is configurable in your weclapp account under **My settings > API**. Authentication is possible in multiple ways: If the request contains the session cookies of a logged in weclapp session then the user and permissions of that session are used. This is useful when testing the API in a web browser, because then requests are “automatically” authenticated if weclapp is used in another tab. But generally the API is not used from a browser or with session cookies, instead there is an API token for each user that can be used to authenticate requests. Each user can find his/her token on the "My Settings page". The token should be kept secret like a password. A user can also generate a new token at any time, doing that invalidates all previous tokens. Authenticating using a token is possible in two ways: * the token can be sent using the AuthenticationToken header `AuthenticationToken: {api_token}` * the standard HTTP Basic authentication can be used: the username needs to be `“*”` and the password is the token ## Using curl ```bash curl --compressed -H "AuthenticationToken:{api_token}" "https://.weclapp.com/webapp/api/v2" ... ``` Examples of how to use curl will be shown in each section of this API. ## Headers This is a JSON-only API. You must supply a `Content-Type: application/json` header on PUT and POST operations. You must set a `Accept: application/json` header on all requests. You may get a `text/plain` response in case of error, e.g. in case of a bad request, you should treat this as an error you need to take action on. To reduce traffic the weclapp API works with [compression](https://developer.mozilla.org/en-US/docs/Web/HTTP/Compression#end-to-end_compression). This means, a client should always submit the header “Accept-Encoding: gzip”. If this header is not set, the API will enforce compression and respond with "Content-Encoding: gzip". Please also make sure to set a `User-Agent` header for all automated requests, as that makes it much easier to identify misbehaving clients. ## URLs The base URL for the API is `https://.weclapp.com/webapp/api/v2/` where `.weclapp.com` is the domain of the specific weclapp instance. So each weclapp instance has its own API endpoints which allow accessing data for that particular instance. The API provides access to various resources like customers, sales orders, articles etc.. Each of those resources implements a common set of operations. The URLs and HTTP methods for the different resource operations use the same pattern for all resources: | Operation | HTTP Method | URL pattern | |-------------------------------|-------------|-----------------------------------------------------------------------| | Query/list instances | GET | `https://.weclapp.com/webapp/api/v2/` | | total number of instances | GET | `https://.weclapp.com/webapp/api/v2//count` | | Get a specific instance by id | GET | `https://.weclapp.com/webapp/api/v2//id/` | | Create a new instance | POST | `https://.weclapp.com/webapp/api/v2/` | | Update a specific instance | PUT | `https://.weclapp.com/webapp/api/v2//id/` | | Delete a specific instance | DELETE | `https://.weclapp.com/webapp/api/v2//id/` | Not all resources support all of those operations. A general description for each operation can be found in API operations by example, and details for each resource are described on the page for that resource. ## Additional operations Some resources allow further operations or actions. Those operations can be executed with a POST request, for some operations that only read data it is also possible to use a GET request (this is documented for each operation). For general operations for a resource the URL pattern is `https://.weclapp.com/webapp/api/v2//`. Some operations are instance specific, those use the following URL pattern: `https://.weclapp.com/webapp/api/v2//id//`. ## JSON | Type | Representation in JSON | |----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | string | Serialized as JSON string, empty strings (length 0 or only whitespace) are always interpreted as null, it is not possible to have a property with an empty string value. | | boolean | Serialized as `true` / `false`. | | decimal number | Most numbers in weclapp are decimal numbers with a fixed precision and scale (e.g. quantities or prices), they are serialized as JSON strings and not as JSON numbers to prevent accidental loss of precision when the JSON is deserialized with a JSON library that uses doubles to represent JSON numbers. The serialized numbers always use a “.” as the decimal mark (if one is required). | | integers | Integer numbers (that can safely be represented as a double) are serialized as JSON numbers. | | floats/doubles | Serialized as JSON numbers. | | dates and timestamps | Serialized as the milliseconds since 1970-01-01T00:00:00Z (as a JSON number). | | enums | Sometimes a property value can be one of a fixed number of named options. Those enum properties are serialized as a JSON string with the name of the option. | The deserialization of data sent to the API is relatively lenient, for example when a string is expected, but a number is given then that number is used as the string and the other way around (if possible). Properties with the value null are not serialized by default and when sending data to the API it is also not necessary to include properties whose value is null: all properties that are missing from the JSON object but are expected are assumed to be `null`. To get all properties including those with the value null the query parameter `serializeNulls` can be added to the request URL, in that case null values are included in the response. ## Error Responses Any request on the weclapp API may return an error response, with a structure conforming to [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807). See the [API error reference](#errors) section for details. ## Change Policy weclapp may modify the attributes and resources available to the API and our policies related to access and use of the API from time to time without advance notice. weclapp will use commercially reasonable efforts to notify you of any modifications to the API or policies through notifications or posts on the weclapp Developer Website. weclapp also tracks deprecation of attributes of the API on its Changelog. Modification of the API may have an adverse effect on weclapp Applications, including but not limited to changing the manner in which weclapp Applications communicate with the API and display or transmit Your Data. weclapp will not be liable to you or any third party for such modifications or any adverse effects resulting from such modifications # API newsletter Sign up here for our [API newsletter](https://340d89eb.sibforms.com/serve/MUIEAEREP3buQMWpwPwuVohmsPBikdVQIilNQeZ2DJBE5NZePFYqyp_62WSheCC5t_Q7eJ6SVpZBauqRY93L8L8Iquik5gaH40Bi0uOtPioS7U7k4JvemqVuSdvEV0A3DgygC5LOAv-kjuN4Ij5MUqzm5DSHYbmKvGucHMXpZMFGGA5Lwi5VUv6ZZbROGqZJCrGfYFxGttzVBqc_). We will inform you regularly about planned API changes. # API operations sample As mentioned previously all resources implement common operations in the same way. In the following all the common operations are explained for the `customer` resource. The operations work in the same way for all other resources (some resources don’t support all the operations), the differences between the resources are mostly the data and the properties that are required and used. ## Querying The most common operation is querying or listing the existing entity instances. This is possible with a `GET` request to the base URL of a resource: ### `GET /customer` ```bash curl --compressed -H "AuthenticationToken:" "https://.weclapp.com/webapp/api/v2/customer" ``` **Output:** ```json { "result": [ { "id": "4342", "version": "1", "addresses": [ { "id": "4344", "version": "0", "city": "München", "countryCode": "DE", "createdDate": 1496828973904, "deliveryAddress": false, "invoiceAddress": false, "lastModifiedDate": 1496828973903, "primeAddress": true, "street1": "Mustergasse 7", "zipcode": "80331 " } ], "blocked": false, "company": "Muster GmbH", "contacts": [ { "id": "4332", "version": "1", "addresses": [ { "id": "4334", "version": "0", "city": "München", "countryCode": "DE", "createdDate": 1496828882836, "deliveryAddress": false, "invoiceAddress": false, "lastModifiedDate": 1496828882836, "primeAddress": true, "street1": "Fasanenweg 15", "zipcode": "80331" } ], "createdDate": 1496828882837, "email": "[email protected]", "firstName": "Max", "lastModifiedDate": 1496828996245, "lastName": "Mustermann", "partyType": "PERSON", "personCompany": "Muster GmbH", "salutation": "MR" } ], "createdDate": 1496828973904, "currencyId": "248", "currencyName": "EUR", "customAttributes": [ { "attributeDefinitionId": "4048" } ], "customerNumber": "C1006", "customerTopics": [], "deliveryBlock": false, "insolvent": false, "insured": false, "lastModifiedDate": 1496828996212, "optIn": false, "partyType": "ORGANIZATION", "responsibleUserFixed": false, "responsibleUserId": "947", "responsibleUserUsername": "[email protected]", "salesChannel": "NET1", "useCustomsTariffNumber": false } ] } ``` In this case there is one sales order with one order item. By default, all null values are omitted, to include them the query parameter serializeNulls can be used: ### `GET /customer?serializeNulls` ```bash curl --compressed -H "AuthenticationToken:" "https://.weclapp.com/webapp/api/v2/customer?serializeNulls" ``` **Output:** ```json { "result": [ { "id": "4342", "version": "1", "addresses": [ { "id": "4344", "version": "0", "city": "München", "company": null, "company2": null, "countryCode": "DE", "createdDate": 1496828973904, "deliveryAddress": false, "globalLocationNumber": null, "invoiceAddress": false, "lastModifiedDate": 1496828973903, "postOfficeBoxCity": null, "postOfficeBoxNumber": null, "postOfficeBoxZipCode": null, "primeAddress": true, "state": null, "street1": "Mustergasse 7", "street2": null, "zipcode": "80331 " } ], "amountInsured": null, "annualRevenue": null, "birthDate": null, "blockNotice": null, "blocked": false, "commercialLanguageId": null, "company": "Muster GmbH", "company2": null, "contacts": [ { "id": "4332", "version": "1", "addresses": [ { "id": "4334", "version": "0", "city": "München", "company": null, "company2": null, "countryCode": "DE", "createdDate": 1496828882836, "deliveryAddress": false, "globalLocationNumber": null, "invoiceAddress": false, "lastModifiedDate": 1496828882836, "postOfficeBoxCity": null, "postOfficeBoxNumber": null, "postOfficeBoxZipCode": null, "primeAddress": true, "state": null, "street1": "Fasanenweg 15", "street2": null, "zipcode": "80331" } ], "birthDate": null, "company": null, "company2": null, "createdDate": 1496828882837, "customAttributes": null, "description": null, "email": "[email protected]", "fax": null, "firstName": "Max", "fixPhone2": null, "lastModifiedDate": 1496828996245, "lastName": "Mustermann", "middleName": null, "mobilePhone1": null, "mobilePhone2": null, "partyType": "PERSON", "personCompany": "Muster GmbH", "personDepartment": null, "personRole": null, "phone": null, "phoneHome": null, "salutation": "MR", "title": null, "website": null } ], "createdDate": 1496828973904, "creditLimit": null, "currencyId": "248", "currencyName": "EUR", "customAttributes": [ { "attributeDefinitionId": "4048", "booleanValue": null, "dateValue": null, "numberValue": null, "selectedValueId": null, "selectedValues": null, "stringValue": null } ], "customerCategoryId": null, "customerCategoryName": null, "customerNumber": "C1006", "customerRating": null, "customerTopics": [], "defaultHeaderDiscount": null, "defaultHeaderSurcharge": null, "deliveryBlock": false, "description": null, "email": null, "fax": null, "firstName": null, "insolvent": false, "insured": false, "invoiceContactId": null, "lastModifiedDate": 1496828996212, "lastName": null, "leadSourceId": null, "leadSourceName": null, "middleName": null, "mobilePhone1": null, "oldCustomerNumber": null, "optIn": false, "parentPartyId": null, "partyType": "ORGANIZATION", "paymentMethodId": null, "paymentMethodName": null, "personCompany": null, "personDepartment": null, "personRole": null, "phone": null, "primaryContactId": null, "responsibleUserFixed": false, "responsibleUserId": "947", "responsibleUserUsername": "[email protected]", "salesChannel": "NET1", "salutation": null, "satisfaction": null, "sectorId": null, "sectorName": null, "shipmentMethodId": null, "shipmentMethodName": null, "termOfPaymentId": null, "termOfPaymentName": null, "title": null, "useCustomsTariffNumber": false, "vatRegistrationNumber": null, "website": null } ] } ``` ## Pagination By default the operation will not return all entity instances but only the first 100, this can be changed by using the `pageSize` query parameter with the number of desired results. But `pageSize` cannot be arbitrarily high it is usually limited 1000 (exceptions to the default limits of 100 and 1000 are noted in the documentation for the specific resources). To get further results it is necessary to skip entity instances, this is done using the `page` query parameter. Examples: ### `GET /customer?pageSize=10` ```bash curl --compressed -H "AuthenticationToken:" "https://.weclapp.com/webapp/api/v2/customer?pageSize=10" ``` returns at most 10 instances ### `GET /customer?page=2&pageSize=10` ```bash curl --compressed -H "AuthenticationToken:" "https://.weclapp.com/webapp/api/v2/customer?page=2&pageSize=10" ``` returns the second page of results (the `page` parameter is one based, so `page=1` is the first page, which is also the default). Using those two parameters it is possible to implement pagination. ## Sorting It is also possible to change the order of the returned results using the `sort` parameter: ### `GET /customer?sort=lastModifiedDate` ```bash curl --compressed -H "AuthenticationToken:" "https://.weclapp.com/webapp/api/v2/customer?sort=lastModifiedDate" ``` sort by `lastModifiedDate` (ascending). ### `GET /customer?sort=-lastModifiedDate` ```bash curl --compressed -H "AuthenticationToken:" "https://.weclapp.com/webapp/api/v2/customer?sort=-lastModifiedDate" ``` sort by `lastModifiedDate` descending. ### `GET /customer?sort=lastModifiedDate,-salesChannel` ```bash curl --compressed -H "AuthenticationToken:" "https://.weclapp.com/webapp/api/v2/customer?sort=lastModifiedDate,-salesChannel" ``` sort by `lastModifiedDate` (ascending) and then `salesChannel` descending. It is generally possible to sort by most of the simple properties of an entity. It is possible to combine multiple sort orders by combining the property names with a comma. To sort in descending order just prepend a minus to the property name. If an unsupported or unknown property is specified then an error response is returned. ## Filtering It is often desired to get just a subset of the data, for example just the orders of a specific customer or created after a specific date. This is possible using filtering query parameters: ### `GET /customer?salesChannel-eq=NET1` ```bash curl --compressed -H "AuthenticationToken:" "https://.weclapp.com/webapp/api/v2/customer?salesChannel-eq=NET1" ``` customers for `salesChannel` `NET1`. ### `GET /customer?createdDate-gt=1398436281262` ```bash curl --compressed -H "AuthenticationToken:" "https://.weclapp.com/webapp/api/v2/customer?createdDate-gt=1398436281262" ``` customers created after the specified timestamp. ### `GET /customer?salesChannel-eq=NET1&createdDate-gt=1398436281262` ```bash curl --compressed -H "AuthenticationToken:" \ "https://.weclapp.com/webapp/api/v2/customer?salesChannel-eq=NET1&createdDate-gt=1398436281262" ``` customers for `salesChannel` `NET1` and created after the specified timestamp. ### `GET /customer?customAttribute4587-eq=NEW` ```bash curl --compressed -H """AuthenticationToken:" \ "https://.weclapp.com/webapp/api/v2/customer?customAttribute4587-eq=NEW" ``` customers with the value `NEW` for `customAttribute` with id 4587. ### `GET /customer?customAttribute4587.entityReferences.entityId-eq=1234` ```bash curl --compressed -H "AuthenticationToken:" "https://.weclapp.com/webapp/api/v2/customer?customAttribute4587.entityReferences.entityId-eq=1234" ``` customers with an entity reference to an entity with the id 1234 for the `customAttribute` with the id 4587. ### `GET /customAttributeDefinitions` All attributeTypes are supported except `MULTISELECT_LIST`. CustomAttributes of attributeType `LIST` could be filtered by `customAttribute{customAttributeId}.id` or `customAttribute{customAttributeId}.value`. ### `GET /customer?customAttribute3387.value-eq=OPTION1` ```bash curl --compressed -H "AuthenticationToken:" \ "https://.weclapp.com/webapp/api/v2/customer?customAttribute3387.value-eq=OPTION1" ``` customers with value `OPTION1` for `customAttribute` with id 3387. A filtering query parameter consists of a property name and a filter operator joined together with a minus. If multiple filtering query parameter are specified then they are combined and the returned results match all of them. Filtering query parameters for unknown properties or properties that don’t support filtering are silently ignored. The following filtering operators are supported (not all of them work for all property types): | Operator | Meaning | |----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | eq | equal | | ne | not equal | | lt | less than | | gt | greater than | | le | less equal | | ge | greater equal | | null | property is null (the query parameter value is ignored and can be omitted) | | notnull | property is not null (the query parameter value is ignored and can be omitted) | | like | like expression (supports `%` and `_` as placeholders, similar to SQL LIKE) | | notlike | not like expression | | ilike | like expression, ignoring case | | notilike | not like expression, ignoring case | | in | the property value is in the specified list of values, the query parameter value must be a JSON array with the values in the correct type, for example `?customerNumber-in=["1006","1007"]` | | notin | the property value is not in the specified list of values | ## "Or" condition filtering In addition to the default behavior of linking filter expressions via "and" you can also link individual filter expressions via "or" by prefixing their parameter name with "or-": ### `GET /customer?or-name-eq=charlie&or-name-eq=chaplin` ```bash curl --compressed -H "AuthenticationToken:" \ "https://.weclapp.com/webapp/api/v2/customer?or-name-eq=charlie&or-name-eq=chaplin" ``` The above example is the equivalent of the expression `(name equals "charlie") or (name equals "chaplin")` For combining `or` and `and` clauses you may also group `or` expressions by using `or-` instead of the plain `or-` prefix: ### `GET /customer?orGroup1-name-eq=charlie&orGroup1-name-eq=chaplin&orGroup2-responsibleUserUsername-eq=mrtest&orGroup2-referenceNumber=4711&commercialLanguageId-eq=12` ```bash curl --compressed -H "AuthenticationToken:" \ "https://.weclapp.com/webapp/api/v2/customer?orGroup1-name-eq=charlie&orGroup1-name-eq=chaplin&orGroup2-responsibleUserUsername-eq=mrtest&orGroup2-referenceNumber=4711&commercialLanguageId-eq=12" ``` The above example is the equivalent of the expression ``` ((name equals charlie) or (name equals chaplin)) and ((responsibleUserUsername equals "mrtest") or (referenceNumber equals "4711")) and (commercialLanguageId equals "12") ``` Technically, the default "or-" variant is just a special case of this, using the empty String as group name. ## Filter Expressions **Warning: This is still a beta feature.** In addition to individual filter properties it is also possible to specify complex filter expressions that can combine multiple conditions and express relations between properties. Example: ```bash curl --compressed -H "AuthenticationToken:" \ https://.weclapp.com/webapp/api/v2/party \ --get \ --data-urlencode 'filter=(lower(contacts.firstName + " " + contacts.lastName) = "Ertan Özdil") and (lastModifiedDate >= "2022-01-01T00:00:00Z")' ``` * "filter" parameters are ANDed with other filter parameters * Property references in filter expressions have exactly the same form and semantics as for the individual filter parameters. * Multiple "filter" parameters may be used if needed. ### Examples Some more example filter expressions: ```sql -- enum literals are specified as string literals (salesChannel in ["NET1", "NET4", "NET5"]) and (partyType = "ORGANIZATION") -- normal arithmetic operations are supported. (unitPrice + unitPrice * salesTax)
kruegge82/jtlffn
2 Downloads
# Introduction JTL-FFN is a standardized interface for fulfillment service providers and their customers. Fulfiller can offer their services to merchants and merchants can respectively choose from a wide range of service providers according to their needs. ## The ecosystem The FFN network consists of this REST API, an online portal and third party integrations (JTL-Wawi being one of them). The REST API orchestrates the interactions between the participants and the portal website provides services by JTL (such as managing and certifying warehouses of a fulfiller and merchants searching for their service providers). ## About this API The base url of this api is [https://ffn2.api.jtl-software.com/api](https://ffn2.api.jtl-software.com/api). This API (and this documentation) consists of three parts: * Fulfiller API - operations used when acting as a fulfiller in the network. Only users with the role `Fulfiller` can access these endpoints. * Merchant API - operations used when acting as a merchant in the network. Only users with the role `Merchant` can access these endpoints. * Shared API - operations available to all users. Please use the navigation menu at the top to switch between the documentation for the different APIs. # OAuth The FFN-API uses [OAuth2](https://tools.ietf.org/html/rfc6749) with the [Authorization Code Grant](https://tools.ietf.org/html/rfc6749#section-4.1) for its endpoints. Users must have an active [JTL customer center](https://kundencenter.jtl-software.de) account to authorize against the OAuth2 server. Applications and services using the API must acquire client credentials from JTL. ## Application credentials When making calls against the API, you need to do it in the context of an application. You will get the credentials for your application from JTL. Application credentials consist of the following: * `client_id` - uniquely identifies your application * `client_secret` - secret used to authenticate your application * `callback_uri` - the uri the OAuth2 server redirect to on authorization requests ## Requesting authorization When you want to authorize a user you redirect him to `https://oauth2.api.jtl-software.com/authorize` with the following query string parameters: * `response_type` - Must be set to "code" for the [Authorization Code Grant](https://tools.ietf.org/html/rfc6749#section-4.1). * `redirect_uri` - After the user accepts your authorization request this is the url that will be redirected to. It must match the `callback_uri` in your client credentials. * `client_id` - Your applications identifier from your application credentials. * `scope` - The scopes you wish to authorize (space delimited). * `state` - An opaque value that will be included when redirecting back after the user accepts the authorisation. This is not required, but is important for [security considerations](http://www.thread-safe.com/2014/05/the-correct-use-of-state-parameter-in.html). After successful authorization by the user, the OAuth2 server will redirect back to your applications callback with the following query string parameters: * `code` - The authorization code. * `state` - The state parameter that was sent in the request. ## Verifying authorization The authorization code you acquired in the last step will now be exchanged for an access token. In order to do this you need to POST a request to `https://oauth2.api.jtl-software.com/token`. >POST > >Authorization: Basic `application_basic_auth`\ >Content-Type: application/x-www-form-urlencoded > >grant_type=authorization_code&code=`code`&redirect_uri=`redirect_uri` In the Authorization header [Basic HTTP authentication](https://tools.ietf.org/html/rfc7617) is used. Your application credentials `client_id` will be used as the username and your `client_secret` as the password. The header should have the value "Basic" plus the Base64 encoded string comprising of `client_id:client_secret`. The body of the request consist of the form encoded parameters: * `grant_type` - Must be set to "authorization_code". * `code` - The authorization code received from the previous step. * `redirect_uri` - Must match the `callback_uri` in your client credentials. A successful verification request will return a JSON response with the properties: * `token_type` - is always "Bearer" * `expires_in` - the time in seconds until the access token will expire * `access_token` - the access token used for API requests * `refresh_token` - token used to get a new access_token without needing to ask the user again Now the APIs endpoints that need authorization can be called by setting the header >Authorization: Bearer `access_token` ## Refreshing authorization To get a new `access_token` (for example when the old one expired) one can POST a request to `https://oauth2.api.jtl-software.com/token`. >POST > >Authorization: Basic `application_basic_auth`\ >Content-Type: application/x-www-form-urlencoded > >grant_type=refresh_token&refresh_token=`refresh_token` The Basic HTTP Authorization works exactly as in the verification step. The body of the request consist of the form encoded parameters: * `grant_type` - Must be set to "refresh_token". * `refresh_token` - The `refresh_token` you acquired during verification. The response will be the same as in the verification step. ## Scopes Scopes allow fine grained control over what actions are allowed for a given application. During login users must approve the requested scopes, so it is often feasible to limit asking for permissions your application really needs. Global scopes for common permission scenarios are the following: * `ffn.fulfiller.read` - full read access for the fulfiller API * `ffn.fulfiller.write` - full write access for the fulfiller API * `ffn.merchant.read` - full read access for the merchant API * `ffn.merchant.write` - full write access for the merchant API More fine grained scopes can be acquired from each respective endpoints documentation. ## Example ### Prerequsites * JTL Customer center account (https://kundencenter.jtl-software.de/) * cUrl (https://curl.se/) * FFN portal account (just login here: https://fulfillment.jtl-software.com) * FFN portal sandbox account (if you want to test on sandbox: https://fulfillment-sandbox.jtl-software.com) * Oauth Client for authorization and define scopes Values in this example (access_token, refresh_token, code...) are expired and cannot be used verbatim. ### Step 1 - Create an OAuth client Navigate to https://kundencenter.jtl-software.de/oauth and create a new OAuth client. (You can´t navigate to Oauth in customer account, you should use this link, or you can change logged in index to oauth) !Templates define what scopes are possible for this client. scopes with access rights: * ffn.merchant.read - full read access for the fulfiller API * ffn.merchant.write - full write access for the fulfiller API * ffn.fulfiller.read - full read access for the merchant API * ffn.fulfiller.write - full write access for the merchant API More fine grained scopes can be acquired from each respective endpoints documentation.  Overview: clients, scopes, client-secret and client-id  In our example: * client_id: 97170e65-d390-4633-ba46-d6ghef8222de * client_secret: f364ldUw3wGJFGn3JXE2NpGdCvUSMlmK72gsYg1z * redirect_uri: http://localhost:53972/ffn/sso The values for this client should not be used in production and are for testing only. ### Step 2 - User login In this step you will redirect the user to the JTL OAuth website using his default browser. Here the user will provide his username/password and accept the requested scopes. Finally the JTL Oauth website will redirect to the provided redirect_uri and provide the code. Template: authorize specified scopes and get code answer to request the access token ``` https://oauth2.api.jtl-software.com/authorize?response_type=code&redirect_uri=[redirect_uri]&client_id=[client_id]&scope=[scopes] ``` Note: the scopes should be seperated by spaces or %20 Filled with our example values: ``` https://oauth2.api.jtl-software.com/authorize?response_type=code&redirect_uri=http://localhost:53972/ffn/sso/oauth&client_id=97170e65-d390-4633-ba46-d6ghef8222de&scope=ffn.merchant.read%20ffn.merchant.write ``` * enter password  * authorize scopes  * code answer from server  Example of the answer from the OAuth server to our redirect_uri: ``` http://localhost:53972/ffn/sso?code=def50200f3ac7aabbb6e82a6b131874115b858549dab62e73c68ea21a03de59b5744dc0f0ee321d7607062cf9bfa57471cd0ee7572db1d7b0a15779b0dda7d0ed8f8bfdb0f69939a34678d67aee41e4849d355d8aa223733ab1f397280b205fa739c6252d77d9ff600136e1b744352115fd62ba1035d8da4cbc1b6791c61d0bb621952b0a14625dd75807113ea0746e35528c304a8ce3c06724c1e1d9e1cb3709e9f52778bc8ca5b2d8f7c055f14244b1f8fcb61554c5bf48e02b882b87b9a76a43579eecd578cec97c6f603907e282e45cfec43837c063dc36b556d4974776a942f47cee19023e130ae852bfca6d3ca9c7cb3283d2bc4971f80651b626f8e7ba0ec2d13dddc4c528e1f3e470de907af7eb304d781534dd9b071d9760c9890e5756893c7800589c407bd2da3a2ff56c3fb15a410e24aa2df7ac54e8d0f7445e38e390171b58a0b66b337057d59acd29ed5bbc4df6bee921b244f030c86f49bcae21c9ca77c05eea0094414803f30089c39d585bf83604a2d9bbcc6442fbfdcff6cca946eb84d1eac2e4f98dff31a93460c951c853f9ef7140f572be963e82a3baf72afba34572af63ee7da ``` Extract the code and note it for next steps. ### Step 3 - Get an access_token from the code Template: get access token + refresh token ``` curl --location --request POST "https://oauth2.api.jtl-software.com/token" --header "Content-Type: application/x-www-form-urlencoded" -u "[client_id]:[client_secret]" --data-urlencode "grant_type=authorization_code" --data-urlencode "redirect_uri=[redirect_uri]" --data-urlencode "code=[code]" ``` Filled with our example values: ``` curl --location --request POST "https://oauth2.api.jtl-software.com/token" --header "Content-Type: application/x-www-form-urlencoded" -u "97170e64-d390-4696-ba46-d6fcef8207de:f364ldUw3wIJFGn3JXE2NpGdAvUSMlmK72gsYg1z" --data-urlencode "grant_type=authorization_code" --data-urlencode "redirect_uri=http://localhost:49420/oauth" --data-urlencode "code=def50200e6f3c65cfaba9419cbf6e48a7ed4324ef851b0ace493213884496b851fd825b90b4f994ee265a62f2358bbcbb0f990af5dbfd93dc63e51a7a6fa3bcfc7f722f56366b0a726fd1ed5df1cb926b16610fc7beb0f236e8858e86397422e3caa75d8094af8ba8ad6a93b938bd341bec1e4df671ad71ad1d5fa41166f5d4b2a3ac7d9172c35a8501f10ad722ec2aea88439c21b148ec2ba85e93c17acebe7d7f3d0118a50941cab145ed5ce92946426e5d388584556c0b010c567b433c577a1c4f7b1dfb2c99c25a0efadece4f64f19e54305bfc591e2b30b1a7ba1a33af3e039bcfa80b21ca365dc003f07989fca92472c2c8e2daab51151624a6a10bc511f2ed586f06544f7b98566df4667f5bbd6ba7c6707cb673c767c9eab5a74e63a8269688941c3158e8cc1cb5ebe9a8aa468faf415171a481ee1489b58bedb5fc329b23e0e34e76a4a500270fbebe4e1d20a0f17cebc96cd8ab3db383af746ca0699da34b4665afad30e9dde4f5f507a1dd14c73a692f06de8bafe3be81d7744dbcd8c5f7d3c767101ff5ce0556c244130c1c3fc3f53975a841c0cacebb70118f7552f50c2d2b1c421b8a21e" ``` The result will be a JSON answer with the users access_token and refresh_token as well as the expiry in seconds. ``` { "token_type":"Bearer", "expires_in":1800, "access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9. eyJhdWQiOiI5NzE3MGU2NC1kMzkwLTQ2OTYtYmE0Ni1kNmZjZWY4MjA3ZGUiLCJqdGkiOiJlOWVhN2Q0MWI1NDIzNTcyYWU0MDEzYjEzMDZiMGRkNWM3YmQ2ZTNjMDNhYTZmNjQ2M2NlMjUzNTc0ZmUyMWE3NGQyNTIyMTJhODQwMmI1ZCIsImlhdCI6MTY2MTI1MzE0OCwibmJmIjoxNjYxMjUzMTQ4LCJleHAiOjE2NjEyNTQ5NDgsInN1YiI6IjQ2MjA5Iiwic2NvcGVzIjpbImZmbi5tZXJjaGFudC5yZWFkIiwiZmZuLm1lcmNoYW50LndyaXRlIl19.eEwY021wR3BWVp-wbAVQrjfqwFbYqLlOV_ca-cb7-O3Kdpi8mkFQBxfI8rzSiV_1WpAINf4ydV9FR9Ty992SMiAqGJ3T9zDHd68oUDePeq7Xfafp-87UboI2mCfGd7518CoKVLqg5ohb4YCqgC7Dz588FofggCQyDZQSM-8raOgcM-pJ1TT7oRuYuDHsOzCOTPcX2YiGYKCc3M6kxlBy_NjrJoLa4qysLRmPkznWwj0caC7a0VJO5KubvECcMb9D7Byr3UNjI7GiGMAufa770V5qCjrWs4gOsRV-Bn7oQydvsL21qqjBKHcssQrlLZWmrcfKqgBKwfRXIx3Mu5HBCmtHjHMnuvPVEZAj6fEfIwjYSeTAHTHApEwbE7J1MPd8MU0K6X2YEUF315fXN5F3rO3ZL5FdTwcM1E-1-PKubLuMAaE6Lw-QsDtBoI4ESylomCmCCfgLV4Vj-in_oCJUmKXAX0tDSa9y9vb6oAExung_BTJCBemffCtkJ55Px7bvi9JXmwvI0pIFo3QzTUtRbFDizCMrPZvsatFx64mXX3IDoVqXr3uzvdetBIJEj2ngVdGRrKGt4Yboae5oFV2d5jdSZBL28pwGjey__ZB4zLR1DodQ0sOqDWJ3WsEjMYXU8_-IGrS8Kkw8Q0R0UqqyVLfcLr-cfH5tYqf2QLqAScY","refresh_token":"def50200e636703f8d6372401e7b5e1163e0f46e5d593f6f8a1e9b1b2777d64684b87b7c552db62f9670bc482a3958d8aafb78083c7166c13f2f233fe4623d22873c819a560dc3213a51448a1e0763c2a0f7fb7230ceeae22a7fa84717458886584ab5a0ed1a500be5f9d3ed36b1d063d39b56c8431f3fe623055626c1f99f8c5b684853965645fe5c5bee941857aef79ae4f9b994316bec9d365119fe0fe8d035218c44d00a47c0e92b4613c1f388b9c171f3d79e45a6d2a52dfbd8d25608d6b0350420155e48cc179764a2432220cc0d1e9bfa7798050d0b36fe658e967186ea75cc1d1277cad973d43a0839c50b6885a87b5b446452855a00ac75c5f6d7f62b914496e30ab89a16b335977e4363b94dda7364bb052832a5d122696b6476fb0e1631030ea3c42d9659ca839cc44919efc9532c84f7170e634d3e189eb181d0c114ed9d8150c619f7567587e0311d89d51d1325646d2c014757ba7f2d7b02f7b56a52e093ed2ea95a8abe4a0289b24a5636dce8ad01c20e8cce8c4c51263e7f1731bb6335b0e31342e2439c77ab7cce7a147e24c9be9d61d8eba216fbfd4d5be2fba3502e69000ad6e67b7230a7f924" } ``` ### Step 4 - Test the access_token Using your newly aquired access_token you can test if its working (reminder: the access_token has a limited lifetime and might be expired, in which case we would need to refresh it (see Step 5)). Template: Test communication with access token on sandbox or production (our client is for both systems) ``` curl --location --request GET "https://ffn-sbx.api.jtl-software.com/api/v1/users/current" --header "Authorization: Bearer [access_token]" ``` If you cannot retrieve the user data using this endpoint make sure you have logged into our respective portal website (sandbox, production) at least once as this triggers user creation in the system. ### Step 5 - Refresh access_token when it expires Template: Get a new access token + refresh token with the refresh token ``` curl --location --request POST "https://oauth2.api.jtl-software.com/token" --header "Content-Type: application/x-www-form-urlencoded" -u "[client_id]:[client_secret]" --data-urlencode "grant_type=refresh_token" --data-urlencode "refresh_token=[refresh_token]" ``` Filled with our example values: ``` curl --location --request POST "https://oauth2.api.jtl-software.com/token" --header "Content-Type: application/x-www-form-urlencoded" -u "97170e64-d390-4696-ba46-d6fcef8207de:f364ldUw3wIJFGn3JXE2NpGdAvUSMlmK72gsYg1z" --data-urlencode "grant_type=refresh_token" --data-urlencode "refresh_token=def50200a01c0caff50b7db271f8268e3806ab2cce8e28e25f41e5fe9167a6521b47f6ed0dd3dd2d7856e1983ae645b032cf9285e91c1ee535decb0e0ca3e52670773f2737114955267d83db0204f80233214a623fcc36de04127e1cdcda006eaf60cacfb30c80081a8c9314e20117f64639ab5e333301a10173385c1bfc660709fde0b1a3517f8030dfdba8187e53c23c9d5fe9f33c48e11a4aa41bfd9ea1291507ea1bc8c64df32bdc91c61af907c41cf0bb305cae76e68448a85ad65b0a03a23ec35a7e9cc42aadd0792b9d7d187ae028e2759a7f4a0164f94d9baca29779a702f023216631e1e777069cc2bc65fd404f4fcc5818219063beb1717afe159b8110394af9a0d245de960c227b1183d6a745819ac08d92238938da798f702f83a3faf648f07a8a6d1e694c008517fd8be2fa154aab88a3eaacb3cbb1830c4bdee018e06c7f81e68c5844213f1d02372b23a22d99ac06a860748a3db891fd71768d74470c9a5a8571058dd901c888d13cd4481d63a800322614e63d3d8e6fb109ee7e1b1e046cd086ecbc2d4d362ca662e3ac867f21168833abd7a8247b06602197b7da555361efbf07b0afed69f7a558" ``` The result will be the same format as in step 3. Refresh_tokens are only valid for a single refresh and you will get a new refresh_token every single time that you must persist. ### My token is not working! #### 404 NotFound You need to log into the respective portal website (sandbox-https://fulfillment-sandbox.jtl-software.com, production-https://fulfillment.jtl-software.com) at least once to trigger user creation. #### 403 Forbidden You might be missing scopes in your token and don't have sufficient rights. #### 401 Forbidden Incorrect Oauth method. For example, we do not support the Oauth method authorisation "client_credentials grant". The authorisation method "code grant" with user must be used.