Skip to main content

Integrating Marketplace API

The PayU marketplace integration is based on the standard REST API integration, but enhanced with additional elements unique to marketplace platforms. Integration enhancements are described in this section.

Authorizing the Request

To communicate with the PayU system you have to authenticate requests with the OAuth token generated with the client_credentials type. To learn how to generate authentication tokens, please refer to Signing API Calls section.

Creating new Order Request

Extending Standard Order Request

While creating new order for the marketplace, you have to add shoppingCarts section to your request. This section defines funds distribution to particular submerchants.

Another important distinction from the standard order creation is extCustomerId parameter added to the buyer section. This parameter identifies submerchant participating in the transaction.

Additionally, if customers choose payment on your checkout page, you must add a payMethods section to the request, specifying the chosen payment method.

shoppingCart Section Example
...
"shoppingCarts": [
{
"extCustomerId": "ext-customer-1",
"amount": 1800,
"fee": 20,
"shippingMethods": [
{
"country": "EN",
"price": 1500,
"name": "Shipping Method 1"
}
],
"products": [
{
"name": "product-x",
"unitPrice": 100,
"quantity": 3,
"virtual": false,
"listingDate": "2020-09-28T08:17:52Z"
}
]
},
{
"extCustomerId": "ext-customer-2",
"amount": 2700,
"fee": 27,
"shippingMethods": [
{
"country": "EN",
"price": 2000,
"name": "Shipping Method 2"
}
],
"products": [
{
"name": "product-y",
"unitPrice": 700,
"quantity": 1,
"virtual": false,
"listingDate": "2018-02-28T09:28:52Z"
}
]
}
]
...
Notes

extCustomerId from shoppingCarts and buyer sections are two different parameters. Inside shoppingCarts it specifies submerchant participating in the transaction. Inside buyer section it identifies the payer.


The sum of the price parameter and the product of the unitPrice and quantity parameters must equal the amount parameter value in the scope of single submerchant.


The sum of each amount parameter in the scope of the request must equal the value of the totalAmount parameter.

For details on parameters, please refer to Create an Order section in our API Reference.

Marketplace Order Request Example

Below you can see a example of the marketplace order request where customer buys multiple products from three submerchants within one transaction.

curl -v -X POST https://secure.payu.com/api/v2_1/orders \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <AUTH_TOKEN>" \
-d '{
"merchantPosId":"341009",
"customerIp": "127.0.0.1",
"continueUrl": "http://your.eshop.com/continue",
"notifyUrl": "https://your.eshop.com/notify",
"currencyCode": "PLN",
"totalAmount": 5000,
"extOrderId": "marketplace-order-xyz-123",
"description": "order XYZ-123",
"additionalDescription": "additional description",
"buyer": {
"email": "john.doe@email.com",
"phone": "(012)1234567",
"firstName": "John",
"lastName": "Doe",
"language": "pl",
"extCustomerId": "john-doe-12345"
},
"shoppingCarts": [
{
"extCustomerId": "marketplace-submerchant-1",
"amount": 200,
"fee": 20,
"products": [
{
"name": "product A",
"quantity": 2,
"unitPrice": 100,
"virtual": false,
"listingDate": "2018-01-28T07:17:52Z"
}
]
},
{
"extCustomerId": "marketplace-submerchant-2",
"amount": 1300,
"products": [
{
"name": "product B",
"quantity": 2,
"unitPrice": 200,
"virtual": false,
"listingDate": "2021-02-09T12:17:52Z"
},
{
"name": "product C",
"quantity": 3,
"unitPrice": 300,
"virtual": false,
"listingDate": "2017-09-15T08:15:52Z"
}
]
},
{
"extCustomerId": "marketplace-submerchant-3",
"amount": 3500,
"fee":350,
"products": [
{
"name": "product D",
"quantity": 1,
"unitPrice": 3500,
"virtual": false,
"listingDate": "2020-09-28T08:17:52Z"
}
]
}
]
}'

When the order transaction is successfully authorized, the funds can be allocated to the correct recipients. For the above example, the split looks like this:

  • marketplace-submerchant-1: +1.80 PLN
  • marketplace-submerchant-2: +13.00 PLN
  • marketplace-submerchant-3: +31.50 PLN
  • marketplace fee: +3.70 PLN

For details on parameters, please refer to Create an Order section in our API Reference.

Additional Error Codes for Order Creation

Below are the error codes for the order requests specific to the marketplace, you can find more error codes in the Status Codes section.

