payouts

Payouts API Integration

This page describes how to use the Payouts API to send up to 15,000 individual payouts in one API call to an email address, US mobile phone number, or Payer ID (an encrypted PayPal account number).

Set up your development environment

Before you can integrate Payouts, you must set up your development environment. After you get a token that lets you access protected REST API resources, you create sandbox accounts to test your web and mobile apps. For details, see Get Started.

Then, return to this page to integrate Payouts.

Create payout

You make payouts in asynchronous payout mode.

In this mode, you can specify up to 15,000 individual payouts in one API call. Exceeding 15,000 payouts in one call returns the HTTP 400 (Bad Request) status code.

The create payout request must include a sender_batch_header object.

Either the sender_batch_header object or each payout item object must include a recipient_type, which specifies the type of receiver data that identifies the recipient.

The recipient_type has one of these values:

EMAIL Unencrypted email.
PAYPAL_ID Encrypted PayPal account number.
PHONE Unencrypted phone number.

These rules apply to the recipient_type:

  • If the sender_batch_header includes a recipient_type, payout items without a specified recipient_type use the recipient_type in the header.

  • If the sender_batch_header omits the recipient_type value, each payout item must include its own recipient_type value.

Include the payouts to individual recipients in the items array in the JSON request body. Specify data for a single payout to one recipient in each item in the array. All items in a payout must specify the same currency.

This sample request creates a payout for four recipients. Because sync_mode=false is the default, it is omitted from the URI.

In this request, the sender_batch_header does not contain a recipient_type attribute. Consequently, each payment in the items array must define a recipient_type:

curl -v -X POST https://api.sandbox.paypal.com/v1/payments/payouts \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer Access-Token" \
  -d '{
  "sender_batch_header": {
    "sender_batch_id": "2014021801",
    "email_subject": "You have a payout!",
    "email_message": "You have received a payout! Thanks for using our service!"
  },
  "items": [
    {
      "recipient_type": "EMAIL",
      "amount": {
        "value": "9.87",
        "currency": "USD"
      },
      "note": "Thanks for your patronage!",
      "sender_item_id": "201403140001",
      "receiver": "receiver@example.com"
    },
    {
      "recipient_type": "PHONE",
      "amount": {
        "value": "112.34",
        "currency": "EUR"
      },
      "note": "Thanks for your support!",
      "sender_item_id": "201403140002",
      "receiver": "91-734-234-1234"
    },
    {
      "recipient_type": "PHONE",
      "amount": {
        "value": "5.32",
        "currency": "USD"
      },
      "note": "Thanks for your patronage!",
      "sender_item_id": "201403140003",
      "receiver": "408-234-1234"
    },
    {
      "recipient_type": "PHONE",
      "amount": {
        "value": "5.32",
        "currency": "USD"
      },
      "note": "Thanks for your patronage!",
      "sender_item_id": "201403140004",
      "receiver": "408-234-1234"
    }
  ]
}'

An EMAIL recipient type uses the recipient email address to identify the recipient. A PHONE recipient type uses a domestic phone number to identify the recipient.

Tip: Make test calls to the Payments API using the PayPal API Explorer.

For information about the URI parameters, see Parameters. For information about request body parameters, see Request.

The response shows information about the payout, including the payout ID:

{
  "batch_header": {
    "sender_batch_header": {
      "sender_batch_id": "2014021801",
      "email_subject": "You have a payout!"
    },
    "payout_batch_id": "12345678",
    "batch_status": "PENDING"
  }
}

Show payout details

To show details for all items in your payout, use the payout_batch_id from the previous response. You can specify the option fields query parameter to filter the fields that are returned in the response. This example specifies fields=batch_header, which tells the API to return only the batch_header in the response:

curl -v -X GET https://api.sandbox.paypal.com/v1/payments/payouts/12345678?fields=batch_header \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer Access-Token"

The response shows only batch header information for the payout. The batch header information includes the payout batch ID, the batch status, and other information:

{
  "batch_header": {
    "payout_batch_id": "12345678",
    "batch_status": "ACKNOWLEDGED",
    "time_created": "2014-01-27T10:17:00Z",
    "time_completed": "2014-01-27T11:17:39.00Z",
    "sender_payout_header": {
      "sender_batch_id": "2014021801",
      "email_subject": "You have a payout!"
    },
    "amount": {
      "value": "435.85",
      "currency": "USD"
    }
  }
}

For information about the response fields, see Response.

Duplicate payout requests

PayPal prevents duplicate batches from being processed. If you specify a sender_batch_id that was used in the last 30 days, the API rejects the request and returns an error message that indicates the duplicate sender_batch_id and includes a HATEOAS link to the original batch payout with the same sender_batch_id. If you receive an HTTP 5nn status code, you can safely retry the request with the same sender_batch_id. In any case, the API completes a payment only once for a specific sender_batch_id that is used within 30 days.

