Marketplace API
Integracja marketplace opiera się na standardowej integracji, ale została rozszerzona o dodatkowe elementy unikalne dla platform marketplace. Rozszerzenia integracji zostały opisane w tej sekcji.
Uwierzytelnienie żądania
Aby móc komunikować się z systemem PayU, musisz uwierzytelnić żądanie za pomocą tokenu OAuth wygenerowanego w trybie client_credentials
. Informacje na temat uwierzytelniania żądań znajdziesz w sekcji Uwierzytelnianie żądań.
Tworzenie nowego zamówienia
Rozszerzenia standardowego zamówienia
Podczas tworzenia nowego zamówienia dla marketplace, musisz dodać sekcję shoppingCarts
do swojego żądania. Ta sekcja definiuje dystrybucję środków do poszczególnych submerchantów.
Kolejną ważną różnicą w stosunku do standardowego zamówienia jest parametr extCustomerId
dodany do sekcji buyer
. Ten parametr identyfikuje submerchanta uczestniczącego w transakcji.
Dodatkowo jeżeli oferujesz rozwiązanie white label musisz dodać do żądania sekcję payMethods
, precyzującą wybraną metodę płatności.
- shoppingCarts
- buyer
- payMethods
...
"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"
}
]
}
]
...
extCustomerId
z sekcji shoppingCarts
i buyer
różnią się i nie są tym samym bytem. W sekcji shoppingCarts
, parametr ten określa submerchanta uczęstniczącego w transakcji. W sekcji buyer
identyfikuje płatnika.
Suma parametrów price
i iloczynu parametrów unitPrice
i quantity
musi być równa wartości parametru amount
w zakresie submerchanta.
Suma wszystkich parametrów amount
w zakresie żądania musi być równa wartości parametru totalAmount
.
Do żądania musisz dodać sekcję buyer
rozszerzoną o parametr extCustomerId
, który jest identyfikatorem submerchanta nadanym przez marketplace:
...
"buyer": {
"email": "john.doe@email.com",
"phone": "(012)1234567",
"firstName": "John",
"lastName": "Doe",
"language": "pl",
"extCustomerId": "john-doe-12345"
},
...
Jeżeli korzystasz z rozwiązania white label, musisz dodać do żądania sekcję payMethods
, w której zawarta będzie wybrana przez kupującego metoda płatności.
...
"currencyCode": "PLN",
"totalAmount": 5000,
...
"payMethods": {
"payMethod": {
"type": "PBL",
"value": "m",
"amount": 5000
}
}
...
Szczegóły parametrów, znajdziesz w sekcji Create an Order w naszej referencji API.
Przykłady zamówienia marketplace
- Standardowe
- white label
Poniżej znajdziesz przykład żądania zamówienia marketplace, w którym klient kupuje wiele produktów od trzech submerchantów w ramach jednej transakcji.
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"
}
]
}
]
}'
Gdy zamówienie zostanie pomyślnie uwierzytelnione, środki mogą zostać przydzielone właściwym odbiorcom. W powyższym przykładzie podział wygląda następująco:
- marketplace-submerchant-1: +1.80 PLN
- marketplace-submerchant-2: +13.00 PLN
- marketplace-submerchant-3: +31.50 PLN
- marketplace fee: +3.70 PLN
Poniżej znajduje się przykład zamówienia white label z sekcją payMethods
, z wybraną metodą płatności.
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": "2020-09-28T08:17:52Z"
}
]
},
{
"extCustomerId": "marketplace-submerchant-2",
"amount": 1300,
"products": [
{
"name": "product B",
"quantity": 2,
"unitPrice": 200,
"virtual": false,
"listingDate": "2018-09-28T08:17:52Z"
},
{
"name": "product C",
"quantity": 3,
"unitPrice": 300,
"virtual": false,
"listingDate": "2019-09-04T08:19:30Z"
}
]
},
{
"extCustomerId": "marketplace-submerchant-3",
"amount": 3500,
"fee":350,
"products": [
{
"name": "product D",
"quantity": 1,
"unitPrice": 3500,
"virtual": false,
"listingDate": "2020-09-28T08:17:52Z"
}
]
}
],
"payMethods": {
"payMethod":{
"type":"PBL",
"value":"m",
"amount":5000
}
}
}'
Szczegóły parametrów, znajdziesz w sekcji Create an Order w naszej referencji API.
Dodatkowe kody błedów dla marketplace
Poniżej znajdują się kody błędów dla zamówień specyficznych dla marketplace, więcej kodów błędów znajdziesz w sekcji Kody statusów.
Kod statusu | Kod | CodeLiteral | Opis |
---|---|---|---|
DATA_NOT_FOUND | DATA_NOT_FOUND | 9999 | Sprzedający nie istnieje w systemie PayU. Sprawdź czy użyłeś poprawnego parametru extCustomerId w sekcji shoppingCarts . |
Przykład powiadomienia dla zakończonej transakcji marketplace
Po złożeniu zamówienia otrzymasz powiadomienie o jego statusie. Więcej informacji znajdziesz w sekcji Powiadomienia.
{
"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"
}
]
}
Pobieranie salda submerchanta
Wysyłając żądania z metodą GET upewnij się, że w ciele żądania nie przesyłasz żadnych danych. Zgodnie ze standardem RFC 9110 żądania, które nie spełniają tego wymogu, zostaną odrzucone przez PayU i zwrócony zostanie kod HTTP 403.
Saldo submerchanta możesz pobrać wysyłając żądanie HTTP GET na endpoint /api/v2_1/customers/ext/<EXT_CUSTOMER_ID>/balances
, określająć walutę salda w parametrze currencyCode
.
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
jest identyfikatorem submerchanta.
Szczegółowy parametrów znajdziesz w sekcji Retrieve Seller Balance w naszej referencji API.
{
"balance": {
"availableAmount": "5494",
"totalAmount": "5500"
},
"status": {
"statusCode": "SUCCESS"
}
}
Wypłacanie środków
Tworzenie wypłaty dla marketplace opiera się na standardowym sposobie tworzenia wypłat za pomocą REST API. Żądanie należy jednak rozszerzyć o odpowiednie parametry.
Ponieważ parametr extPayoutId
musi być unikalny w zakresie danego sklepu, po napotkaniu błędu musisz użyć dla niego innej wartości.
Możliwe jest wypłacanie środków na konta sprzedawców marketplace w walucie innej niż waluta sklepu. Więcej informacji znajdziesz na stronie wypłaty wielowalutowe.
Standardowe żądanie wypłaty powinno zostać rozszerzone o sekcję account
zawierającą parametr extCustomerId
.
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"
}
}'
Aby wykonać wypłatę dla marketplace na środowisku sandbox musisz użyć parametru extCustomerId
ustawionego na MARKETPLACE_K2_FEE.
Szczegóły parametrów znajdziesz w sekcji Create a Payout w naszej referencji API.
{
"payout": {
"payoutId": "b3e4fc98c6894239864a9d6941f0fe76",
"extPayoutId": "PAYOUT23423423423",
"extCustomerId": "12345678",
"status": "PENDING"
},
"status": {
"statusCode": "SUCCESS"
}
}
Dodatkowe kody błędów dla wypłat
Poniżej znajdują się kody błędów dla żądań wypłat specyficznych dla marketplace, więcej kodów błędów dla wypłat znajdziesz na stronie przeznaczonej wypłatom.
Kod statusu | CodeLiteral | Kod | Opis |
---|---|---|---|
ERROR_VALUE_INVALID | AMOUNT_TO_BIG | 9103 | Zbyt duża kwota wypłaty. |
BUSINESS_ERROR | MARKETPLACE_CUSTOMER_IS_NOT_ACTIVE | 9104 | Sprzedawca jest nieaktywny. |
BUSINESS_ERROR | MARKETPLACE_CUSTOMER_IS_LOCKED | 9106 | Sprzedawca jest zablokowany. |
ERROR_VALUE_INVALID | MARKETPLACE_CUSTOMER_NOT_VERIFIED | 9132 | Sprzedający nie został jeszcze zweryfikowany przez PayU. |
ERROR_VALUE_INVALID | PROVIDING_BANK_ACCOUNT_IS_FORBIDDEN | 9133 | Podanie numeru konta do wypłaty jest zabronione. |
DATA_NOT_FOUND | CUSTOMER_NOT_FOUND | 9999 | Sprzedający nie istnieje w systemie PayU. |
Weryfikacja powiadomienia dla wypłat
Aby zweryfikować powiadomienie dla wypłaty musisz obliczyć wartość parametru sig_ext_order
i porównać ją z parametrem sig_ext
znajdującym się w notyfikacji.
Aby obliczyć parametr sig_ext_order
musisz:
- Stworzyć ciag znaków składający się z wartości parametrów:
type
,merchant_id
,payout_id
,amount
,currency
,status
,payout_init_date
andts
. - Na końcu stworzonego ciągu musisz dodać wartość **drugiego klucza (e.g. pKGtKJJ8BdLu7TP6). Następnie musisz użyć funkcji
md5()
na całym ciągu.
{
"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"
}
Biorąc pod uwagę powyższy przykład, parametr sig_ext_order
jest obliczany w następujący sposób:
md5(payout23297759aa29da1df743ac96e8c3f281af66fd2PLN22021-02-21 15:09:181588597815353pKGtKJJ8BdLu7TP6)
Wynikiem powyższej funkcji jest: 2ecc4770168fc08d0ed30d871e1c2651, co powinno być użyte jako wartość parametru sig_ext_order
.
Statusy powiadomień wypłat
Status w notyfikacji jest przysyłany w jako kod w polu status
. Poniżej przedstawiona jest tabela z opisami poszczególnych kodów.
Kod Statusu | Opis | Opis statusu |
---|---|---|
1 | Waiting to be processed | Wypłata jest po stronie PayU. Powinna być traktowana jako w toku. |
2 | Processing | Wypłata jest po stronie PayU. Powinna być traktowana jako w toku. |
3 | Cancelled | Środki zostały zwrócone do portfela. |
4 | Incomplete data | Wypłata jest po stronie PayU. Powinna być traktowana jako w toku. |
5 | Finalized | Środki zostały przekazane dla sprzedającego. |
6 | Returned | Środki zostały zwrócone do portfela. |
7 | Rejected | Wypłata jest po stronie PayU. Powinna być traktowana jako w toku. |
Pobieranie historii operacji
Wysyłając żądania z metodą GET upewnij się, że w ciele żądania nie przesyłasz żadnych danych. Zgodnie ze standardem RFC 9110 żądania, które nie spełniają tego wymogu, zostaną odrzucone przez PayU i zwrócony zostanie kod HTTP 403.
Historię operacji submerchant możesz pobrać, wysyłając żądanie HTTP GET na endpoint /api/v2_1/customers/ext/<EXT_CUSTOMER_ID>/operations
, określając zakres czasowy.
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
jest unikalnym identyfikatorem submerchanta.
Szczegóły parametrów znajdziesz w sekcji Retrieve Seller Operation History naszej referencji API.
"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"
}
}
Tworzenie zwrotu
Tworzenie zwrotu dla marketplace opiera się na standardowej integracji zwrotów z REST API. Żądanie należy jednak rozszerzyć o odpowiednie parametry. Możesz utworzyć częściowy lub pełny zwrot dla wybranego submerchanta lub dla wszystkich submerchantów zaangażowanych w transakcję.
Jeżeli wysyłasz żądanie częściowego zwrotu, powinieneś rozszerzyć je o parametr extCustomerId
.
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
jest identyfikatorem zamówienia, dla którego został utworzony zwrot.
Szczegóły parametrów znajdziesz w sekcji Create a Refund w naszej referencji API.
{
"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"
}
}
Kody błędów zwrotów specyficzne dla marketplace
Poniżej znajdują się kody błędów dla żądań zwrotów specyficznych dla marketplace. Więcej kodów błędów dla zwrotów znajdziesz w sekcji Kody błedów.
Kod statusu | CodeLiteral | Kod | Opis |
---|---|---|---|
BUSINESS_ERROR | AMOUNT_EXCEEDED | 9109 | Kwota zwrotu przekracza kwotę dla danego sprzedającego w zamówieniu. |
BUSINESS_ERROR | AMBIGUOUS_REFUND_SOURCE | 9110 | Zwrot nie może być z realizowany z więcej niż jednego źródła. |
BUSINESS_ERROR | EXT_REFUND_ID_MISSING | 9116 | Pole extRefundId nie zostało podane. |
BUSINESS_ERROR | NO_SHOPPING_CARTS_IN_ORDER | 9118 | Brak produktów w zamówieniu. |
DATA_NOT_FOUND | MARKETPLACE_TRANSACTION_NOT_FOUND | 9119 | Zamówienie o podanym identyfikatorze nie istnieje. |
DATA_NOT_FOUND | CUSTOMER_NOT_FOUND | 9999 | Sprzedający nie istnieje w systemie PayU. |
Przesyłanie środków pomiędzy saldami
W ramach marketplace możesz przelewać środki między saldami submerchanta i marketplace. Możesz to zrobić wysyłając żądanie HTTP POST na endpoint /api/v2_1/customers/ext/<EXT_CUSTOMER_ID>/feeDebitTransfer
.
Aby włączyć tę funkcję, wymagana jest dodatkowa konfiguracja po stronie PayU, a także zgoda działu compliance. Aby aktywować tą funkcję skontaktuj się działem wsparcia PayU.
Przykłady transferu środków pomiędzy saldami
- Od submerchanta do marketplace
- Od marketplace do submerchanta
Aby przesłać środki z salda submerchanta na saldo marketplace musisz wysłać żądanie HTTP POST na endpoint /api/v2_1/customers/ext/<EXT_CUSTOMER_ID>/feeDebitTransfer
.
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
jest identyfikatorem submerchanta.
Szczegóły parametrów znajdziesz w sekcji Transfer Funds from Seller to Marketplace Balance w naszej referencji API.
Aby przesłać środki z salda marketplace na saldo submerchanta musisz wysłać żądanie HTTP POST na endpoint /api/v2_1/customers/ext/<EXT_CUSTOMER_ID>/feeCreditTransfer
.
curl -X POST https://secure.snd.payu.com/api/v2_1/customers/ext/<EXT_CUSTOMER_ID>/feeCreditTransfer \
-H 'Authorization: Bearer 4b29a650-82b7-4c1b-8b6f-2786edd6d2bd' \
-H 'Content-Type: application/json' \
-H 'Postman-Token: 9f9a1496-1864-4856-9b50-699fc1e0ef1f' \
-H 'cache-control: no-cache' \
-d '{
"amount": 25,
"currencyCode": "PLN",
"description": "Return fee for order XXX1ORD",
"extTransferId": "credit-63a3e837-ba7e-45a0-b1b5-267e2c237cd6"
}'
EXT_CUSTOMER_ID
jest identyfikatorem submerchanta.
Szczegóły parametrów znajdziesz w sekcji Transfer Funds from Marketplace to Seller Balance w naszej referencji API.
{
"extCustomerId": "<extCustomerId>",
"extTransferId": "debit-9dbc62be-dfc8-401f-a9f4-79e5013cb734",
"status": {
"statusCode": "SUCCESS"
}
}
Kody błędów dla transferu środków między saldami
Status Http | Kod statusu | CodeLiteral |
---|---|---|
400 | BUSINESS_ERROR | MARKETPLACE_TRANSFER_EXISTS |
400 | BUSINESS_ERROR | MARKETPLACE_NO_BALANCE |
400 | BUSINESS_ERROR | MARKETPLACE_FEE_TRANSFER_LIMITS_EXCEEDED |