Error Codes Specific for Marketplace Order Creation
StatusCodeCodeCodeLiteralDescription
DATA_NOT_FOUND
DATA_NOT_FOUND
9999
Submerchant doesn't exist. Please check if you used correct extCustomerId parameters in the shoppingCarts section.

Notification Example for the Completed Marketplace Transaction

After order is completed you will receive a notification with the status of the order. You can read more in the Notifications section.

{
"order": {
"orderId": "V6V7HHL1H9230518GUEST000P01",
"extOrderId": "Marketplace Standard Order",
"orderCreateDate": "2023-05-18T16:04:35.660+02:00",
"notifyUrl": "https://notifyurl.com",
"customerIp": "127.0.0.1",
"merchantPosId": "199022",
"description": "Marketplace Standard Order",
"currencyCode": "PLN",
"totalAmount": "5000",
"buyer": {
"customerId": "guest",
"email": "john.doe@email.com",
"phone": "654111654",
"firstName": "John",
"lastName": "Doe"
},
"payMethod": {
"amount": "5000",
"type": "PBL"
},
"status": "COMPLETED",
"shoppingCarts": [
{
"extCustomerId": "customer1",
"amount": "5000",
"fee": "1000",
"shippingMethods": [
{
"country": "PL",
"price": "0",
"name": "Shipping Method 1"
}
],
"products": [
{
"name": "product-x",
"unitPrice": "5000",
"quantity": "1"
}
]
}
]
},
"localReceiptDateTime": "2023-05-18T16:04:47.102+02:00",
"properties": [
{
"name": "PAYMENT_ID",
"value": "5007331705"
}
]
}

Retrieving Submerchant Balance

GET Request Body

When making GET requests, please remember not to include any data in the request body, as specified in the RFC 9110 standard. Requests that do not adhere to this requirement will be rejected by PayU with an HTTP 403 status.

You can retrieve the submerchant balance by sending an HTTP GET request to the /api/v2_1/customers/ext/<EXT_CUSTOMER_ID>/balances, specifying balance currency.

Submerchant Balance Retrieve Request Example
curl -v -X GET https://secure.payu.com/api/v2_1/customers/ext/<EXT_CUSTOMER_ID>/balances?currencyCode=PLN \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <AUTH_TOKEN>"
  • EXT_CUSTOMER_ID is submerchant identifier.

For details on parameters, please refer to Retrieve Seller Balance section in our API Reference.

Submerchant Balance Retrieve Response Example
{
"balance": {
"availableAmount": "5494",
"totalAmount": "5500"
},
"status": {
"statusCode": "SUCCESS"
}
}

Withdrawing Funds

Creating a payout for the marketplace is based on the standard payout creation using the REST API. However, the request should be extended with appropriate parameters.

Warning!
extPayoutId Parameter

As the extPayoutId parameter must be unique within the scope of a given shop, upon encountering an error, you should use a different value for the extPayoutId parameter.

Fx-payouts

It is possible to withdraw funds to marketplace sellers accounts in a currency other than the currency of the store. For further information, please refer to the Fx-payouts section.

Your standard payout request should be extended with the account section containing the extCustomerId parameter.

Payout Request Example
curl -X POST https://secure.payu.com/api/v2_1/payouts \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <AUTH_TOKEN>" \
-d '{
"shopId":"shop-id",
"payout": {
"amount": "1000",
"currencyCode": "PLN",
"description": "Some payout",
"extPayoutId": "my_payout_id_123"
},
"account": {
"extCustomerId": "ext-customer-id-1"
}
}'
Notes

In order to make a payout for the marketplace sandbox account use the parameter. extCustomerId with the value of MARKETPLACE_K2_FEE.

For the parameters descriptions, please refer to the Create a Payout section in our API Reference.

Payout Response Example
{
"payout": {
"payoutId": "b3e4fc98c6894239864a9d6941f0fe76",
"extPayoutId": "PAYOUT23423423423",
"extCustomerId": "12345678",
"status": "PENDING"
},
"status": {
"statusCode": "SUCCESS"
}
}

Additional Error Codes for Payout Creation

Below are the error codes for payout requests specific to the marketplace, you can find more error codes for payouts on the Payouts page.

