Menu
Guides
API Reference

Guides

Split payouts on Payment Provider Protocol

Learn how the VTEX Gateway calculates commissions and sends the recipients array to your connector at each stage of the Payment Provider Protocol.

9 min read

Split payouts are a common requirement for payment providers used by marketplaces. They allow a marketplace to process the payment for an order, collect its commission, and pay sellers for their products in a single transaction, which improves operational efficiency when managing payouts at scale.

The VTEX platform allows merchants to register sellers, configure commission percentages for the total order and shipping rates, and set specific commissions by seller category. For more information, see Adding a seller.

This guide describes how the VTEX Gateway calculates the split and what changes in each Payment Provider Protocol request when split payouts are active.

Before you begin

Check the following requirements:

  • Your connector must be integrated through the Payment Provider Protocol.
  • The manifest returned by the Get manifest endpoint must declare the allowsSplit property for every payment method, using disabled for methods that don't support split payouts.
  • To support partial refunds in split transactions, the acceptSplitPartialRefund parameter must be enabled for your connector. Request this during the payment provider homologation process.
  • The merchant must have sellers and commission percentages configured in the marketplace, as described in Adding a seller.

Cart scenarios

When an order is placed, the cart falls into one of three scenarios:

ScenarioSplit behavior
Products only from the marketplaceNo split payout, commission calculation, or split payload. The marketplace receives the full order payment value.
Products from the marketplace and one or more sellersSplit payout required.
Products only from sellersSplit payout required.

When a split payout is required, the VTEX Gateway is responsible for:

  • Calculating the commission per seller of each order.
  • Sending the split payload data to the payment provider.
  • Processing the complete or partial refund in split operations, when required.

The VTEX Gateway sends the split payload only if the payment provider supports this scenario.

Commission calculation example

Consider an order of 199.62 USD with the following registered commissions: 16% for the marketplace when the product comes from seller X, and 20% for the marketplace when the product comes from seller Y. The cart contains products from seller X, seller Y, and the marketplace itself.

The VTEX Gateway calculates the following breakdown:

ItemSellerItem amountMarketplace commissionAmount sent to recipient
SellerX productsellerX87.1213.9473.18
SellerY productsellerY42.608.5234.08
Marketplace productMarketplace69.90-92.36, that is 69.90 + 13.94 + 8.52

The marketplace receives the value of its own products plus the commission collected from both sellers, and each seller receives the value of its products minus the marketplace commission.

Split timing settings

You can configure the following characteristics of the split process:

  • Automatic settlement time: The payment provider controls whether automatic settlement occurs before or after the anti-fraud analysis via the delayToAutoSettle and delayToAutoSettleAfterAntifraud fields in the authorization response.
  • Split payload sending time: Set per payment method through the allowsSplit property of each item in the paymentMethods array of the manifest.

The allowsSplit property accepts the following values:

ValueBehavior
onAuthorizeThe VTEX Gateway sends the recipients array in the authorization request.
onCaptureThe VTEX Gateway sends the recipients array in the settlement request. Capture and settlement refer to the same step.
disabledThe VTEX Gateway doesn't send the recipients array for this payment method.

The allowsSplit property is required for every payment method in the manifest. Don't omit it: use disabled for payment methods that don't support split payouts. The split payload is sent at the stage specified by the declared value.

The recipients array

The split payout solution adds an array of objects called recipients to the Payment Provider Protocol. Each item of this array carries the data your connector needs to split the transaction between the recipients involved, meaning the marketplace and the sellers.

The recipient object contains the following fields:

FieldTypeRequiredDescription
idStringYesRecipient identifier.
nameStringYesRecipient name.
documentTypeStringYesRecipient document type, such as the Brazilian CNPJ.
documentStringYesRecipient document number.
roleStringYesIndicates whether the recipient is the seller or the marketplace.
chargeProcessingFeeBooleanNoIndicates whether this recipient is charged for processing fees.
chargebackLiableBooleanNoIndicates whether this recipient is liable for chargebacks.
amountNumberYesAmount due to this recipient.
comissionAmountNumberNoAmount of commission due to the marketplace. Sent only for recipients whose role is seller.

The commission field is spelled comissionAmount, with a single m, in the Create payment and Refund payment schemas, and commissionAmount, with a double m, in the Settle payment schema. Handle both spellings in your connector to avoid losing commission data.

Protocol changes by stage

The following sections describe the changes applied to each stage of the Payment Provider Protocol when split payouts are active.

