Orders Integration Guide

Important: PayPal for Marketplaces is a limited-release solution at this time. It is available to select partners for approved use cases. For more information, reach out to your PayPal account manager or contact us.

Overview

This guide shows you how to create, view, and pay for orders and disburse funds based on order approval. You can customize your integration by leveraging the following Orders API features:

  • Partner fees. Collect funds from any party.

  • Holds. Place an automatic hold on all PayPal payments made on the platform.

  • Disbursements. Control PayPal’s release of funds to your merchant’s PayPal account (Connected path) or bank account (Managed path). With instant disbursement, merchants receive funds as soon as a sale is complete. With delayed disbursement, funds aren't released until you trigger disbursement.

  • Multi-seller payment. Process payments from multiple merchants at once. Your customers experience one streamlined checkout regardless of how many merchants they’re purchasing from.

  • Notifications. Once an order is created or paid for, you receive real-time responses on the order status. In addition, notifications (webhooks) are sent to your application with the order status.

  • Loss account (Managed path only). Because you own loss liability with a Managed path integration, a loss account is configured to facilitate reverse movement of funds. PayPal reverses these transactions from your loss account.

Prerequisites

Partners must be approved and sign a contract before they can begin using the Orders API. PayPal evaluates partners on a variety of criteria before approving them to handle orders.

Before you can use the Orders API, you must:

Integration steps

Here’s how to integrate payment processing through the Orders API:

1. Required Add a PayPal button.
2. Required Set the transaction context.
3. Optional Set up webhooks.
4. Required Create order.
5. Required Pay for the order.
6. Optional Show order status.
7. Optional Refund payment.
8. Required Disburse funds.

Add PayPal button

Follow the steps to add a PayPal button to your website.

Set transaction context

Before you can use the Orders API, you must set the transaction context:

PUT /v1/risk/transaction-contexts

This call enables PayPal to complete a risk and compliance analysis of the transaction. This analysis occurs when the buyer logs in and authorizes payment through their PayPal account.

Pass the standard request headers to this call:

  • Authorization

  • Accept

  • Content-Type

  • PayPal-Request-Id

In the URI, include these parameters:

  • merchant_id. The unique, externally visible PayPal account number that identifies the partner.

  • tracking_id. A random, unique ID (such as a time stamp) that you provide to identify the transaction.

Note: Every PayPal consumer, business, or partner account has a unique ID that identifies it. A payer_id field defines the externally available, encrypted ID for each account. The payer_id for the partner is the value that you pass to this function as the merchant_id parameter. To find your payer ID, log into your PayPal account and navigate to your profile. The value for Merchant account ID is your payer ID.

Save the tracking ID so you can pass it in the PayPal-Client-Metadata-Id header in subsequent calls. When a customer creates and pays for an order, this header value ties the transaction APIs to the SetTransactionContext call.

Request body

In the additional_data field of the request payload, you provide information about the customer, such as account ID, email, phone, and so on. Contact your PayPal account manager to identify the data to send to this API.

This example passes merchant_id, a time stamp for tracking_id, and customer details in the request body:

PUT https://api.sandbox.paypal.com/v1/risk/transaction-contexts/6KFWC9NAZWBYB/1495722184170oren

-H "PayPal-Request-Id: eae77a21-acc5-4d69-acfc-1a23d308a864"
-H "Authorization: Bearer Access-Token"
-d '{
  "additional_data”: [{
  "key": "sender_account_id",
  "value": "oren"
}, {
  "key": "sender_first_name",
  "value": "oren"
}, {
  "key": "sender_last_name",
  "value": "oren"
}, {
  "key": "sender_create_date",
  "value": "2017-08-29T03: 42: 34Z"
}, {
  "key": "seller_account_id",
  "value": "partnerengtest1-seller@paypal.com"
}, {
  "key": "seller_create_date",
  "value": "2017-08-29T03: 42: 34Z"
}, {
  "key": "transaction_is_tangible",
  "value": "TRUE"
}]
}'

A successful call returns the HTTP 200 status code.

Set up and use webhooks

PayPal APIs use webhooks for event notification. A webhook is an HTTP callback that receives notification messages for events. For information, see set up webhooks.

Create order

To create an order:

POST /v1/checkout/orders

In addition to the standard Accept, Content-Type, PayPal-Request-Id, and Authorization headers, include these headers:

  • PayPal-Client-Metadata-Id. Specify the tracking ID that you passed to set the transaction context. The value in this header ties the current API call to the set transaction context call.

  • PayPal-Partner-Attribution-Id. Specify a unique build notation (BN) code. If you do not have a BN code, contact your PayPal account manager.

