Orders
Fetch orders
The Integration Platform handles connections to multiple remote systems and multiple remote systems can alter a record type. It is important to understand the difference between an one-to-one integration and an integration platform when handling fetching order information.
The order can be updated multiple times and all updates to the order will change the last modified date e.g.:
- new
orderStatus
- new
shippingStatus
- new
shipment
- new
payment event
This described endpoint can be used to fetch all orders, however the parameter modifiedAtOrAfter
will limit the response to all orders with a timestamp more or equal the selected timestamp. It is recommended to fetch order changes regularly and handle updates in the integrating system.
Query parameter
modifiedAtOrAfter
(Date time)
Request
$ curl \
-u '<USERNAME>':'<PASSWORD>' \
-F 'User-Agent: my-app/1.0 (YOURADDRESS@example.com)' \
-H 'X-Tenant: <TENANT CODE>' \
-H 'X-ConnectionId: <CONNECTION ID>' \
https://api.{HOSTNAME}/api/order?modifiedAtOrAfter=2020-09-24T17:23:01Z
Response
Full response omitted for brevity.
[
{
"href": "/api/order/00061e1066ab0aca7473627d3d488c86",
"localId": "00061e1066ab0aca7473627d3d488c86",
"remoteIdMap": {},
"remoteRefMap": {},
"created": "2020-09-10T10:56:10Z",
"lastModified": "2020-09-25T10:24:02Z",
...
},
{
"href": "/api/order/3fb2568eb7e165e34dd311af5550002b",
"localId": "3fb2568eb7e165e34dd311af5550002b",
"remoteIdMap": {},
"remoteRefMap": {},
"created": "2020-09-10T10:58:10Z",
"lastModified": "2020-09-25T10:24:02Z",
...
}
]
Order information
Read the section Order to understand the content in the Order. An example of important information is how prices is handled. The field called pricePerUnitExclVat
contain the paid price, any discount have already been applied. The discount amount is defined in a separate field. Check the API reference for detailed information.
All orders will be returned if modifiedAtOrAfter
is excluded.
Query for specific orders
It is possible to use the query endpoint to find orders that match certain conditions. The endpoint could be used to import orders that have a specific status and that have been changed after a specific time.
An example of this type of query is shown below. All orders that match lastModified>2020-12-22T06:24:57Z
and orderStatus="completed"
will be returned.
Check the API reference /order/query for more information about available query fields. The fields are documented in the model.
Request
$ curl \
-u '<USERNAME>':'<PASSWORD>' \
-F 'User-Agent: my-app/1.0 (YOURADDRESS@example.com)' \
-H 'X-Tenant: <TENANT CODE>' \
-H 'X-ConnectionId: <CONNECTION ID>' \
https://api.{HOSTNAME}/api/order/query \
-XPOST \
-d \
'{
"filter": {
"type": "and",
"subclauses": [
{
"type": "gt",
"field": "lastModified",
"value": {
"type": "datetime",
"value": "2020-12-22T06:24:57Z"
}
},
{
"type": "eq",
"field": "orderStatus",
"value": {
"type": "str",
"value": "completed"
}
}
]
}
}'
Response
An array of orders. Full response omitted for brevity.
[
{
"localId": "0006463d034d595774bf76d0311a21be",
"remoteId": "x",
...
},
{
"localId": "3fb2568eb7e165e34dd311af5550002b",
"remoteId": "y",
...
}
]
Create a sales order
Read the section Record types -> Order before continuing.
A sales order is created as an order with the orderType: "sale"
.
The full content of the order is described in API references Order. Below are some important notes to help when creating and verifying an order.
- VatRates/taxes
- Test to create an order that contains order rows with different vat rates e.g 25%, 12% … and use the field
perUnitTaxes
. - Discount
- Test to represent an order from a purchase with a percent discount and one with a fixed amount discount. Note that Sharespine handles both types of discounts as amounts. The discount can be added on each orderrow as rowDiscountExclTax OR as a separate row with rowtype “discount”.
- orderRows->pricePerUnitExclTax
- Note the description of the field:
The price PAID per unit without tax. This is after all discounts have been applied and is thus the actual to-pay price
. Tip: Create a test order with qty>1, use a discount and verify that all values are correct. - vatType
- Read Tax model field descriptions
- orderRows->rowType
- Test that the correct order row type is used.
- source
- This section will contain the source of the order i.e the system that created the order. The field
code
within thesource
section can be used to add information about “sales channel” in the external system. Use the fieldcode
if it is applicable. - Order status
- Read Order status fields
- Shipment
- Shipment contains information about planned/shipped packages. See Add shipment
- Payment information
- The information is saved as payment events. The information is needed to allow capture of payment from a third party system or for automatic bookkeeping of payment related data. See Add payment information and Payments
Request
$ curl \
-u '<USERNAME>':'<PASSWORD>' \
-F 'User-Agent: my-app/1.0 (YOURADDRESS@example.com)' \
-H 'X-Tenant: <TENANT CODE>' \
-H 'X-ConnectionId: <CONNECTION ID>' \
https://api.{HOSTNAME}/api/order \
-XPOST \
-d \
'{
"orderTime": "2021-05-19T10:10:10Z",
"customerType": "person",
"vatType": "DomesticVendorResponsible",
"currency": "SEK",
"orderType": "sale",
"orderNo": "10001",
"totalSumExclTax": {
"currency": "SEK",
"amount": "80.00"
},
"totalTax": {
"currency": "SEK",
"amount": "20.00"
},
"billingAddress": {
"name": {
"firstName": "Test",
"lastName": "Person"
},
"street": "Gatan",
"zipCode": "12345",
"city": "Staden",
"country": "SE",
"phoneNumbers": [
{
"type": "mobile",
"number": "+46701234567"
}
],
"emailAddress": "test@example.com",
},
"shippingAddress": {
"name": {
"firstName": "Test",
"lastName": "Person"
},
"street": "Gatan",
"zipCode": "12345",
"city": "Staden",
"country": "SE",
"phoneNumbers": [
{
"type": "mobile",
"number": "+46701234567"
}
],
"emailAddress": "test@example.com",
}
},
"orderRows": [
{
"rowType": "product",
"sku": "1",
"title": "T-Shirt - XS / Blue",
"qty": "1",
"pricePerUnitExclTax": {
"currency": "SEK",
"amount": "80.00"
},
"perUnitTaxes": [
{
"taxType": "vat",
"taxableAmount": {
"currency": "SEK",
"amount": "80.00"
},
"tax": {
"currency": "SEK",
"amount": "20.00"
}
}
]
}
]
}'
Update order rows
There are several options to update order rows. Choose the best options for your use case.
- Update one specific order row by using the endpoints
PUT /order/{localId}/orderrow/{orderrowlocalId}
orPUT /order/by-remote-id/orderrow/by-remote-id
. - Update one or more order rows by using the endpoints
PUT /order/{localId}/orderrow
orPUT /order/by-remote-id/orderrow
. Send an array with order rows that should be updated.- matchLocalId or matchRemoteId for the order row is required. The id are used to identify order row to update.
- row should contain the updated data
- the endpoints above can not be used to add new order rows.
- Replace all order rows by using the endpoints
PUT /order/{localId}
orPUT /order/by-remote-id
.- all existing order rows will be replaced with the order rows send in the request. It is however possible to update the order without affecting the order rows by excluding the
orderRows
-field from the request.
- all existing order rows will be replaced with the order rows send in the request. It is however possible to update the order without affecting the order rows by excluding the
Find the endpoints at API references - Orders
Add tracking information
A common use case is when an external part need order information to fulfill the order. The order will be fetched from the Integration Platform, processed and shipped to the customer. The external system wants to update the order with tracking information. This article will show an example on how that can be done through the API.
The workflow in this example is:
- Fetch the order from the Integration Platform
- Handle the order in the external system
- Ship the order to the customer
- Add a shipment to the order
- Update the order status, shipping status
Fetch order
The order should be fetched from the Integration Platform which can be done by the method described in Fetch orders. The response will contain all matching orders, save the localId for each order. The localId
can be used in the next call when adding the shipment.
Add a shipment
In this example we will only add a tracking code and a tracking uri. The Integration Platform stores tracking information as a shipment connected to the order. The shipment can be sent to any remote system that have shipment support in the Integration Platform.
Request
$ curl \
-u '<USERNAME>':'<PASSWORD>' \
-F 'User-Agent: my-app/1.0 (YOURADDRESS@example.com)' \
-H 'X-Tenant: <TENANT CODE>' \
-H 'X-ConnectionId: <CONNECTION ID>' \
https://api.{HOSTNAME}/api/order/{localId}/shipment \
-XPOST \
-d \
'{
[
{
"trackingCode": "Trackingcode test",
"trackingUri": "https://tracking.example.com"
}
]
}'
You can also use /order/by-remote-id/shipment?remoteId={the order remoteId}
.
Update status
The order should probably be updated when it has been shipped to the customer. The order can have an order status, payment status and a shipping status. In this example we will update the order status and the shipping status.
The current available status values for orderStatus
and shippingStatus
can be found in the API reference, check the model for OrderEdit.
$ curl \
-u '<USERNAME>':'<PASSWORD>' \
-F 'User-Agent: my-app/1.0 (YOURADDRESS@example.com)' \
-H 'X-Tenant: <TENANT CODE>' \
-H 'X-ConnectionId: <CONNECTION ID>' \
https://api.{HOSTNAME}/api/order/{localId} \
-XPUT \
-d \
'{
[
{
"orderStatus": "complete",
"shippingStatus": "fully-shipped"
}
]
}'
You can also use /order/by-remote-id?remoteId={the order remoteId}
.
Response
Full response omitted for brevity.
{
"orderStatus": "complete",
"shippingStatus": "fully-shipped",
...
}
Add payment information
An order contains payment information that includes:
- Payment method.
- Payment transaction.
- Payment transaction events.
Read the section Record types -> Order and Payments before continuing.
Payment Method
A payment method is an entity in the Integration Platform and can be created through the API see API reference. Use an existing payment method or create a new one and save the localId
.
Request
$ curl \
-u '<USERNAME>':'<PASSWORD>' \
-F 'User-Agent: my-app/1.0 (YOURADDRESS@example.com)' \
-H 'X-Tenant: <TENANT CODE>' \
-H 'X-ConnectionId: <CONNECTION ID>' \
https://api.{HOSTNAME}/api/payment/method \
-XPOST \
-d \
'{
[
{
"remoteId": "checkout_provider",
"name": "Checkout provider",
"notes": "Some text"
}
]
}'
Response
Full response omitted for brevity.
{
"remoteId": "checkout_provider",
"name": "Checkout provider",
"notes": "Some text",
...
}
Payment transaction
A payment transaction is started by a prepare
event in the Integration Platform and is mandatory. A prepare
event could be created when a payment is reserved by the payment provider. A prepare
event is added to an order, and it also contains a payment method.
A common transaction event sequence is:
prepare
Reserve payment.payment
Capture/finalize payment.deposit
Payout from the PSP.
Another possible transaction sequence is:
prepare
Reserve payment.payment
Capture/finalize payment.deposit
Payout from the PSP.credit
Payment to the customer is credited.refund
A refund to the PSP since the payout was done before the credit.
All transaction events after prepare
is added by a POST
to the endpoint /payment/transaction/{localId}/event/
Create prepared payment transaction
Request
$ curl \
-u '<USERNAME>':'<PASSWORD>' \
-F 'User-Agent: my-app/1.0 (YOURADDRESS@example.com)' \
-H 'X-Tenant: <TENANT CODE>' \
-H 'X-ConnectionId: <CONNECTION ID>' \
https://api.{HOSTNAME}/api/order/{localId}/payment \
-XPOST \
-d \
'{
"type": "prepare",
"eventTime": "2015-01-02T03:04:05Z",
"paymentMethodId": "3fb2568eb7e165e34dd311af5550002b",
"correlationId": "{Unique id for the transaction (created by the payment service provider)}",
"correlationOrderNo": "string",
"comment": "string",
"amount": {
"currency": "SEK",
"amount": "100.00"
},
"feeExclTax": {
"currency": "SEK",
"amount": "4.00"
},
"feeTaxes": [
{
"taxType": "vat",
"label": "string",
"percentage": "25.00",
"taxableAmount": {
"currency": "SEK",
"amount": "4.00"
},
"tax": {
"currency": "SEK",
"amount": "1.00"
}
}
]
}'
More details can be found in the API reference in the section Payment Transaction -> events.
Add payment event
Request
$ curl \
-u '<USERNAME>':'<PASSWORD>' \
-F 'User-Agent: my-app/1.0 (YOURADDRESS@example.com)' \
-H 'X-Tenant: <TENANT CODE>' \
-H 'X-ConnectionId: <CONNECTION ID>' \
https://api.{HOSTNAME}/api/payment/transaction/{localId}/event/ \
-XPOST \
-d \
'{
"type": "payment",
"eventTime": "2015-01-02T03:04:05Z",
"amount": {
"currency": "SEK",
"amount": "100.00"
},
"feeExclTax": {
"currency": "SEK",
"amount": "4.00"
},
"feeTaxes": [
{
"taxType": "vat",
"label": "string",
"percentage": "25.00",
"taxableAmount": {
"currency": "SEK",
"amount": "4.00"
},
"tax": {
"currency": "SEK",
"amount": "1.00"
}
}
]
}'
Create a return order
Read the section Record types -> Order before continuing.
A return order is created as an order with the orderType: "return"
and the field returnedOrder
which refer to the original sales order within the Integration Platform.
The field returnedOrder
is mandatory for returns.
The example below shows a return of the product T-Shirt - XS / Blue
with the pricePerUnitExclTax
80 SEK. The pricePerUnitExclTax
can be set to the same value (or lower) as was set on the original sales order.
Request
$ curl \
-u '<USERNAME>':'<PASSWORD>' \
-F 'User-Agent: my-app/1.0 (YOURADDRESS@example.com)' \
-H 'X-Tenant: <TENANT CODE>' \
-H 'X-ConnectionId: <CONNECTION ID>' \
https://api.{HOSTNAME}/api/order \
-XPOST \
-d \
'{
"orderTime": "2021-05-19T10:10:10Z",
"customerType": "person",
"currency": "SEK",
"orderType": "return",
"orderNo": "10001",
"returnedOrder": {
"localId": "0008329ba79e98a8799e5c0d48cc25f9"
},
"totalSumExclTax": {
"currency": "SEK",
"amount": "80.00"
},
"totalTax": {
"currency": "SEK",
"amount": "20.00"
},
"orderRows": [
{
"rowType": "product",
"sku": "1",
"title": "T-Shirt - XS / Blue",
"qty": "1",
"pricePerUnitExclTax": {
"currency": "SEK",
"amount": "80.00"
},
"perUnitTaxes": [
{
"taxType": "vat",
"taxableAmount": {
"currency": "SEK",
"amount": "80.00"
},
"tax": {
"currency": "SEK",
"amount": "20.00"
}
}
]
}
]
}'