Seller Payouts
Introduction
The marketplace operator is able to create and approve payouts to marketplace vendors by capturing all eligible orders in a payout window.
There are currently two Payout Modes. The Marketplace Operator can select from between the two which mode they wish to operate under for Payouts. The two Payout Modes that a Marketplace Operator can choose from to create Payouts are:
- Automated by fulfillment
- Manual
The difference between the two modes is that for Automated by fulfillment, so long as certain criteria are met for each Seller Order (detailed in the Payouts - Automated by Fulfillment Mode section), when you create a Payout, those Seller Orders will automatically be included in the Payout. In Manual mode, you, as a Marketplace Operator, will have to go into each Seller Order and mark for yourself whether or not they're ready for payout (offers greater flexibility as there are fewer criteria for Seller Orders to be met under Manual Mode to be included in a Payout).
We'll discuss both Payout Modes in this article, under the Payouts - Automated by Fulfillment Mode, and Payouts - Manual Mode sections. But first, how to select the mode.
Select the Marketplace Payout Mode
To select the Payout Mode you wish to use, as it is a marketplace configuration, you must do so through the marketplaceConfigurationUpdate
mutation, as so (The input fields shown in this snapshot are required, so you can query marketplaceConfiguration
first to get these values to pass to the mutation if you don't already know/remember them. There are other optional input fields not shown as well):
For the next section, we'll set our marketplace configuration payoutAutomationStrategy
to AUTOMATED_BY_FULFILLMENT
.
mutation {
marketplaceConfigurationUpdate(
input: {
maxCheckoutLineQuantity: 50
maxCheckoutQuantity: 100
maxProductsInGroup: 10
requireProductApproval: false
marketplaceAccruesShippingRevenue: false
payoutAutomationStrategy: AUTOMATED_BY_FULFILLMENT
}
) {
marketplaceConfiguration {
payoutAutomationStrategy
}
marketplaceConfigurationErrors {
field
message
code
}
}
}
Payouts - Automated by Fulfillment Mode
Create the Draft Payout
Let's assume you, as a Marketplace Operator, have a bunch of orders already. Or in this example, we'll have one order.
For a Seller Order to qualify for a payout, the Seller Order needs to meet the following criteria:
- Seller Order must be fully paid, meaning payment has been fully captured at the Marketplace Order level
- Seller Order must be partially or fully fulfilled
- The fulfillment date of the Seller Order must be on a date that is 15 days or more BEFORE the chosen End Date. The End Date is the cutoff date we'll use when creating the Payout.
In this example, we'll have one Seller Order that is qualified for a Payout. In order to create a draft Payout, we run the payoutCreate mutation, as so:
mutation {
payoutCreate(input: { vendorType: "sellers", endDate: "2022-10-31" }) {
payout {
id
created
startDate
endDate
status
name
vendorType
}
payoutErrors {
field
message
code
}
}
}
The endDate must be on or before today's date.
And since this is a Vendor Payout, as opposed to an Affiliate payout, we choose “sellers”, as opposed to “affiliates”, for vendorType.
View List of Payouts
If you want to see a list of you Payouts (past and present), you can do so via the payouts
query. In this screenshot, we'll just show the one we recently created:
{
payouts(first: 1, sortBy: { field: CREATED, direction: DESC }) {
edges {
node {
id
name
status
vendorType
created
endDate
}
}
pageInfo {
hasPreviousPage
hasNextPage
}
}
}
View Payout Details
If we want to get some details about one of our Payouts (past or present), we can do so through the payout
mutation, which needs the Payout ID for the Payout of interest. The Draft Payout we just created above has an ID of “UGF5b3V0OjY=
”. Here is an example of some of the data we can query for this Payout (see GraphQL playground documentation for an exhaustive list of fields you can query for):
{
payout(id:"UGF5b3V0OjY=") {
vendors
vendorPayouts(first:100) {
edges {
node {
id
seller {
id
companyName
}
status
}
}
}
status
endDate
netSales {
currency
amount
}
penalties {
currency
amount
}
adjustments {
currency
amount
}
payout {
currency
amount
}
}
}
}
payout {
currency
amount
}
}
}
We can see from the above that only one Vendor/Seller is associated with this Payout, and they have yet to be Paid. You may have multiple Vendors in a Payout, if unlike in this example, multiple Vendors qualified for the Payout.
Apply Adjustments and Penalties to Payout
You may also notice from the above that there are no adjustments or penalties associated with the Payout. You can make adjustments (additions to a given Seller Payout) or penalties (deductions from a given Seller Payout) for any number of reasons. Since a Payout may have multiple Seller Payouts associated with it, we'll need the Seller ID associated with any Seller Payout that we wish to add adjustments or penalties for. We can see above that the Seller ID of the only Seller in our Payout is “U2VsbGVyOjQ=
”. Let's say we want to make an adjustment (addition) of 10
and penalty (deduction) of 5
to the Payout, in whatever currency the Marketplace is currently set to. We can make such adjustments and penalties, as so:
mutation {
payoutUpdate(
id: "UGF5b3V0OjY="
input: {
vendorPayouts: [
{ adjustments: 10, penalties: -5, vendorId: "U2VsbGVyOjQ=" }
]
}
) {
payout {
id
status
name
created
penalties {
currency
amount
}
adjustments {
currency
amount
}
payout {
currency
amount
}
}
payoutErrors {
field
message
code
}
}
}
Exclude Select Vendors from a Payout
Suppose we had multiple Vendors associated with this Draft Payout. If we wanted to exclude any of them, we would need the IDs of the vendorPayouts
we want to exclude. We can use the payout
query from above. Here's is a shortened version of it, for convenience:
{
payout(id: "UGF5b3V0OjY=") {
vendors
vendorPayouts(first: 100) {
edges {
node {
id
seller {
id
companyName
}
status
}
}
}
}
}
The vendorPayout ID in this case is “VmVuZG9yUGF5b3V0OjY=
”, which can be seen in the response above.
With this in hand, the mutation to exclude Vendors from a given payout is vendorPayoutsBulkExclude
. It takes an argument of ids, which is an array of the vendorPayout
IDs that we wish to exclude.
You'll need at least one vendor remaining in the Payout after exclusions, otherwise you'll get an error when trying to execute this mutation.
Given the above note, if we try to run this mutation in our example, we get an error. Nonetheless, the mutation would look like this:
mutation {
vendorPayoutsBulkExclude(ids: ["VmVuZG9yUGF5b3V0OjY="]) {
count
payoutErrors {
field
message
code
}
}
}
Lock a Payout So It Can Be Completed
At this point, we've made adjustments and penalties to our draft Vendor Payouts, and also excluded any Vendors we wish from this Payout. Now we are ready, as the Marketplace Operator, to “Lock” this Payout so it can no longer be altered and will be ready for an actual Payout. We'll need the Payout ID, which we already have from previous API calls, and in our case is “UGF5b3V0OjY=
”. The mutation will be payoutStatusUpdate
, and we would use it like this:
mutation {
payoutStatusUpdate(id: "UGF5b3V0OjY=", input: { status: "locked" }) {
payout {
id
name
status
}
payoutErrors {
field
message
code
}
}
}
We can “Unlock” the Payout to make it editable again by using the very same mutation, and setting the value of the status field to “draft”.
Complete the Payout
Our payout is now Locked and we are ready to execute the actual Payout, so our Vendors get paid for their sales in our Marketplace.
The mutation to execute a Payout to your Vendors is vendorPayoutsBulkProcess
. You must pass two arguments to the mutation; gateway
, and ids
.
Retrieve Payout Gateways
To see what gateways you have available to you, you can execute the getPayoutGateways
query, as so:
{
getPayoutGateways {
id
name
}
}
Payouts with Stripe
For using Stripe Connect to process payouts, we'll grab the “nautical.payments.stripe
”, from this query response. This will be used as our gateway
value when we run the vendorPayoutsBulkProcess
mutation.
Furthermore, we needs the ids of the Vendors Payouts we will be paying out in this Payout. In this example, we just have the vendor payout ID of "VmVuZG9yUGF5b3V0OjY=
". So, we can execute our mutation as so:
mutation {
vendorPayoutsBulkProcess(
gateway: "nautical.payments.stripe"
ids: ["VmVuZG9yUGF5b3V0OjY="]
) {
count
payoutErrors {
field
message
code
}
}
}
As an alternative, you can pass “manual
” as the value for gateway. This implies that the marketplace has issued the payouts externally/manually to their vendors.
When the payouts final status is "PAID
" (which will be the case after this last mutation is successfully executed), then an automatically generated eMail is sent to the Vendors to notify them that a payout has been processed.
Payouts - Manual Mode
Create the Draft Payout
Let's assume you, as a Marketplace Operator, have a bunch of orders already. We can check the Payout Status of our Seller Orders by using the orders
query, as so:
{
orders(first: 100, sortBy: { field: CREATION_DATE, direction: DESC }) {
edges {
node {
id
payoutStatus
}
}
}
}
You can see we have an orders with a payoutStatus of “NOT_READY
”. Suppose we want to payout this Seller Order. We'll need its ID, which is “T3JkZXI6Nw==
”.
As part of being in Manual Mode for Payouts, we'll have to manually set this Seller Order as having a payoutStatus of “READY_FOR_PAYOUT
”. To do this, we can use the ID we just grabbed and the orderPayoutStatusUpdate
mutation, as so:
mutation {
orderPayoutStatusUpdate(
id: "T3JkZXI6Nw=="
input: { payoutStatus: READY_FOR_PAYOUT }
) {
order {
id
payoutStatus
}
orderErrors {
field
message
code
}
}
}
You can do the above for multiple Seller Orders, so that you can payout multiple Vendors in a given Payout. You'd just have to run the above mutation again for all the other Seller Orders, using their respective IDs.
In order to create a draft Payout, we run the payoutCreate
mutation, as so:
mutation {
payoutCreate(input: { vendorType: "sellers", endDate: "2022-10-31" }) {
payout {
id
created
startDate
endDate
status
name
vendorType
}
payoutErrors {
field
message
code
}
}
}
The endDate must be on or before today's date.
And since this is a Vendor Payout, as opposed to an Affiliate payout, we choose “sellers”, as opposed to “affiliates”, for vendorType.
View List of Payouts
If you want to see a list of you Payouts (past and present), you can do so via the payouts
query. In this screenshot, we'll just show the one we recently created:
{
payouts(first: 1, sortBy: { field: CREATED, direction: DESC }) {
edges {
node {
id
name
status
vendorType
created
endDate
}
}
pageInfo {
hasPreviousPage
hasNextPage
}
}
}
View Payout Details
If we want to get some details about one of our Payouts (past or present), we can do so through the payout
mutation, which needs the Payout ID for the Payout of interest. The Draft Payout we just created above has an ID of “UGF5b3V0Ojc=
”. Here is an example of some of the data we can query for this Payout (see GraphQL playground documentation for an exhaustive list of fields you can query for):
{
payout(id:"UGF5b3V0Ojc=") {
vendors
vendorPayouts(first:100) {
edges {
node {
id
seller {
id
companyName
}
status
}
}
}
status
endDate
netSales {
currency
amount
}
penalties {
currency
amount
}
adjustments {
currency
amount
}
payout {
currency
amount
}
}
}
}
payout {
currency
amount
}
}
}
We can see from the above that only one Vendor/Seller is associated with this Payout, and they have yet to be Paid. As mentioned already, you may have multiple Vendors in a Payout if unlike in this example, multiple Seller Orders have been marked as “READY_FOR_PAYOUT
”.
Apply Adjustments and Penalties to Payout
You may also notice from the above that there are no adjustments or penalties associated with the Payout. You can make adjustments (additions to a given Seller Payout) or penalties (deductions from a given Seller Payout) for any number of reasons. Since a Payout may have multiple Seller Payouts associated with it, we'll need the Seller ID associated with any Seller Payout that we wish to add adjustments or penalties for. We can see above that the Seller ID of the only Seller in our Payout is “U2VsbGVyOjQ=
”. Let's say we want to make an adjustment (addition) of 10
and penalty (deduction) of 5
to the Payout, in whatever currency the Marketplace is currently set to. We can make such adjustments and penalties, as so:
mutation {
payoutUpdate(
id: "UGF5b3V0Ojc="
input: {
vendorPayouts: [
{ adjustments: 10, penalties: -5, vendorId: "U2VsbGVyOjQ=" }
]
}
) {
payout {
id
status
name
created
penalties {
currency
amount
}
adjustments {
currency
amount
}
payout {
currency
amount
}
}
payoutErrors {
field
message
code
}
}
}
Exclude Select Vendors from a Payout
Suppose we had multiple Vendors associated with this Draft Payout. If we wanted to exclude any of them, we would need the IDs of the vendorPayouts
we want to exclude. We can use the payout
query from above. Here's is a shortened version of it, for convenience:
{
payout(id: "UGF5b3V0Ojc=") {
vendors
vendorPayouts(first: 100) {
edges {
node {
id
seller {
id
companyName
}
status
}
}
}
}
}
The vendorPayout
ID in this case is “VmVuZG9yUGF5b3V0OjY=
”, which can be seen in the response above.
With this in hand, the mutation to exclude Vendors from a given payout is vendorPayoutsBulkExclude
. It takes an argument of ids
, which is an array of the vendorPayout
IDs that we wish to exclude.
You'll need at least one vendor remaining in the Payout after exclusions, otherwise you'll get an error when trying to execute this mutation.
Given the above note, if we try to run this mutation in our example, we get an error. Nonetheless, the mutation would look like this:
mutation {
vendorPayoutsBulkExclude(ids: ["VmVuZG9yUGF5b3V0OjY="]) {
count
payoutErrors {
field
message
code
}
}
}
Lock a Payout So It Can Be Completed
At this point, we've made adjustments and penalties to our draft Vendor Payouts, and also excluded any Vendors we wish from this Payout. Now we are ready, as the Marketplace Operator, to “Lock” this Payout so it can no longer be altered and will be ready for an actual Payout. We'll need the Payout ID, which we already have from previous API calls, and in our case is “UGF5b3V0OjY=
”. The mutation will be payoutStatusUpdate
, and we would use it like this:
mutation {
payoutStatusUpdate(id: "UGF5b3V0OjY=", input: { status: "locked" }) {
payout {
id
name
status
}
payoutErrors {
field
message
code
}
}
}
We can “Unlock” the Payout to make it editable again by using the very same mutation, and setting the value of the status
field to “draft
”.
Complete the Payout
Our payout is now Locked and we are ready to execute the actual Payout, so our Vendors get paid for their sales in our Marketplace.
The mutation to execute a Payout to your Vendors is vendorPayoutsBulkProcess
. You must pass two arguments to the mutation; gateway
, and ids
.
Retrieve Payout Gateways
To see what gateways you have available to you, you can execute the getPayoutGateways
query, as so:
{
getPayoutGateways {
id
name
}
}
Payout Vendors
As mentioned at the beginning of this Document, it is assumed that the marketplace is using Stripe Connect for their payouts. As such, we'll grab the “nautical.payments.stripe
”, from this query response. This will be used as our gateway
value when we run the vendorPayoutsBulkProcess
mutation.
Furthermore, we needs the ids of the Vendors Payouts we will be paying out in this Payout. In this example, we just have the vendor payout ID of "VmVuZG9yUGF5b3V0OjY=
". So, we can execute our mutation as so:
mutation {
vendorPayoutsBulkProcess(
gateway: "nautical.payments.stripe"
ids: ["VmVuZG9yUGF5b3V0OjY="]
) {
count
payoutErrors {
field
message
code
}
}
}
As an alternative, you can pass “manual
” as the value for gateway. This implies that the marketplace has issued the payouts externally/manually to their vendors.
When the payouts final status is "PAID
" (which will be the case after this last mutation is successfully executed), then an automatically generated eMail is sent to the Vendors to notify them that a payout has been processed.