For more information about the payout status values, see payout_enumerations in the Payouts API reference pages.

Test Payouts

The PayPal sandbox enables you to pass specific information in a request to simulate positive and negative test scenarios. The simulated responses mimic actual API responses without calling downstream services. You can handle these responses in your code to manage your buyer’s experience.

For easy API development and testing, download the latest version of Postman. Then, download the Payouts collection .

Permissions

Before you trigger a simulation, you need to create a PayPal app and generate a valid access token.

Simulation methods

To trigger a simulation for the Payouts API, use a JSON pointer in the request payload or use a path parameter in the request URI.

Use a JSON pointer in the request payload

Trigger Test value Simulated error response
items[0]/note ERRPYO002 SENDER_EMAIL_UNCONFIRMED

JSON pointer Request

curl -X POST https://api.sandbox.paypal.com/v1/payments/payouts \
  -H "content-type: application/json" \
  -H "Authorization: Bearer Access-Token" \
  -d '{
  "sender_payout_header":
  {
    "sender_batch_id": "1524086406556",
    "email_subject": "This email is related to simulation"
  },
  "items": [
  {
    "recipient_type": "EMAIL",
    "receiver": "payouts-simulator-receiver@paypal.com",
    "note": "ERRPYO002",
    "sender_item_id": "15240864065560",
    "amount":
    {
      "currency": "USD",
      "value": "1.00"
    }
  }]
}'

JSON pointer response

{
  "name": "SENDER_EMAIL_UNCONFIRMED",
  "message": "Authorization error occurred",
  "debug_id": "ca787bdf80d7a",
  "information_link": "https://developer.paypal.com/docs/api/payments.payouts-batch/#errors"
}

Use a path parameter in the request URI

Trigger Test value Simulated error response
/v1/payments/payouts ERRPYO015 CLOSED_MARKET

Path parameter request

curl -X GET https://api.sandbox.paypal.com/v1/payments/payouts/ERRPYO015 \
  -H "content-type: application/json" \
  -H "Authorization: Bearer Access-Token"

Path parameter response

{
  "batch_header":
  {
    "payout_batch_id": "DQCP2UAJCBMNY",
    "batch_status": "SUCCESS",
    "time_created": "2017-08-21T11:22:33Z",
    "time_completed": "2017-08-21T11:22:54Z",
    "sender_payout_header":
    {
      "email_subject": "user test case"
    },
    "amount":
    {
      "currency": "USD",
      "value": "190.0"
    },
    "fees":
    {
      "currency": "USD",
      "value": "0.0"
    }
  },
  "items": [
  {
    "payout_item_id": "RWD4Y3H9VV8BA",
    "transaction_status": "FAILED",
    "payout_item_fee":
    {
      "currency": "USD",
      "value": "0.0"
    },
    "payout_batch_id": "DQCP2UAJCBMNY",
    "payout_item":
    {
      "recipient_type": "EMAIL",
      "amount":
      {
        "currency": "USD",
        "value": "190.0"
      },
      "note": "payout to  receiver",
      "receiver": "receiver@example.com",
      "sender_item_id": "MSI-2727"
    },
    "time_processed": "2017-08-21T11:22:44Z",
    "errors":
    {
      "name": "CLOSED_MARKET",
      "message": "Market closed and transaction is between 2 different countries",
      "information_link": "https://developer.paypal.com/docs/api/payments.payouts-batch/#errors",
      "details": []
    },
    "links": [
    {
      "href": "https://api.sandbox.paypal.com/v1/payments/payouts-item/RWD4Y3H9VV8BA",
      "rel": "item",
      "method": "GET",
      "encType": "application/json"
    }]
  }],
  "links": [
  {
    "href": "https://api.sandbox.paypal.com/v1/payments/payouts/DQCP2UAJCBMNY",
    "rel": "self",
    "method": "GET",
    "encType": "application/json"
  }]
}

Test values

Use the following test values to trigger positive and negative responses for these Payouts actions:

  • Create payout
  • Show payout details
  • Cancel payout item
  • Show payout item details

Note: Test values are case sensitive.

Create payout positive response test values

Use the JSON pointer method to simulate this response at POST v1/payments/payouts/.

Trigger Test value Simulated error response
items[0]/note POSPYO001 PAYLOAD WITH 201 RESPONSE CODE

Create payout negative response test values

Use the JSON pointer method to simulate these error responses at POST v1/payments/payouts.

Trigger Test value Simulated positive response
items[0]/note ERRPYO001 SENDER_RESTRICTED
items[0]/note ERRPYO002 SENDER_EMAIL_UNCONFIRMED
items[0]/note ERRPYO003 AUTHORIZATION_ERROR
items[0]/note ERRPYO005 INSUFFICIENT_FUNDS
items[0]/note ERRPYO006 INTERNAL_ERROR
items[0]/note ERRPYO010 MALFORMED_REQUEST_ERROR
items[0]/note ERRPYO011 REQUIRED_SCOPE_MISSING
items[0]/note ERRPYO012 SENDER_LOCKED
items[0]/note ERRPYO013 THIRD_PARTY_CALLS_FORBIDDEN
items[0]/note ERRPYO014 USER_BUSINESS_ERROR