For more information about these headers, see REST API authentication and headers.

Use these parameters to define your order request:

Parameter Description
redirect_urls

URLs to return the customer to your website after he or she approves or cancels the order. Specify these values:

"return_url": "https://marketplace.com/return"
"cancel_url": "https://marketplace.com/cancel"
purchase_units

An array with details for the customer, merchant, partner, and order. Specify this information:

  • reference_id. The purchase unit within the context of the order.

  • description. The purchase unit description.

  • payment_linked_group. An integer value that links purchase units that you want to process in the same way for payment acceptance and processing.

    Suppose that a buyer orders a phone from one merchant and a case from a different merchant. Normally, if the phone is unavailable, the purchase unit for the phone is canceled but the purchase unit for the case still ships. To guarantee that the case does not ship without the phone, use payment_linked_group to link the phone's purchase unit with the case’s purchase unit.

    Note: Your code must define what to do if a linked purchase unit is canceled. The API uses payment_linked_group to identify linked purchase units, but does not automatically respond to cancellation of a linked purchase unit.
  • custom. An external ID to reconcile client transactions with PayPal transactions. This value is returned in transaction and settlement reports.

  • invoice_number. An external invoice number for this order. This value is returned in transaction and settlement reports.

In addition to defining order details, purchase_unit enables you to specify your fees. For example:

"partner_fee_details": {
  "amount": {
    "currency": "USD",
    "value": "1.00"
  },
  "receiver": {
    "email": "apicaller@paypal.com"
  }
}

When funds are disbursed, you receive the amount that you specify here and the merchant receives the transaction amount minus PayPal and partner fees.

Sample API request

Here’s a create order request:

POST https://api.sandbox.paypal.com/v1/checkout/orders
-H "PayPal-Client-Metadata-Id: 1495722184170oren"
-H "PayPal-Request-Id: b992fcd6-41b6-43b5-b99a-be9acaf85727"
-H "PayPal-Partner-Attribution-Id: PseudoShop_MP"
-H "Authorization: Bearer Access-Token"
-H "Content-Type: application/json"
-d '{
  "purchase_units": [{
    "reference_id": "pu1_forward fashions",
    "description": "pu1_description",
    "amount": {
      "currency": "USD",
      "details": {
        "subtotal": "100.00",
        "shipping": "0.00",
        "tax": "0.00"
      },
      "total": "100.00"
    },
    "payee": {
      "email": "partnerengtest1-seller@paypal.com"
    },
    "items": [{
      "name": "Denim Woven Shirt",
      "sku": "sku01",
      "price": "100.00",
      "currency": "USD",
      "quantity": 1,
      "category": "PHYSICAL",
      "supplementary_data": [],
      "postback_data": [],
      "item_option_selections": []
    }],
    "shipping_address": {
      "recipient_name": "John Doe",
      "default_address": false,
      "preferred_address": false,
      "primary_address": false,
      "disable_for_transaction": false,
      "line1": "2211 N First Street",
      "line2": "Building 17",
      "city": "San Jose",
      "country_code": "US",
      "postal_code": "95131",
      "state": "CA",
      "phone": "(123) 456-7890"
    },
    "shipping_method": "United Postal Service",
    "partner_fee_details": {
      "receiver": {
        "email": "partnerengtest1-facilitator@paypal.com"
      },
      "amount": {
        "value": "16.80",
        "currency": "USD"
      }
    },
    "payment_linked_group": 1,
    "custom": "oren",
    "invoice_number": "invoice_oren_4262",
    "payment_descriptor": "PseudoShop"
  }],
  "metadata": {
    "supplementary_data": [],
    "postback_data": []
  },
  "redirect_urls": {
    "return_url": "https://psvip3-vip.ccg21.dev.paypalcorp.com/checkout?mode=commit&rmi=1495725899514oren&useBraintree=false&disbursementMode=DELAYED",
    "cancel_url": "https://psvip3-vip.ccg21.dev.paypalcorp.com/checkout?mode=foo&rmi=1495725899514oren&useBraintree=false&disbursementMode=DELAYED"
  },
}'

Sample API response

  • The create order call to /checkout/orders/ creates an order. Save the associated order ID to pass to subsequent calls.

  • A successful create order request returns an HTTP 2nn status code. Any other status value indicates an error. In this case, correct the problem and resubmit the order.

Here’s the response to the preceding order request:

Headers:
201 Created
PayPal-Debug-Id: e6692015bc1c0
Body:
{
 "id": "875532314N6767612",
"gross_total_amount": {
  "value": "100.00",
  "currency": "USD"
},
...

"links": [{
    "href": "https://api.paypal.com//v1/checkout/orders/875532314N6767612",
    "rel": "self",
    "method": "GET"
  },
  {
    "href": "https://www.api.paypal.com/webapps/hermes?token=875532314N6767612",
    "rel": "approval_url",
    "method": "REDIRECT"
  },
  {
    "href": "https://api.sandbox.paypal.com//v1/checkout/orders/875532314N6767612",
    "rel": "cancel",
    "method": "DELETE"
  }
],
"status": "CREATED"
}

The links array contains HATEOAS links that enable you to complete other actions for the order:

  • Show order details:

    (GET) "href": https://api.paypal.com/v1/checkout/orders/6GJ5755276400205X
    
  • Redirect the customer to the URL to approve the order:

    (REDIRECT) "href": https://www.paypal.com/webapps/hermes?token=6GJ5755276400205X
    
  • Delete the order:

    (DELETE) "href": https://api.paypal.com/v1/checkout/orders/6GJ5755276400205X
    

Pay for order

After the customer has been redirected to the return URL, process payments by calling:

POST /v1/checkout/orders/order_id/pay

In addition to the standard Accept, Content-Type, PayPal-Request-Id, and Authorization headers, include the PayPal-Client-Metadata-Id and PayPal-Partner-Attribution-Id headers.

In the URL, pass the parameter order_id. Specify the ID returned from the call to create the order.

In the request body, pass the disbursement_mode parameter. You can specify either of these disbursement modes:

  • DELAYED. PayPal holds the money until you call /v1/payments/referenced-payouts-items/ to disburse funds. For example, you could code logic to distribute funds automatically after a set period of time, when the order is processed for shipping, and so on.

  • INSTANT. PayPal disburses funds immediately when an order is complete. In this case, you do not need to call /v1/payments/referenced-payouts-items.

Note: To learn more about delayed or instant disbursement, see Managing risk for Connected or Managed integrations.

API request

Here’s an example of a request for delayed disbursement.

POST https://api.sandbox.paypal.com/v1/checkout/orders/875532314N6767612/pay
-H “PayPal-Client-Metadata-Id: 1495725899514oren”
-H “PayPal-Request-Id: 9c5e3668-cb92-4a40-99b7-c74cb68913f4”
-H “PayPal-Partner-Attribution-Id: PseudoShop_MP”
-H “Authorization: Bearer Access-Token”
-H “Content-Type: application/json”
-d ‘{
  "disbursement_mode": "DELAYED"
}’

API response

And here’s the corresponding response:

Headers:
201 Created
Body:
{
  "order_id": "875532314N6767612",
  "status": "APPROVED",
  "payer_info": {
    ...
  }
},
"purchase_units": [],
"links": [{
  "href": "https://api.sandbox.paypal.com//v1/checkout/orders/875532314N6767612",
  "rel": "self",
  "method": "GET"
}],
}

The response for a call that sets disbursement to INSTANT is similar.

Show order status

For a transaction, the webhook notification contains the transaction ID and a link to show status details or refund the payment.

  • Show status details:

    "href": "https://api.paypal.com/v1/payments/capture/29N36144XH0198422",
    "method": "GET"
    
  • Refund the payment:

    "href":
    "https://api.paypal.com/v1/payments/capture/29N36144XH0198422/refund",
    "method": "POST"
    

Refund payment

To request payment refunds for an order, pass the capture ID in the URI:

POST /v1/payments/capture/capture_id/refund

The capture_id is either:

In the request body, specify:

  • amount. Currency and total amount to refund.

  • custom. The transaction ID that you specified when you created a purchase unit for the order.

  • invoice_number. The merchant-specific order ID that you specified when you created a purchase unit for the order.

Along with the standard headers (Accept, Content-Type, PayPal-Request-Id, and Authorization), pass PayPal-Client-Metadata-Id. Specify the tracking ID you passed to the risk call. It enables PayPal to confirm that a valid device and application originated the transaction.

Here’s an example of a refund request:

POST

-H "Content-Type: application/json"
-H "Authorization: Bearer Access-Token
-d '{
 "amount": {
   "currency": "USD",
   "total": "0.7"
 },
 "custom": "custom_29N36144XH0198422",
 "invoice_number": "inv_29N36144XH0198422"
}' "https://api.paypal.com/v1/payments/capture/29N36144XH0198422/refund"

