Marketplace
Overview
Marketplace enables platforms (partners) to process payments where multiple sellers participate in a single transaction. Within one payment you define transfers to sellers, and Paynow splits the funds automatically.
This document covers Marketplace-specific features (seller boarding, transfers, BPP, marketplace refunds/vouchers). General integration topics (e.g. notifications, payment status diagrams, generic Signature calculation rules) are described in the base Paynow documentation — we do not duplicate them here.
Integration checklist
Use the checklist below to make sure that you have correctly integrated with paynow services.
- Create sandbox account here.
- Contact with Paynow support to activate marketplace feature
- Create seller shop for your marketplace Seller Boarding
- Find credentials for your markeplace API access
- Integrate with Paynow API.
- Configure notification address
- Make a payment - test positive and negative payment path
- If Buyer Protection Program is enabled for the seller Confirm transfer
- Make a refund
- (Optional) Make a refund with bank transfer - for sellers without enough funds on their balance
- (Optional) Vouchers
Concepts and settlement model
Seller
A seller is identified in Paynow by sellerId (format like XXX-XXX-XXX-XXX). Sellers are onboarded into your marketplace using Seller Boarding.
Transfers inside a payment
In a Marketplace payment you pass transfers[], where for each seller you provide:
sellerId— Paynow seller identifiergrossAmount— gross amount assigned to the sellerfeeAmount— marketplace fee deducted from the seller’s transfer
The sum of all transfers[].grossAmount must equal the payment amount.
Seller Boarding
The process is initiated by the partner request. After initiating the process, the paynow system returns the sellerApplicationUrl to which the customer should be redirected in order to perform the following steps:
- fill in the registration form,
- verify identity,
- verify settlement account.
Once the process is complete, Paynow delivers asynchronous notifications about the current seller status (COMPLETED or CANCELED). At any time, the partner can retrieve the process status for the seller's data by sending the get status request.
Initialize seller boarding
POST /v3/boarding/merchants/sellers/init
Request body (minimum):
{
"nip": "1145934848"
}
Optional:
notificationUrl— URL for seller status notifications (notification mechanism is described in base docs).
Response (201):
{
"sellerId": "MBC-G58-B69-AT2",
"sellerApplicationUrl": "https://panel.paynow.pl/...",
"status": "NEW"
}
Get seller application status
GET /v3/boarding/merchants/sellers/{sellerId}
Response (200):
{
"sellerId": "MBC-G58-B69-AT2",
"sellerApplicationUrl": "https://panel.paynow.pl/...",
"status": "COMPLETED"
}
Statuses:
| Status | Description |
|---|---|
NEW | Process has been created |
IN_VERIFICATION | Waiting for seller verification |
VERIFICATION_FAILED | Seller verification has failed |
AML_VERIFICATION | Application is being verified by Paynow |
COMPLETED | Process has been successfully completed |
CANCELED | Process has been canceled |
Marketplace payments
Each payment request must contain an 'externalId' that is assigned by the Merchant during creation. It uniquely identifies the payment on the Merchant's side.
The description field can contain any text that helps to identify the payment.
The buyer field must include, at a minimum, the email address of the Buyer making the payment and may contain other fields to describe the Buyer.
The transfer list contains all the sellers participating in the payment. All fields are required
- sellerId from the seller boarding
- sum of the gross amounts must be equal to the amount of payment
- fee amount must be lower than the gross amount
Create payment with transfers
POST /v3/payments
Unlike a standard payment, a Marketplace payment includes transfers[] with per-seller split.
Example request body:
{
"amount": 45671,
"externalId": "234567898654",
"description": "Test transaction",
"buyer": {
"email": "jan.kowalski@example.pl"
},
"transfers": [
{
"sellerId": "MB9-CWR-7R9-QMP",
"grossAmount": 32175,
"feeAmount": 500
},
{
"sellerId": "MB2-GRP-A23-P10",
"grossAmount": 13496,
"feeAmount": 60
}
]
}
Example response (201):
{
"redirectUrl": "https://paywall.sandbox.paynow.pl/NOLV-8F9-08K-WGD?token=...",
"paymentId": "NOLV-8F9-08K-WGD",
"status": "NEW"
}
The response contains the URL that the Buyer should be redirected to, ID of the payment generated by Paynow, and the current status of the payment.
Returned paymentId should be saved by Merchant for further reference.
feeAmount is deducted from the seller transfer. Make sure feeAmount < grossAmount.
Buyer Protection Program (BPP): confirm/cancel transfers
The Buyer Protection Program can be enabled for individual sellers, which means that the funds will not go immediately to withdrawal, but will wait for confirmation or cancellation of the transfers. Confirmation of the transfer will result in the withdrawal of funds to the seller. Cancellation of the transfer will automatically return the funds to the buyer. NOTE: If a request for cancellation is not sent or processed correctly then an automatic confirm will be executed after the set time. The time is set individually for each marketplace. In order to activate Buyer Protection Program please contact support@paynow.pl
- Confirm transfer — funds will be paid out to the seller
- Cancel transfer — funds will be refunded to the buyer
PATCH /v3/payments/{paymentId}/confirm
{
"sellers": ["MB3-4FF-IXA-ACM"]
}
The seller list contains at least one sellerId of the seller who participated in the payment.
PATCH /v3/payments/{paymentId}/cancel
{
"sellers": ["MB3-4FF-IXA-ACM"]
}
The seller list contains at least one sellerId of the seller who participated in the payment.
Marketplace refunds
Payment may be refunded multiple times for a total amount not exceeding the payment amount and it is allowed only for payments in status CONFIRMED.
Paynow accepts refunds with a minimum amount 1 PLN for CARD payment, for other 0.01 PLN.
There are two ways to make a Marketplace refund:
- refund with per-seller split — funded from the seller balances (and the marketplace balance for the fee),
- refund with bank transfer — for a single seller, funded by a dedicated bank transfer; use it when the seller does not have enough funds on the balance.
Create refund with per-seller split
POST /v3/payments/{paymentId}/refunds
For Marketplace refunds you pass transfers[] similar to a Marketplace payment (refund split across sellers + fee refund).
Example request body:
{
"amount": 212,
"reason": "RMA",
"transfers": [
{
"sellerId": "MB9-CWR-7R9-QMP",
"grossAmount": 135,
"feeAmount": 23
},
{
"sellerId": "MB2-GRP-A23-P10",
"grossAmount": 77,
"feeAmount": 7
}
]
}
The provided amount should be given in the smallest unit of refund currency (grosz in case of PLN). This means that the above request defines a refund for 2.12 PLN.
The transfer list contains all the sellers who participated in the payment and whose products will be the object of this refund. All fields are required
- sellerId from the seller boarding
- gross amount and fee amount cannot be greater than the amounts from transfer in the payment request
- sum of the the gross amounts must be equal to the refund amount
The sum of all transfers[].grossAmount must equal the refund amount.
Optionally, you can add the notificationUrl field to receive refund status notifications.
Handle the returned response:
{
"refundId": "R3FU-UND-D8K-WZD",
"status": "PENDING"
}
The response contains ID of the refund generated by Paynow and the current status of the refund.
Returned refundId should be saved by Merchant for further reference.
For each seller, grossAmount minus feeAmount is charged from the seller balance and feeAmount from the marketplace
balance. If there are not enough funds, the request is rejected with the INSUFFICIENT_BALANCE_FUNDS error. In that
case you can use a refund with bank transfer.
Refund with bank transfer
POST /v3/payments/{paymentId}/refunds/accounts
A refund with bank transfer lets you refund a payment even if the seller does not have enough funds on the balance (e.g. a seller with few transactions, or one who has stopped selling on your platform). The refund is not charged from the seller balance. Instead, Paynow returns the details of a bank transfer that must be made to cover the refund. When the transfer is booked on the Paynow refund account, the refund is processed and the money is transferred to the buyer.
The general flow is described in Refunds. In Marketplace:
- (Optional) You request a refund with per-seller split and receive the
INSUFFICIENT_BALANCE_FUNDSerror. - You request a refund with bank transfer for the seller (
sellerId), setting how long Paynow should wait for the transfer (validityTime). - Paynow creates the refund in
NEWstatus and returnsbankTransferData. - You present
bankTransferDatato the seller, who makes the bank transfer. - When the transfer is booked, the refund is processed. If it is not booked within
validityTime, the refund is cancelled (CANCELLED).
Example request body:
{
"amount": 10000,
"reason": "RMA",
"validityTime": 432000,
"sellerId": "MB9-CWR-7R9-QMP",
"notificationUrl": "https://marketplace.example.com/paynow/refund-notifications"
}
amount(required) – refund amount in the smallest currency unit; cannot exceed thegrossAmountassigned to the seller in the payment (reduced by any previous refunds for this seller).validityTime(required) – time in seconds that Paynow waits for the bank transfer (259200to864000, i.e. from 3 to 10 days).sellerId(required for Marketplace payments) – identifier of the seller who participated in the payment and whose transfer isCONFIRMED. One request covers a single seller and the bank transfer covers the fullamount(no marketplacefeeAmountis charged from the marketplace balance).reason(optional) – refund reason (RMA,REFUND_BEFORE_14,REFUND_AFTER_14,OTHER).notificationUrl(optional) – URL for refund status notifications.
Example response (201):
{
"refundId": "R3FU-UND-D8K-WZD",
"status": "NEW",
"bankTransferData": {
"accountNumber": "{refund-account-number}",
"amount": 10000,
"currency": "PLN",
"title": "{transfer-title}",
"recipientName": "{recipient-name}",
"recipientAddress": "{recipient-address}"
}
}
Returned refundId should be saved by Merchant for further reference. Until the transfer is booked, the refund stays in
NEW status and can be cancelled.
The transfer must exactly match the returned bankTransferData – the same amount and currency, to the given account
number and with the given title. Otherwise Paynow will not be able to match the transfer with the refund and the
refund will not be processed.
Refund status
GET /v3/refunds/{refundId}/status
Instead of querying the status, you can pass notificationUrl when you request a refund – both a
refund with per-seller split and a refund with bank transfer. Paynow
will then send a notification when the refund reaches its final status (SUCCESSFUL, FAILED or CANCELLED). It is
especially useful for refunds with bank transfer, which may be completed even several days after they were requested.
The notification mechanism is described in Refunds.
Seller balances
As a marketplace, it's possible to get sellers balances using the endpoint described below.
GET /v3/balances/sellers/{sellerId}
Response example:
{
"balance": {
"amount": 500
},
"escrow": {
"amount": 100
}
}
where balance.amount is the seller balance available to payout or make a refund
and escrow.amount is the seller balance frozen due to the buyer protection program.
If balance.amount is not enough to cover a refund, you can use a refund with bank transfer.
Vouchers in Marketplace
Marketplace supports scenarios where part of the order amount is covered by a voucher. Voucher is an unique payment option. Platform buys vouchers for given amount and then distributes them across buyers. When buyer enters voucher code during checkout process, total amount is reduced by voucher amount. During processing of the payment sellers receive both money from buyer and voucher divided proportionaly to the share of original transaction.
Voucher reservation
To use a voucher card in payment, the first step is to make a reservation of voucher funds by making a request as in the example below.
A complete and up-to-date list of transfers with vendors and grossAmount is, in turn, necessary for proper processing of the payment initialization process. If the shopping cart is changed, it is also necessary to make the voucher reservation again.
NOTE: Second request with the same voucher card code cancels the reservation from the first request as long as the payment has not been initialized or revoked.
NOTE: Unused reservations will be canceled after a certain period of time. For details, please contact support.
NOTE: The voucher reservation lifetime is an important factor in determining the appropriate payment expiration time (field validityTime in create payment request).
POST /v3/vouchers/reservations
Example request body:
{
"voucherCode": "VC1-ABC-DEF-GHI",
"amount": 45671,
"transfers": [
{
"sellerId": "MB9-CWR-7R9-QMP",
"grossAmount": 32175
},
{
"sellerId": "MB2-GRP-A23-P10",
"grossAmount": 13496
}
]
}
The amount and grossAmount should be specified in the smallest unit of the order currency (grosz in the case of PLN). It means that the above request defines a order of 456.71 PLN.
The transfer list contains all the sellers participating in the reservation and further payment. All fields are required
- sellerId from the seller boarding
- sum of the transfers gross amounts must be equal to the amount of order
Example response (200):
{
"voucherReservationId": "ABC-123-456-789",
"payerAmount": 15671,
"voucherAmount": 30000,
"transfers": [
{
"sellerId": "MB9-CWR-7R9-QMP",
"payerGrossAmount": 11041,
"voucherGrossAmount": 21134,
},
{
"sellerId": "MB2-GRP-A23-P10",
"payerGrossAmount": 4630,
"voucherGrossAmount": 8866,
}
]
}
Returned voucherReservationId should be saved by Merchant for further reference in payment request.
Value of payerAmount indicates how much the payer has to pay for the order (cannot be lower than 1.00 PLN).
Value of voucherAmount indicates how much of the order will be covered by the voucher card.
The amount from the voucher card is divided proportionally among the sellers according to the specified grossAmount in the request for voucher card reservation. The response contains information on how this amount was divided.
Bad Request The below table defines the Error Types that voucher reservation endpoint may return
| Error Type | Reason | Value |
|---|---|---|
| PAYMENT_AMOUNT_TOO_LARGE | If amount is too large. | String value of the maximum amount allowed to make voucher reservation |
| PAYMENT_AMOUNT_TOO_SMALL | If amount is too small. | String value of the minimum amount required to make voucher reservation |
| ORDER_AMOUNT_TOO_SMALL_FOR_VOUCHER | If amount is smaller than the minimum order amount. | String value of the minimum amount required to make voucher reservation |
| INVALID_SUM_OF_TRANSFERS_GROSS_AMOUNT | If the sum of transfers.amount is not equal to amount. | |
| VOUCHER_CARD_EXPIRED | If the voucher card is expired. | |
| VOUCHER_CARD_NO_FUNDS | If there are no funds on the voucher card. |
Payment with voucher
To create a payment with a voucher card it's required to provide the previously obtained voucherReservationId.
NOTE: The payment amount and list of transfers along with sellerId and grossAmount must be the same as when making a reservation on the voucher card.
Example request body:
{
"amount": 45671,
"externalId": "234567898654",
"description": "Test transaction",
"buyer": {
"email": "jan.kowalski@melements.pl"
},
"voucherReservationId": "ABC-123-456-789",
"transfers": [
{
"sellerId": "MB9-CWR-7R9-QMP",
"grossAmount": "32175",
"feeAmount": "500"
},
{
"sellerId": "MB2-GRP-A23-P10",
"grossAmount": "13496",
"feeAmount": "60"
}
]
}
The amount specified should be in the smallest unit of the payment currency ( grosz in the case of PLN). It means that the above request defines a payment for 456.71 PLN.
Each payment request must contain an 'externalId' that is assigned by the Merchant during creation. It uniquely identifies the payment on the Merchant's side.
The description field can contain any text that helps to identify the payment.
The buyer field must include, at a minimum, the email address of the Buyer making the payment and may contain other fields to describe the Buyer.
The transfer list contains all the sellers participating in the payment. All fields are required
- sellerId from the seller boarding
- sum of the gross amounts must be equal to the amount of payment
- fee amount must be lower than the gross amount
Example reponse
{
"redirectUrl": "https://paywall.sandbox.paynow.pl/NOLV-8F9-08K-WGD?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwb3NJZCI6IjEwMDAiLCJwYXltZW50SWQiOiJOT0xWLThGOS0wOEstV0dEIiwiZXhwIjoxNTU0ODEzMTY4fQ.71TLjI8U8p0c_hhC1Nj3cAPU3mtzYW4ylGo8qVeB18o",
"paymentId": "NOLV-8F9-08K-WGD",
"status": "NEW"
}
Make a refund to payment with voucher card
The process of creating a refund to a payment with a voucher card is the same as creating a refund to a payment without the voucher card Creating a refund.
The main difference lies in the behind-the-scenes operations and the addition of two extra fields in the response.
When processing a partial refund, the system will attempt to return as much of the refunded amount as possible to the payer, based on the amount they actually paid and the portion used from the voucher.
Only after the full expected amount has been refunded to the payer will the remaining amount be refunded to the voucher.
If the refunded amount is equal to the full amount from the original payment, then the payerAmount and voucherAmount will match the values from that payment.
Response from refund request endpoint will have 2 additional fields so you need to handle payer amount and voucher amount fields.
Handle the returned response
{
"refundId": "REF-UND-D8K-WZD",
"status": "PENDING",
"payerAmount": 50,
"voucherAmount": 10
}
payerAmount field represents the amount that will be returned directly to payer while voucherAmount represents the amount that will be returned to voucher card used in the related payment.
The same applies to a refund with bank transfer – its response also contains
payerAmount and voucherAmount, and bankTransferData.amount covers the whole refund amount (both parts):
{
"refundId": "R3FU-UND-D8K-WZD",
"status": "NEW",
"payerAmount": 8999,
"voucherAmount": 1100,
"bankTransferData": {
"accountNumber": "{refund-account-number}",
"amount": 10099,
"currency": "PLN",
"title": "{transfer-title}",
"recipientName": "{recipient-name}",
"recipientAddress": "{recipient-address}"
}
}
For full request/response schemas and field types, refer to the API Reference docs. This document intentionally focuses on Marketplace extensions and business-level description.