Authorization

When allowsSplit is onAuthorize for the payment method, the VTEX Gateway sends the recipients array in the authorization payload, containing the values to be passed on to each seller and to the marketplace involved in the order.

The following example shows the authorization request for the order described in Commission calculation example:


_125
curl --location --request POST 'https://{providerApiEndpoint}/payments' \
_125
--header 'X-VTEX-API-AppKey: {appKey}' \
_125
--header 'X-VTEX-API-AppToken: {appToken}' \
_125
--header 'Content-Type: application/json' \
_125
--header 'Accept: application/json' \
_125
--data-raw '{
_125
"value": 199.62,
_125
"reference": "22590454",
_125
"orderId": "v22590454abc",
_125
"transactionId": "888EC956B26A4F53B3A8F2D420271195",
_125
"paymentId": "FAD57B4061034026A78545DD3FC6A85D",
_125
"paymentMethod": "Visa",
_125
"merchantName": "mystore",
_125
"card": {
_125
"holder": "John Doe",
_125
"number": "4682185088924788",
_125
"csc": "021",
_125
"expiration": {
_125
"month": "06",
_125
"year": "2029"
_125
}
_125
},
_125
"currency": "USD",
_125
"installments": 1,
_125
"deviceFingerprint": "12ade389087fe",
_125
"miniCart": {
_125
"buyer": {
_125
"id": "3287c060-2e43-4dc7-b730-4b8d2a9bd114",
_125
"firstName": "Mary",
_125
"lastName": "Rose",
_125
"document": "987654321",
_125
"documentType": "SSN",
_125
"email": "mary.rose@example.com",
_125
"phone": "+12125550143"
_125
},
_125
"shippingAddress": {
_125
"country": "USA",
_125
"street": "Main Street",
_125
"number": "123",
_125
"complement": "Apt 3B",
_125
"neighborhood": null,
_125
"postalCode": "10001",
_125
"city": "New York",
_125
"state": "NY"
_125
},
_125
"billingAddress": {
_125
"country": "USA",
_125
"street": "Market Street",
_125
"number": "4440",
_125
"complement": "Suite 1000",
_125
"neighborhood": null,
_125
"postalCode": "94105",
_125
"city": "San Francisco",
_125
"state": "CA"
_125
},
_125
"items": [
_125
{
_125
"id": "25807",
_125
"name": "SellerX product",
_125
"price": 87.12,
_125
"quantity": 1,
_125
"discount": 0,
_125
"categoryId": "1000097",
_125
"sellerId": "sellerX"
_125
},
_125
{
_125
"id": "29052",
_125
"name": "Marketplace product",
_125
"price": 69.90,
_125
"quantity": 1,
_125
"discount": 0,
_125
"categoryId": "1000148",
_125
"sellerId": "1"
_125
},
_125
{
_125
"id": "48760",
_125
"name": "SellerY product",
_125
"price": 42.60,
_125
"quantity": 1,
_125
"discount": 0,
_125
"categoryId": "1000104",
_125
"sellerId": "sellerY"
_125
}
_125
],
_125
"shippingValue": 0,
_125
"taxValue": 0,
_125
"url": "https://admin.mystore.example.com/admin/checkout/#/orders?q=v22590454abc"
_125
},
_125
"callbackUrl": "https://api.example.com/some-path/to-notify/status-changes?an=mystore",
_125
"returnUrl": "https://mystore.example.com/checkout/order/v22590454abc",
_125
"recipients": [
_125
{
_125
"id": "mystore",
_125
"name": "Company XPTO",
_125
"documentType": "EIN",
_125
"document": "012345678",
_125
"role": "marketplace",
_125
"chargeProcessingFee": true,
_125
"chargebackLiable": true,
_125
"amount": 92.36
_125
},
_125
{
_125
"id": "sellerX",
_125
"name": "Company X",
_125
"documentType": "EIN",
_125
"document": "888888888",
_125
"role": "seller",
_125
"chargeProcessingFee": false,
_125
"chargebackLiable": false,
_125
"amount": 73.18,
_125
"comissionAmount": 13.94
_125
},
_125
{
_125
"id": "sellerY",
_125
"name": "Company Y",
_125
"documentType": "EIN",
_125
"document": "999999990",
_125
"role": "seller",
_125
"chargeProcessingFee": false,
_125
"chargebackLiable": false,
_125
"amount": 34.08,
_125
"comissionAmount": 8.52
_125
}
_125
]
_125
}'