The response includes:

  • An ID for the refund (2M4379007H634953P).

  • A set of HATEOAS links to show details for the refund, parent payment, and original payout.

For example:

{
 "id": "2M4379007H634953P",
 "state": "completed",
 "amount": {
   "total": "0.70",
   "currency": "USD"
 },
 "refund_from_received_amount": {
   "value": "0.67",
   "currency": "USD"
 },
 "refund_from_transaction_fee": {
   "value": "0.03",
   "currency": "USD"
 },
 "total_refunded_amount": {
   "value": "0.70",
   "currency": "USD"
 },
 "parent_payment": "PAYID-LBA6I7Y200213815P317172G",
 "capture_id": "29N36144XH0198422",
 "create_time": "2017-12-02T14:21:51.051Z",
 "update_time": "2017-12-02T14:21:51.051Z",
 "links": [
   {
     "href": "https://api.paypal.com/v1/payments/refund/2M4379007H634953P",
     "rel": "self",
     "method": "GET"
   },
   {
     "href": "https://api.paypal.com/v1/payments/payment/PAYID-LBA6I7Y200213815P317172G",
     "rel": "parent_payment",
     "method": "GET"
   },
   {
     "href": "https://api.paypal.com/v1/payments/capture/29N36144XH0198422",
     "rel": "capture",
     "method": "GET"
   }
 ]
}

Disburse funds

Note: You must disburse funds only if you chose delayed disbursement.

To disburse funds into PayPal business accounts for you (the partner) and the merchant:

POST /v1/payments/referenced-payouts-items

In addition to the standard Accept, Content-Type, PayPal-Request-Id, and Authorization headers, include the Prefer: respond-sync header.

  • Specify respond-async if you want PayPal to process the request asynchronously. The POST response contains a link to the resource that you can use later to query the referenced payout status.

  • Specify respond-sync if you want PayPal to process the request synchronously. The POST response contains the final result of the referenced payout.

Pass the following parameters in the request body:

  • reference_id. The transaction ID for the payout. The pay for order call generates a webhook, which returns the transaction ID.

  • reference_type. Set to TRANSACTION_ID to specify the type of the ID.

Here’s an example of payment disbursement:

POST

-H "Content-Type: application/json"
-H "PayPal-Request-Id: postman-request-1480716758"
-H "Authorization: Bearer Access-Token
-H "PayPal-Partner-Attribution-Id: PseudoShop_MP"
-H "Prefer: respond-sync"
-d '{
 "reference_id": "29N36144XH0198422",
 "reference_type": "TRANSACTION_ID"
}' "https://api.paypal.com/v1/payments/referenced-payouts-items"

The call creates a referenced-payout-item object:

Headers:

200 Success

Body
{
  "item_id": "g8rfiM0u38L_FJ6qqA-3yHjaTFuTEjdK5ef2WbcpdDsQOci_Lk-we3dHjNNpEcY=",
  "processing_state": {
    "status": "SUCCESS"
  },
  "reference_id": "29N36144XH0198422",
  "reference_type": "TRANSACTION_ID",
  "payout_transaction_id": "67B93249N8969944D",
  "external_reference_id": "postman-request-1480713480",
  "payout_amount": {
    "currency_code": "USD",
    "value": "0.27"
  },
  "payout_destination": "B2A2BDS5DBA4Y",
  "links": [{
    "href": "https://api.paypal.com/v1/payments/referenced-payouts-items/g8rfiM0u38L_FJ6qqA-3yHjaTFuTEjdK5ef2WbcpdDsQOci_Lk-we3dHjNNpEcY=",
    "rel": "self",
    "method": "GET",
    "encType": "application/json"
  }]
}

The response includes these fields:

  • processing_state. Status of the payout (“SUCCESS” in this case).

  • item_id. A unique ID PayPal creates for the payout request.

  • reference_id. The transaction ID of the transaction to disburse to the merchant.

  • payout_transaction_id. Encrypted PayPal ID for the payout.

  • payout_amount. Exact amount and currency to be disbursed.

  • payout_destination. Payer ID of the account that receives the funds.

  • A HATEOAS link to show details for the payout. For example:

    GET "href": "https://api.paypal.com/v1/payments/referenced-payouts-items/g8rfiM0u38L_FJ6qqA-3yHjaTFuTEjdK5ef2WbcpdDsQOci_Lk-we3dHjNNpEcY="
    

Note: PayPal fees are deducted from the merchant’s funds.

Congratulations

You have set up orders.