Creating Orders
12 minute read
What you’ll learn
In this article you’ll learn how to use the GraphQL orderCreate
mutation, specifically, you’ll learn:
- The typical way operators integrate into Marketplacer
- High-level anatomy of an order
- How to use the
orderCreate
mutation along with some tips and tricks - How to apply adjustments (custom fees and promotions)
The Connected Pattern
The typical pattern employed by a marketplace operator building an integration into Marketplacer (referred to as the Connected Pattern) involves “connecting” an existing frontend eCommerce platform with Marketplacer.
For context the primary responsibilities of each solution component, include, but are not limited to:
Marketplacer | Connected Integration | eCommerce |
---|---|---|
Host products created by Sellers | Facilitate the movement of products from Marketplacer to the eCommerce domain | Surface products for customers to buy |
Surface orders for sellers to action | Facilitate the movement of orders from the eCommerce domain to Marketplacer | Accept and process payments Create orders in Marketplacer |
For a more detailed overview of the Connected Pattern, the following resources may be of use:
- Connected Integration overview video
- Connected Integration Playbook.
The focus of this article is the use of the orderCreate
mutation, which allows for the direct creation of orders (post payment) on Marketplacer for downstream sellers to action.
Anatomy of an order
At this point it’s probably worth clarifying what an order
is in Marketplacer, the following diagram illustrates the high level anatomy:
Put simply:
- A Seller is an individual entity (usually a business) that the marketplace operator has invited to sell on their marketplace. Multiple sellers can “participate” in a single order.
- An Order is the “marketplace-level” object that acts as the container for a customer’s entire purchase. An
order
object in Marketplacer will always have at least 1 Invoice attached to it. - An invoice is the individual seller’s “view” of the order. Given that we are dealing with a marketplace, it is conceivable that customers will purchase items from 1 or more Sellers. It is therefore necessary to “split” the order into seller-level components, in this case the
invoice
object. Even if there is only 1 seller participating in the transaction, there will still be aninvoice
created on theorder
- A Line Item is the individual item that a customer will purchase. Line items start their journey as Variants placed for sale on the marketplace by the seller. When a
variant
object is purchased alineItem
object is created.
What about products?
From an API perspective “Products” in Marketplacer are referred to as “Adverts” and manifest asadvert
objects in the GraphQL API. Adverts have multiple Variants, and it’s ultimately the Variant that is purchased by the customer.Probably the main take-away from the previous conversation is the parent child relationship between the order
and invoice
objects.
Using orderCreate
An example of the orderCreate
mutation is available in both our Postman and Insomnia collections, details on both can be found here. The rest of this section describes the main input components of this mutation.
The orderCreate
mutation input (OrderCreateMutationInput
) has the following input types of interest, we’ll cover each one in turn:
- OrderInput
- OrderCreateNotificationEnum
- LineItemInput
- If using the
LineItemInput
, you cannot also useInvoiceInput
- If using the
- InvoiceInput
- If using the
InvoiceInput
, you cannot also useLineItemInput
LineItemInput
can be supplied as child input type ofInvoiceInput
, but as stated above it cannot exist at the same level
- If using the
Which approach?
As stated above, you can supply either a list of Line Items when creating an order, or you can supply the Invoices (with child Line Items), that you want to create for each Seller, but not both at the same level of the orderCreate mutation call. So which one?By far the most popular approach is to use the Line Item method as Marketplacer will auto-create the individual invoices required for each seller participating in the order. If you choose the Invoice approach, the responsibility to create appropriate Seller Invoices lies with the API consumer.
OrderInput
This is section contains information related to the entire order, for example:
- Customer Name
- Customer Address
- Customer messages / notes
- Metadata / External Ids
OrderCreateNotifications
This describes how you’d like to (optionally) notify Sellers that they have new order, options are:
- SMS
The default position is that no communications are sent to the Sellers so this has to be explicitly requested.
LineItemInput
In this section you define the order line items, the following attributes are typically defined:
variantId
: This is the id of the variant that you wish to purchasequantity
: The number of line items you wish to purchasecost
: This is the object that holds the costs associated with each line item, broken down as:amount
: This is the total cost for the line item(s), not the unit price. E.g. If you have a variant priced at 1000 cents, and order 3 of them, then you’d pass 3000 as the value heretax
: If you have a specific tax amount for this line item it can be supplied here, otherwise you can omit and the default tax will be applied automatically by Marketplacer
postage
: This is the object that holds the postage costs associated with each line item, broken down as:amount
: This is the total postage cost for all the line itemstax
: If you have a specific tax amount for postage it can be supplied here, otherwise you can omit
adjustments
: This object allows you to applypromotions
(for each line item)adjustmentType
: This is mandatory and should be of typePROMOTION
amountCents
: This must be negative and the total amount of all adjustments cannot be more than the total of the invoice.amountToWithholdFromSellerRemittanceCents
: must be positive and not more than the absolute amount ofamountCents
. This is important, the amount to withhold means that the remaining balance of the discount will be added to the remittance. E.g. If the operator was funding the entire promotion, this would need to be 0. If the cost of the discount was being borne entirely by the seller,amountToWithholdFromSellerRemittanceCents
would be the absolute value of amountCents.description
: This is mandatory, and will be what is displayed in our UI and invoices as the reason for the promotion.sourceId
: This is the ID of the promotion as it exists in Marketplacer. This determines if the discount is to be applied to the shipping or the item, based on the action taken when the associated promotions was created.
externalIds
: This is akey
/value
pair combination that can be used to attach 3rd party (aka “external”) Ids for each line item at the point the order is created.- NOTE: External Ids are not used to reference the products you want to add to the order, for this you need to use the
variantId
.
- NOTE: External Ids are not used to reference the products you want to add to the order, for this you need to use the
metadata
: This is akey
/value
pair combination that can be used to represent any additional metadata for each line item.deliveryType
: If not supplied this defaults toBUY_ONLINE
which means the products purchased will be sent to the customer. The other values are:CLICK_AND_COLLECT
- customer will collect the items identified as suchNO_DISPATCH
- Not typically used but relates to items that are nor delivered or picked up, e.g. digital downloads.
Points to note
- There has to be a sufficient stock holding for each variant you wish to purchase - this is the
countOnHand
attribute on eachvariant
object- You cannot over-order, i.e
quantity
>countOnHand
- You cannot pre-order
- You cannot over-order, i.e
- The unit of currency for both
cost
andpostage
objects is the lowest denominated unit of currency configured for the marketplace, e.g.:- US / Australian Dollars: Unit of currency would be cents
- GBP Pound: Unit of currency would be pence
- Euro: Unit of currency would be cents
- We require a “whole cents unit price”.
- E.g. if you supplied 10830 for the
amount
with aquantity
of 4, this equates to an individual line item price of 2707.5 cents, (fractions of a cent are not permissible) - In the above case the individual line item price is rounded up to 2708, resulting in total line item amount of 10832 cents ($108.32)
- E.g. if you supplied 10830 for the
- If you choose to supply a value for
tax
you have to do so for bothcost
andpostage
objects you cannot just specify for one - If you choose to supply values for tax for 1 line item (for both
cost
andpostage
objects), you have to supplytax
values for all line items on the order - Multiple line items from different Sellers can be added, Markerplacer will workout the “order-split” or invoice creation automatically
adjustments
of typesFEE
andPROMOTION
can be applied usingorderCreate
however the reader should be aware of the following:- Promotions (
PROMOTION
) can only be applied on Line Items (LineItemInput
) and not via the Invoice (InvoiceInput
) - Custom Fees (
FEE
) can only be applied on the Invoice (InvoiceInput
) and not via Line Items (LineItemInput
)
- Promotions (
Example 1: Use lineItems
to create a simple order
mutation {
orderCreate(
input: {
order: {
firstName: "John"
surname: "Doe"
phone: "0405555555"
emailAddress: "jb@email.com"
address: {
address: "146 Buckhurst Street"
city: "Melbourne"
country: { code: "AU" }
postcode: "3000"
state: { name: "Victoria" }
}
}
lineItems: [
{
variantId: "VmFyaWFudC03MTM3"
quantity: 1
cost: { amount: 1200, tax: 120 }
}
]
}
) {
order {
id
legacyId
totalCents
}
status
errors {
field
messages
}
}
}
Example 2: Use lineItems
to create an order with a promotion adjustment
In the following example of the orderCreate
mutation we need to supply the sourceId
which relates to the ID of the promotion as it exists in Marketplacer. An example of how you can return promotions, (specifically their IDs), is provided in the query below.
Where can I get the sourceId?
In the following example of theorderCreate
mutation we need to supply the sourceId
which relates to the ID of the promotion as it exists in Marketplacer. An example of how you can return promotions, (specifically their IDs), is provided in the query below.query {
promotions(status: "active") {
nodes {
id
name
}
}
}
The above query will give you all the active
promotions configured on your Marketplacer instance. All we require for the adjustments
input in the following mutation is an id
(aka sourceId
). Note: this query can return a much more complex set of data relating to each promotion, an example of which can be found in both our Postman and Insomnia collections.
An example of creating an order with a promotion is shown below:
mutation {
orderCreate(
input: {
order: {
firstName: "John"
surname: "Doe"
phone: "0405555555"
emailAddress: "jb@email.com"
address: {
address: "146 Buckhurst Street"
city: "Melbourne"
country: { code: "AU" }
postcode: "3000"
state: { name: "Victoria" }
}
}
lineItems: [
{
variantId: "VmFyaWFudC03MTM3"
quantity: 1
cost: { amount: 1200 }
adjustments: [
{
adjustmentType: PROMOTION
amountCents: -120
amountToWithholdFromSellerRemittanceCents: 0
description: "10% off"
sourceId: "UHJvbW90aW9uLTEyMA=="
}
]
}
]
}
) {
order {
id
legacyId
totalCents
}
status
errors {
field
messages
}
}
}
Example 3 Create a click and collect order
In this example we override the default deliveryType
for the line items (BUY_ONLINE
- which means items will be delivered via post), instead specifying the item is for collection (CLICK_AND_COLLECT
).
mutation {
orderCreate(
input: {
order: {
firstName: "John"
surname: "Doe"
phone: "0405555555"
emailAddress: "jb@email.com"
address: {
address: "146 Buckhurst Street"
city: "Melbourne"
country: { code: "AU" }
postcode: "3000"
state: { name: "Victoria" }
}
}
lineItems: [
{
variantId: "VmFyaWFudC03MTM3"
quantity: 1
cost: { amount: 1200, tax: 120 }
deliveryType: CLICK_AND_COLLECT
}
]
}
) {
order {
id
legacyId
totalCents
}
status
errors {
field
messages
}
}
}
NOTE: If you supply multiple line items with different deliveryTypes
e.g.:
- Line Item 1:
deliveryType
=BUY_ONLINE
- LIne Item 2:
deliveryType
=CLICK_AND_COLLECT
- Line Item 3:
deliveryType
=CLICK_AND_COLLECT
This will result in 2 Invoices being created:
- Invoice 1: Line Item 1 (
BUY_ONLIINE
) - Invoice 2: Line Item 2 and Line Item 3 (
CLICK_AND_COLLECT
)
Ready for collection
Sellers working with click and collect invoices will need to use theclickAndCollectStatusUpdate
mutation to move the invoice through to the READY
and COLLECTED
states.This mutation is described in the Seller API documentation.
InvoiceInput
Using InvoiceInput
is the 2nd (less popular way) to create orders as the onus on “splitting” the order into Invoices lies with the consumer of the orderCreate
mutation. The following attributes are typically defined when using InvoiceInput
:
externalIds
: This is akey
/value
pair combination that can be used to represent 3rd party (aka “external”) Ids for each invoice.metadata
: This is akey
/value
pair combination that can be used to represent any additional metadata for each invoice.lineItems
: Refer to the above section on the attribute set available on theLineItemInput
type.adjustments
: This object allows you to apply custom fees for each invoiceadjustmentType
: This is mandatory and should be of typeFEE
(note you cannot apply promotions at the Invoice level, you need to make promotion adjustments at the line item level - see above example)amountCents
: This must be a positive amountamountToWithholdFromSellerRemittanceCents
: must be positive and not more than the absolute amount ofamountCents
. This gives you the ability to recover this fee from the seller.description
: This is mandatory, and will be what is displayed in our UI and invoices as the reason for the custom fee.
Example 3: Use InvoiceInput
to create an order (and Invoice) with a custom fee
mutation{
orderCreate(input: {
order: {
firstName: "John"
surname: "Doe"
phone: "0405510036"
emailAddress: "jd@email.com"
address: {
address: "146 Buckhurst Street"
city: "Melbourne"
country: {
code: "AU"
}
postcode: "3000"
state: {
name: "Victoria"
}
}
}
invoices:[
{
lineItems: [
{
variantId: "VmFyaWFudC03MTM3"
quantity: 1
cost:{
amount: 400
}
}
]
adjustments:[
{
adjustmentType: FEE
amountCents: 40
amountToWithholdFromSellerRemittanceCents: 40
description: "Remote Shipping Fee"
}
]
}
]
})
{
order{
id
legacyId
totalCents
}
status
errors{
field
messages
}
}
}