Show payout positive response test values

Use the path parameter in the request URI method to simulate this response at GET v1/payments/payouts.

Trigger or test value Simulated positive response
/v1/payments/payouts/POSPYO002 PAYLOAD WITH 201 RESPONSE CODE

Show payout negative response test values

Use the path parameter in the request URI method to simulate these error responses at GET v1/payments/payouts.

Trigger or test value Simulated error response
/v1/payments/payouts/ERRPYO015 CLOSED_MARKET
/v1/payments/payouts/ERRPYO016 CURRENCY_COMPLIANCE
/v1/payments/payouts/ERRPYO017 CURRENCY_NOT_SUPPORTED_FOR_RECEIVER
/v1/payments/payouts/ERRPYO018 DUPLICATE_ITEM
/v1/payments/payouts/ERRPYO019 RECEIVER_ACCOUNT_LOCKED
/v1/payments/payouts/ERRPYO020 RECEIVER_COUNTRY_NOT_ALLOWED
/v1/payments/payouts/ERRPYO021 RECEIVER_UNCONFIRMED
/v1/payments/payouts/ERRPYO022 RECEIVER_UNREGISTERED
/v1/payments/payouts/ERRPYO023 RECEIVER_YOUTH_ACCOUNT
/v1/payments/payouts/ERRPYO024 RECEIVING_LIMIT_EXCEEDED
/v1/payments/payouts/ERRPYO025 REGULATORY_BLOCKED
/v1/payments/payouts/ERRPYO026 REGULATORY_PENDING
/v1/payments/payouts/ERRPYO027 RISK_DECLINE
/v1/payments/payouts/ERRPYO028 SELF_PAY_NOT_ALLOWED
/v1/payments/payouts/ERRPYO029 TRANSACTION_LIMIT_EXCEEDED
/v1/payments/payouts/ERRPYO030 UNDEFINED
/v1/payments/payouts/ERRPYO031 ZERO_AMOUNT

Cancel payout item positive response test values

Use the path parameter in the request URI method to simulate this response at POST v1/payments/payouts-item/payouts_item_id/cancel.

Trigger or test value Simulated positive response
v1/payments/payouts-item/POSPOI002/cancel PAYLOAD WITH 200 RESPONSE CODE

Cancel payout item negative response test values

Use the path parameter in the request URI method to simulate these error responses at POST v1/payments/payouts-item/payouts_item_id/cancel.

Trigger or test value Simulated positive response
v1/payments/payouts-item/ERRPOI001/cancel INVALID_RESOURCE_ID
v1/payments/payouts-item/ERRPOI002/cancel ITEM_INCORRECT_STATUS
/v1/payments/payouts-item/ERRPYO004/cancel BATCH_NOT_COMPLETED
/v1/payments/payouts-item/ERRPYO007/cancel ITEM_ALREADY_CANCELLED
/v1/payments/payouts-item/ERRPYO008/cancel ITEM_CANCELLATION_FAILED
/v1/payments/payouts-item/ERRPYO009/cancel ITEM_INCORRECT_STATUS

Show payout item details positive response test values

Use the path parameter in the request URI method to simulate this response at GET v1/payments/payouts-item/payouts_item_id.

Trigger or test value Simulated positive response
v1/payments/payouts-item/POSPOI001 PAYLOAD WITH 200 RESPONSE CODE

Show payout item negative response test values

Use the path parameter in the request URI method to simulate these error responses at GET v1/payments/payouts-item/payouts_item_id.

Trigger or test value Simulated error response
v1/payments/payouts-item/ERRPOI003 INVALID_RESOURCE_ID

Batch processing positive response test values

Use the path parameter in the request URI method to simulate this response at GET v1/payments/payouts/payout_batch_id.

Trigger or test value Simulated positive response
v1/payments/payouts/POSPYOB001 PAYLOAD WITH 200 RESPONSE CODE

Batch processing negative response test values

Use the path parameter in the request URI method to simulate these error responses at GET v1/payments/payouts/payout_batch_id.

Trigger or test value Simulated error response
v1/payments/payouts/ERRPYOB001 SUCCESS
v1/payments/payouts/ERRPYOB002 PENDING
v1/payments/payouts/ERRPYOB003 DENIED
v1/payments/payouts/ERRPYOB004 PROCESSED

Use the JSON pointer method to simulate this error response at POST v1/payments/payouts.

Trigger Test value Simulated error response
items[0]/note ERRPYOB005 PENDING

Next

Set up webhook notifications or view reports.

Additional information

Feedback