When allowsSplit is onCapture or disabled for the payment method, there are no changes in the authorization payload.

Settlement

When allowsSplit is onCapture for the payment method, the VTEX Gateway sends the list of recipients involved in the transaction in the settlement request.

Consider a cart consisting of products from seller A, with an order value of 45.00 and a marketplace commission rate of 16%. The VTEX Gateway sends 7.2 to the marketplace and 37.8 to seller A:


_36
curl --location --request POST 'https://{providerApiEndpoint}/payments/{paymentId}/settlements' \
_36
--header 'X-VTEX-API-AppKey: {appKey}' \
_36
--header 'X-VTEX-API-AppToken: {appToken}' \
_36
--header 'Content-Type: application/json' \
_36
--header 'Accept: application/json' \
_36
--data-raw '{
_36
"transactionId": "D3AA1FC8372E430E8236649DB5EBD08E",
_36
"requestId": "2019-02-04T22:53:42-40000",
_36
"paymentId": "F5C1A4E20D3B4E07B7E871F5B5BC9F91",
_36
"value": 45.00,
_36
"authorizationId": "5784589",
_36
"tid": "5784589",
_36
"recipients": [
_36
{
_36
"id": "mystore",
_36
"name": "Company XPTO",
_36
"documentType": "CNPJ",
_36
"document": "05314972000174",
_36
"role": "marketplace",
_36
"chargeProcessingFee": true,
_36
"chargebackLiable": true,
_36
"amount": 7.2
_36
},
_36
{
_36
"id": "sellerA",
_36
"name": "Company ABC",
_36
"documentType": "CNPJ",
_36
"document": "24830098000172",
_36
"role": "seller",
_36
"chargeProcessingFee": true,
_36
"chargebackLiable": true,
_36
"amount": 37.8,
_36
"commissionAmount": 7.2
_36
}
_36
]
_36
}'

When allowsSplit is onAuthorize or disabled for the payment method, there are no changes in the settlement payload.

Complete refund

The complete refund payload has no changes when split payouts are active, because the refund covers the whole transaction:


_12
curl --location --request POST 'https://{providerApiEndpoint}/payments/{paymentId}/refunds' \
_12
--header 'X-VTEX-API-AppKey: {appKey}' \
_12
--header 'X-VTEX-API-AppToken: {appToken}' \
_12
--header 'Content-Type: application/json' \
_12
--header 'Accept: application/json' \
_12
--data-raw '{
_12
"paymentId": "F5C1A4E20D3B4E07B7E871F5B5BC9F91",
_12
"transactionId": "D3AA1FC8372E430E8236649DB5EBD08E",
_12
"settleId": "Q5C1A4E20D3B4E07B7E871F5B5BC9F91",
_12
"value": 45.0,
_12
"requestId": "LA4E20D3B4E07B7E871F5B5BC9F91"
_12
}'

Partial refund

To use the split partial refund feature, request the Partner Support team to enable the acceptSplitPartialRefund parameter as true during the payment provider homologation process.

The recipients array contains the recipients affected by the refund: each seller whose items are refunded and the marketplace, with the commission share it returns. When the refund applies only to marketplace items, the array contains only the marketplace data.

Partial refund of a seller item

Consider a cart composed of items from seller A, with a marketplace commission of 16%, for which 20.00 must be refunded. The VTEX Gateway sends 3.2 for the marketplace and 16.8 for seller A:


_31
curl --location --request POST 'https://{providerApiEndpoint}/payments/{paymentId}/refunds' \
_31
--header 'X-VTEX-API-AppKey: {appKey}' \
_31
--header 'X-VTEX-API-AppToken: {appToken}' \
_31
--header 'Content-Type: application/json' \
_31
--header 'Accept: application/json' \
_31
--data-raw '{
_31
"requestId": "LA4E20D3B4E07B7E871F5B5BC9F91",
_31
"settleId": "Q5C1A4E20D3B4E07B7E871F5B5BC9F91",
_31
"paymentId": "F5C1A4E20D3B4E07B7E871F5B5BC9F91",
_31
"tid": "10022005181543584603",
_31
"value": 20.00,
_31
"transactionId": "D3AA1FC8372E430E8236649DB5EBD08E",
_31
"recipients": [
_31
{
_31
"id": "mystore",
_31
"name": "Company XPTO",
_31
"documentType": "CNPJ",
_31
"document": "05314972000174",
_31
"role": "marketplace",
_31
"amount": 3.2
_31
},
_31
{
_31
"id": "sellerA",
_31
"name": "Company ABC",
_31
"documentType": "CNPJ",
_31
"document": "24830098000172",
_31
"role": "seller",
_31
"amount": 16.8
_31
}
_31
]
_31
}'

