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.