Payout Error Codes Specific for Marketplace
StatusCodeCodeLiteralCodeDescription
ERROR_VALUE_INVALID
AMOUNT_TO_BIG
9103
Payout amount too large.
BUSINESS_ERROR
MARKETPLACE_CUSTOMER_IS_NOT_ACTIVE
9104
Customer is not active.
BUSINESS_ERROR
MARKETPLACE_CUSTOMER_IS_LOCKED
9106
Customer is locked.
ERROR_VALUE_INVALID
MARKETPLACE_CUSTOMER_NOT_VERIFIED
9132
Submerchant is not verified by PayU.
ERROR_VALUE_INVALID
PROVIDING_BANK_ACCOUNT_IS_FORBIDDEN
9133
Bank account is forbidden for marketplace payout.
DATA_NOT_FOUND
CUSTOMER_NOT_FOUND
9999
Submerchant doesn't exist.

Verifying Notification for Payouts

To verify notification for payout you have to calculate a value of sig_ext_order parameter and compare it with the sig_ext parameter in the notification.

To calculate the sig_ext_order parameter you have to:

  1. Create a string, in order, from the parameters: type, merchant_id, payout_id, amount, currency, status, payout_init_date and ts.
  2. Add the second key (e.g. pKGtKJJ8BdLu7TP6) to the end of the generated string and use md5() hash function on the whole string.
Notification Example for the Payout
{
"sig": "53767327a0a6d77974bc08302f5b7df4",
"payout_id": "59aa29da1df743ac96e8c3f281af66fd",
"amount": "2",
"sig_ext": "2ecc4770168fc08d0ed30d871e1c2651",
"payout_init_date": "2021-02-21 15:09:18",
"sig_ext_order": "type,merchant_id,payout_id,amount,currency,status,payout_init_date,ts",
"currency": "PLN",
"merchant_id": "232977",
"type": "payout",
"status": "2",
"ts": "1588597815353"
}

Looking at the example above the sig_ext_order would be calculated as:

md5(payout23297759aa29da1df743ac96e8c3f281af66fd2PLN22021-02-21 15:09:181588597815353pKGtKJJ8BdLu7TP6)

The result of the above function is: 2ecc4770168fc08d0ed30d871e1c2651. This string should be used as a value of the sig_ext_order parameter.

Payout Notification Statuses

The payout status is passed as a code in the status field of the notification. See below for descriptions of possible marketplace payout statuses.

Payout Notification Statuses
Status CodesDescriptionStatus Description
1
Waiting to be processed
Payout is at PayU side. Should be treated as in progress.
2
Processing
Payout is at PayU side. Should be treated as in progress.
3
Cancelled
Funds returned to wallet.
4
Incomplete data
Payout is at PayU side. Should be treated as in progress.
5
Finalized
Funds were sent from PayU to seller.
6
Returned
Funds returned to wallet.
7
Rejected
Payout is at PayU side. Should be treated as in progress.

Retrieving Operation History

GET Request Body

When making GET requests, please remember not to include any data in the request body, as specified in the RFC 9110 standard. Requests that do not adhere to this requirement will be rejected by PayU with an HTTP 403 status.

You can retrieve the submerchant operations history by sending an HTTP GET request to the /api/v2_1/customers/ext/<EXT_CUSTOMER_ID>/operations endpoint, specifying the operations timeframe.

Operation History Retrieve Request Example
curl -X GET \
'https://secure.payu.com/api/v2_1/customers/ext/<EXT_CUSTOMER_ID>/operations?eventDateFrom=<EVENT_DATE_FROM>&eventDateTo=<EVENT_DATE_TO>' \
-H 'Authorization: Bearer <AUTH_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'cache-control: no-cache'
  • EXT_CUSTOMER_ID is submerchant identifier.
Operation History Retrieve Response Example
    "operations": [
{
"type": "PAYMENT_RECEIVED",
"amount": "1500",
"currencyCode": "PLN",
"description": "operation description",
"status": "COMPLETED",
"creationDate": "2016-04-20T11:05:54+02:00",
"eventDate": "2016-04-20T12:05:54+02:00",
"details": {
"orderId": "CWDBL3KD6G170110GUEST000P01",
"extOrderId": "105877825874b0c0b47a0",
"counterparties": [
{
"extCustomerId": "35463545",
"name": "Alice",
"email": "alice@email.com",
"products": [
{
"name": "product-x",
"unitPrice": "1500",
"quantity": "1"
}
]
}
],
"funds": []
}
}
],
"pageResponse": {
"records": "1",
"size": "1",
"pageCount": "1"
}
}

For details on parameters, please refer to Retrieve Seller Operation History section in our API Reference.

Creating a Refund