Partial refund of a marketplace item

When 20.00 USD must be refunded for a marketplace item, the VTEX Gateway sends a single recipient object with the marketplace data:


_23
curl --location --request POST 'https://{providerApiEndpoint}/payments/{paymentId}/refunds' \
_23
--header 'X-VTEX-API-AppKey: {appKey}' \
_23
--header 'X-VTEX-API-AppToken: {appToken}' \
_23
--header 'Content-Type: application/json' \
_23
--header 'Accept: application/json' \
_23
--data-raw '{
_23
"requestId": "LA4E20D3B4E07B7E871F5B5BC9F91",
_23
"settleId": "Q5C1A4E20D3B4E07B7E871F5B5BC9F91",
_23
"paymentId": "F5C1A4E20D3B4E07B7E871F5B5BC9F91",
_23
"tid": "10022005181543584603",
_23
"value": 20.00,
_23
"transactionId": "D3AA1FC8372E430E8236649DB5EBD08E",
_23
"recipients": [
_23
{
_23
"id": "mystore",
_23
"name": "Company XPTO",
_23
"documentType": "CNPJ",
_23
"document": "05314972000174",
_23
"role": "marketplace",
_23
"amount": 20.00
_23
}
_23
]
_23
}'

Cancellation

The cancellation payload has no changes in this version of the split payouts feature:


_10
curl --location --request POST 'https://{providerApiEndpoint}/payments/{paymentId}/cancellations' \
_10
--header 'X-VTEX-API-AppKey: {appKey}' \
_10
--header 'X-VTEX-API-AppToken: {appToken}' \
_10
--header 'Content-Type: application/json' \
_10
--header 'Accept: application/json' \
_10
--data-raw '{
_10
"paymentId": "F5C1A4E20D3B4E07B7E871F5B5BC9F91",
_10
"requestId": "D12D9B80972C462980F5067A3A126837"
_10
}'

Connector responses

Split payouts don't change the response bodies your connector must return. Answer each request with the standard Payment Provider Protocol response for that operation.

A successful settlement returns the status code 200 OK:


_10
{
_10
"paymentId": "F5C1A4E20D3B4E07B7E871F5B5BC9F91",
_10
"settleId": "2EA354989E7E4BBC9F9D7B66674C2574",
_10
"value": 45.00,
_10
"code": null,
_10
"message": "Successfully settled",
_10
"requestId": "DCEAA1FC8372E430E8236649DB5EBD08E"
_10
}

A successful refund also returns the status code 200 OK:


_10
{
_10
"paymentId": "F5C1A4E20D3B4E07B7E871F5B5BC9F91",
_10
"refundId": "2EA354989E7E4BBC9F9D7B66674C2574",
_10
"value": 20.00,
_10
"code": null,
_10
"message": "Successfully refunded",
_10
"requestId": "LA4E20D3B4E07B7E871F5B5BC9F91"
_10
}

Error handling

Report failures through the status code and the code and message fields of the response, so that the VTEX Gateway can record the result of the operation:

Status codeWhen to use itResponse fields
500 Internal Server ErrorYour connector or the payment provider couldn't complete the split operation.Set settleId or refundId to null, value to 0, and describe the failure in code and message.
501 Not ImplementedYour connector can't refund the payment automatically and the merchant must refund it outside VTEX.Set code to refund-manually and explain the limitation in message.

The following example shows a settlement that failed:


_10
{
_10
"paymentId": "F5C1A4E20D3B4E07B7E871F5B5BC9F91",
_10
"settleId": null,
_10
"value": 0,
_10
"code": "ERR123",
_10
"message": "Settlement has failed due to an internal error",
_10
"requestId": "DCEAA1FC8372E430E8236649DB5EBD08E"
_10
}

When validating a split request, consider the following:

  • The sum of the amount values of all recipients matches the value field of the request.
  • The recipients array is absent when the payment method sets allowsSplit as disabled, or when the order contains marketplace products only. Treat the absence of this array as a transaction without split.
  • Partial refund requests only include the recipients involved in that refund, so don't assume that the array repeats every recipient of the authorization.

Learn more