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.

  • Payment instruments. Pay for an order with a wide variety of payment instruments: PayPal, credit or debit card, or an ELV direct debit.

  • Vaulting. The PayPal vault helps to securely store customer credit cards. You can pay for an order with a vaulted credit card.

  • Channel billing agreements. Enable your customers to save PayPal as a payment method on your marketplace.

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. Required Create order.
4. Required Pay for order.
5. Optional Show order status.
6. Optional Refund payment.
7. 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 request 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 HTTP request headers.

Use these parameters to define your order:

  • 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, use purchase_unit to specify your fees. For example:

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

Sample API request

To create an order:

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://api.sandbox.paypal.com/checkout?mode=commit&rmi=1495725899514oren&useBraintree=false&disbursementMode=DELAYED",
    "cancel_url": "https://api.sandbox.paypal.com/checkout?mode=foo&rmi=1495725899514oren&useBraintree=false&disbursementMode=DELAYED"
  },
}'

Sample API response

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

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

The response to the preceding order request is:

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

"links": [{
    "href": "https://api.sandbox.paypal.com/v1/checkout/orders/875532314N6767612",
    "rel": "self",
    "method": "GET"
  },
  {
    "href": "https://api.sandbox.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.sandbox.paypal.com/v1/checkout/orders/6GJ5755276400205X
    
  • Redirect the customer to the URL to approve the order:

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

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

Pay for order

Your customers can pay for an order with a wide variety of payment instruments: PayPal, credit or debit card, or an ELV direct debit.

To process payments after the customer has been redirected to the return URL:

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 create order call.

In the request body, pass the disbursement_mode parameter. Specify one 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.

Additional ways to pay

In addition to PayPal payments, the Orders API accepts the following payment instruments:

  • Credit/debit card
  • A vaulted credit/debit card. See Vault overview to learn more about vaulting.
  • Bank account
  • PayPal billing agreement ID (if your customer has one set up).

To pay with a credit card:

 POST 'https://api.sandbox.paypal.com/v1/checkout/orders/21E005655U660730L/pay' \
 -H 'Content-Type: application/json' \
 -d '{
  "disbursement_mode": "INSTANT",
  "payer": {
    "payment_method": "paypal",
    "funding_instruments": [{
      "credit_card": {
        "number": "4417119669820331",
        "type": "visa",
        "expire_month": 11,
        "expire_year": 2018,
        "cvv2": "874",
        "first_name": "Betsy",
        "last_name": "Buyer",
        "billing_address": {
          "line1": "2211 N First Street",
          "line2": "Building 17",
          "city": "San Jose",
          "state": "CA",
          "postal_code": "95131",
          "country_code": "US"
        }
      }
    }]
  }
}'

To pay with a vaulted instrument:

curl -v -k -X
  POST 'https://api.sandbox.paypal.com/v1/checkout/orders/21E005655U660730L/pay' \
  -H 'Content-Type: application/json' \
  -d '{
  "disbursement_mode": "INSTANT",
  "payer": {
    "payment_method": "credit_card",
    "funding_instruments": [{
      "credit_card_token": {
        "credit_card_id": "CARD-2RE1087455820591DLEYKFMI",
        "external_customer_id": "joe_shopper408 - 334 - 8890"
      }
    }]
  }
}

To pay with a bank payment:

curl -v -k -X
POST 'https://api.sandbox.paypal.com/v1/checkout/orders/21E005655U660730L/pay' \
  -H 'Content-Type: application/json' \
  -d '{
  "disbursement_mode": "INSTANT",
  "payer": {
    "payment_method": "paypal",
    "funding_instruments": [{
      "bank_account": {
        "account_number": "74129148",
        "account_number_type": "BBAN",
        "routing_number": "10000000",
        "birth_date": "1973-12-12",
        "first_name": "Longggg",
        "last_name": "Johns",
        "billing_address": {
          "city": "Kleinmachnow",
          "country_code": "DE",
          "line1": "Marktplatz 43",
          "postal_code": "14532"
        }
      }
    }]
  }
}

To pay with a PayPal billing agreement:

curl -v -k -X
  POST 'https://api.sandbox.paypal.com/v1/checkout/orders/21E005655U660730L/pay' \
  -H 'Content-Type: application/json' \
  -d '{
    "disbursement_mode": "INSTANT",
    "payer": {
      "payment_method": "paypal",
      "funding_instruments": [
        {
          "billing": {
            "billing_agreement_id": "insert_billing_agreement_id"
          }
        }
      ]
    }
  }'

Show order status

For a transaction, the webhook notification contains a sale feature field that includes an ID and a link to show status details or refund the payment.

  • Show status details:

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

    "href": "https://api.sandbox.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 and PayPal-Auth-Assertion. For first-party calls, the value is:

<base64 encoding of ({"alg":"none"})>.<base64 encoding of ({"iss" : "client_id","payer_id":" payer_id "})>

Where payer_id is the merchant's payer ID.

Specify the tracking ID that you passed to the risk call, which 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.sandbox.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.sandbox.paypal.com/v1/payments/refund/2M4379007H634953P",
      "rel": "self",
      "method": "GET"
    },
    {
      "href": "https://api.sandbox.paypal.com/v1/payments/payment/PAYID-LBA6I7Y200213815P317172G",
      "rel": "parent_payment",
      "method": "GET"
    },
    {
      "href": "https://api.sandbox.paypal.com/v1/payments/capture/29N36144XH0198422",
      "rel": "capture",
      "method": "GET"
    }
  ]
}

Additional checkout experience options

Shortcut

Shortcut is an optimized checkout experience that enables you to skip collecting your customer's shipping address, email address and telephone number on your checkout page — the information is pre-filled based on stored PayPal data.

Patch cart

With patch cart, your customers can change the shipping amount and shipping address on the PayPal checkout page. Call the PATCH operation and provide the purchase units that you want to update.

PATCH v1/checkout/orders/order_id/

Vaulting

With vaulting, you can store customer credit cards and use them to pay.

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.

  • To process the request asynchronously, specify respond-async. The POST response contains a link to the resource that you can use later to query the referenced payout status.

  • To process the request synchronously, specify respond-sync. The POST response contains the final result of the referenced payout.

Pass these 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 the type of 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.sandbox.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.sandbox.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. The status of the payout, which is “SUCCESS” in this case.

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

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

  • payout_transaction_id. The encrypted PayPal ID for the payout.

  • payout_amount. The exact amount and currency to be disbursed.

  • payout_destination. The payer ID of the account that receives the funds.

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

    GET "href": "https://api.sandbox.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.