Creating a refund for the marketplace is based on the standard refund creation using the REST API. However, the request should be extended with appropriate parameters. You can create a partial or full refund for a selected submerchant or for all submerchants involved in the transaction.

If you are sending a partial refund, you should extend refund request with extCustomerId parameter.

Marketplace Refund Example
curl -X POST https://secure.payu.com/api/v2_1/orders/<ORDER_ID>/refunds \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <AUTH_TOKEN>" \
-d '{
"refund": {
"description": "Refund",
"amount": 1000
"extCustomerId": "ext-customer-1",
"extRefundId": "ext-refund-id-1"
}
}'
  • ORDER_ID is order identifier, which refund is created for.

For details on parameters, please refer to Create a Refund section in our API Reference.

Response Example for the Refund Request
{
"status": {
"statusCode": "SUCCESS",
"statusDesc": "Refund queued for processing"
},
"orderId": "47FD97QSPL140325GUEST000P01",
"refund": {
"dispositions": {
"instrumentAmount": "1000",
"walletAmount": "0",
"couponAmount": "0"
},
"refundId": "R84FWMHX6K150901abjtwtchP01",
"extRefundId": "ext-refund-id-1"
}
}

Additional Refund Error Codes for Marketplace

Below are the error codes for refund requests specific to the marketplace, you can find more error codes for refunds in the Error Codes section on the Refunds page.

Refund Error Codes Specific for Marketplace
Status CodeCodeLiteralCodeDescription
BUSINESS_ERROR
AMOUNT_EXCEEDED
9109
Refund amount exceeds amount for given submerchant in order.
BUSINESS_ERROR
AMBIGUOUS_REFUND_SOURCE
9110
Refund can't be realized from more than one source.
BUSINESS_ERROR
EXT_REFUND_ID_MISSING
9116
extRefundId is missing.
BUSINESS_ERROR
NO_SHOPPING_CARTS_IN_ORDER
9118
Missing shopping carts in order.
DATA_NOT_FOUND
MARKETPLACE_TRANSACTION_NOT_FOUND
9119
Order with given identifier doesn't exist.
DATA_NOT_FOUND
CUSTOMER_NOT_FOUND
9999
Submerchant doesn't exist.

Transfering Funds Between Balances

Within scope of the marketplace, you can transfer funds between submerchant and marketplace balances. You can do it by sending an HTTP POST request to the /api/v2_1/customers/ext/<EXT_CUSTOMER_ID>/feeDebitTransfer endpoint.

Notes

To enable this functionality, addTransfering Funds from Submerchant to Marketplace Exampleitional configuration is required on the PayU side, as well as compliance approval. Please to activate this feature.

Examples for Transfering Funds Between Balances

To transfer funds from the submerchant balance to the marketplace balance, you need to send an HTTP POST request to the /api/v2_1/customers/ext/<EXT_CUSTOMER_ID>/feeDebitTransfer endpoint.

curl -X POST https://secure.snd.payu.com/api/v2_1/customers/ext/<EXT_CUSTOMER_ID>/feeDebitTransfer \
-H 'Authorization: Bearer 4b29a650-82b7-4c1b-8b6f-2786edd6d2bd' \
-H 'Content-Type: application/json' \
-H 'Postman-Token: dc779a1e-07d4-4998-bbb6-bb7e0bbbf45b' \
-H 'cache-control: no-cache' \
-d '{
"amount": 25,
"currencyCode": "PLN",
"description": "Get fee for order XX2ORD2",
"extTransferId": "debit-9dbc62be-dfc8-401f-a9f4-79e5013cb734"
}'
  • EXT_CUSTOMER_ID is submerchant identifier.

For details on parameters, please refer to Transfer Funds from Seller to Marketplace Balance section in our API Reference.

Response Example for Transfering Funds Between Balances
{
"extCustomerId": "<extCustomerId>",
"extTransferId": "debit-9dbc62be-dfc8-401f-a9f4-79e5013cb734",
"status": {
"statusCode": "SUCCESS"
}
}

Potential Error Codes for Transfering Funds Between Balances

Error Codes for Transfering Funds Between Balances
Http StatusStatus CodeCodeLiteral
400
BUSINESS_ERROR
MARKETPLACE_TRANSFER_EXISTS
400
BUSINESS_ERROR
MARKETPLACE_NO_BALANCE
400
BUSINESS_ERROR
MARKETPLACE_FEE_TRANSFER_LIMITS_EXCEEDED