Delay disbursement

DocsCurrent


Use this integration to hold funds from a buyer before disbursing it to your seller. Holding funds gives you time to conduct additional vetting. If you want to capture funds immediately, use Immediate capture.

Delayed disbursement supports:

  • Authorization: Set intent to authorize in the create order call to authorize a payment and place funds on hold after the customer makes a payment.
  • Capture: Set intent to capture create order call to capture payment immediately after the customer makes a payment.

Note: Funds are automatically disbursed to the seller after 28 days, and PayPal deducts fees from the seller’s funds.

Know before you code

Required

To use this integration you must:

Run in Postman

Note: This server-side integration uses the Orders REST API for this server-side integration.

1. Generate PayPal-Auth-Assertion header

You’ll need to Pass the PayPal-Auth-Assertion header with the standard Content-Type, Authorization, and PayPal-Request-ID headers. In client-side JavaScript, the value of the PayPal-Auth-Assertion header can be generated as follows:

1// client-side JavaScript
2
3function encodeObjectToBase64(object) {
4 const objectString = JSON.stringify(object);
5 return window.btoa(objectString);
6}
7
8const clientId = "CLIENT-ID";
9const sellerPayerId = "SELLER-PAYER-ID"; // preferred
10// const sellerEmail = "SELLER-ACCOUNT-EMAIL"; // use instead of payer-id if required
11
12const header = {
13 alg: "none"
14};
15const encodedHeader = encodeObjectToBase64(header);
16
17const payload = {
18 iss: clientId,
19 payer_id: sellerPayerId
20 // email: sellerEmail
21};
22const encodedPayload = encodeObjectToBase64(payload);
23
24const jwt = `${encodedHeader}.${encodedPayload}.`; // json web token
25console.log(`Paypal-Auth-Assertion=${jwt}`);

Note: The token contains two period (.) characters, which are required according to the JSON web token structure.

Modify the code

  • Use the client ID of the platform or marketplace from the PayPal Developer dashboard for clientId.
  • In the given example, the sellerPayerId is the payer ID of the receiving seller's PayPal account. You can also use email instead of payer_id and supply the email address of the seller's PayPal account.

Example functions to generate the PayPal-Auth-Assertion header in other programming environments:

Node.js

1// Node.js
2
3function encodeObjectToBase64(object) {
4 const objectString = JSON.stringify(object);
5 return Buffer
6 .from(objectString)
7 .toString("base64");
8}
9
10const clientId = "CLIENT-ID";
11const sellerPayerId = "SELLER-PAYER-ID"; // preferred
12// const sellerEmail = "SELLER-ACCOUNT-EMAIL"; // use instead if payer-id unknown
13
14const header = {
15 alg: "none"
16};
17const encodedHeader = encodeObjectToBase64(header);
18
19const payload = {
20 iss: clientId,
21 payer_id: sellerPayerId
22 // email: sellerEmail
23};
24const encodedPayload = encodeObjectToBase64(payload);
25
26const jwt = `${encodedHeader}.${encodedPayload}.`; // json web token
27console.log(`Paypal-Auth-Assertion=${jwt}`);

Java

1// Java
2
3import org.apache.commons.codec.binary.Base64;
4
5public class Base64Encode {
6
7 public static void main(String[] args) {
8 String clientId = "CLIENT-ID";
9 String sellerPayerId = "SELLER-PAYER-ID"; // preferred
10 // String sellerEmail = "SELLER-ACCOUNT-EMAIL"; // use instead if payer-id unknown
11
12 String header = "{\"alg\":\"none\"}";
13 String payload =
14 "{\"iss\":\"" + clientId + "\",\"payer_id\":\"" + sellerPayerId + "\"}";
15 // "{"iss":"" + clientId + "","email":"" + sellerEmail + ""}";
16
17 byte[] encodedHeader = Base64.encodeBase64(header.getBytes());
18 byte[] encodedPayload = Base64.encodeBase64(payload.getBytes());
19
20 String jwt = new String(encodedHeader) +
21 "." +
22 new String(encodedPayload) +
23 "."; // json web token
24 System.out.println("Paypal-Auth-Assertion=" + jwt);
25 }
26}

2. Create order

You must first create an order and capture funds. To create an order, copy the following code and modify as follows:

  • Replace BN-CODE with your PayPal attribution ID.
  • Replace PAYPAL-AUTH-ASSERTION with your PayPal auth assertion generated from Step 1.
  • Use the purchase_units/payee object to specify the end receiver of the funds.
  • Use the purchase_units/payment_instruction/disbursement_mode field to specify when funds should be disbursed to the payee upon calling capture order. In this integration, set this field to DELAYED.
  • Use the purchase_units/payment_instruction/platform_fees array to specify fees for the order. You must onboard your seller with the PARTNER_FEE feature to use this array.

Sample request - cURL

1curl -v -X POST https://api-m.sandbox.paypal.com/v2/checkout/orders
2-H 'Content-Type: application/json'
3-H 'Authorization: Bearer ACCESS-TOKEN'
4-H 'PayPal-Partner-Attribution-Id: BN-CODE'
5-H 'PayPal-Auth-Assertion: PAYPAL-AUTH-ASSERTION'
6-d '{
7 "intent": "CAPTURE",
8 "purchase_units": [{
9 "amount": {
10 "currency_code": "USD",
11 "value": "100.00"
12 },
13 "payee": {
14 "email_address": "seller@example.com"
15 },
16 "payment_instruction": {
17 "disbursement_mode": "DELAYED",
18 "platform_fees": [{
19 "amount": {
20 "currency_code": "USD",
21 "value": "25.00"
22 }
23 }]
24 }
25 }]
26 }'

Sample request - Node

1var express = require('express');
2var request = require('request');
3express().post('/my-server/create-order', function(req, res) {
4 request.post('https://api-m.sandbox.paypal.com/v2/checkout/orders', {
5 headers: {
6 "Content-Type": "application/json",
7 "Authorization": "Bearer ACCESS-TOKEN",
8 "PayPal-Partner-Attribution-Id": "BN-CODE",
9 "PayPal-Auth-Assertion": "PAYPAL-AUTH-ASSERTION"
10 },
11 body: {
12 "intent": "CAPTURE",
13 "purchase_units": [{
14 "amount": {
15 "currency_code": "USD",
16 "value": "100.00"
17 },
18 "payee": {
19 "email_address": "seller@example.com"
20 },
21 "payment_instruction": {
22 "disbursement_mode": "DELAYED",
23 "platform_fees": [{
24 "amount": {
25 "currency_code": "USD",
26 "value": "25.00"
27 }
28 }]
29 }
30 }],
31 },
32 json: true
33 }, function(err, response, body) {
34 if (err) {
35 console.error(err);
36 return res.sendStatus(500);
37 }
38 res.json({
39 id: body.id
40 });
41 });
42});

3. Capture order

After your buyer approves the order, call capture order to capture the buyer’s funds.

Copy the following code and modify as follows:

  • Replace ACCESS-TOKEN with your access token.
  • Replace BN-CODE with your PayPal partner attribution ID.
  • Replace PAYPAL-AUTH-ASSERTION with your PayPal auth assertion generated from Step 1.

Sample request - cURL

1curl -v -k -X POST https://api-m.paypal.com/v2/checkout/orders/5O190127TN364715T/capture
2-H 'Content-Type: application/json'
3-H 'Authorization: Bearer ACCESS-TOKEN'
4-H 'PayPal-Partner-Attribution-Id: BN-CODE'
5-H 'PayPal-Auth-Assertion: PAYPAL-AUTH-ASSERTION'
6-d '{}'

Sample request - Node

1var express = require('express');
2var request = require('request');
3express().post('/my-server/handle-approve/:id', function(req, res) {
4 var OrderID = req.params.id;
5 request.post('https://api-m.sandbox.paypal.com/v2/checkout/orders/' + OrderID + '/capture', {
6 headers: {
7 "Content-Type": "application/json",
8 "Authorization": "Bearer ACCESS-TOKEN",
9 "PayPal-Partner-Attribution-Id": "BN-CODE",
10 "PayPal-Auth-Assertion": "PAYPAL-AUTH-ASSERTION"
11 }
12 }, function(err, response, body) {
13 if (err) {
14 console.error(err);
15 return res.sendStatus(500);
16 }
17 res.json({
18 status: 'success'
19 });
20 });
21});

Note: Note: Orders cannot be captured until the status of the order is set to APPROVED. The order status is set to APPROVED when the buyer successfully completes the checkout flow.

4. Show order details

To see your order details, pass the order ID as a path parameter in a show order details call.

Copy the following code and modify as follows:

  • Replace ACCESS-TOKEN with your access token.
  • Replace BN-CODE with your PayPal partner attribution ID.
  • Replace PAYPAL-AUTH-ASSERTION with your PayPal auth assertion generated from Step 1.

Sample request - cURL

1curl -v -X GET https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T
2-H "Content-Type: application/json"
3-H 'Authorization: Bearer ACCESS-TOKEN'
4-H 'PayPal-Partner-Attribution-Id: BN-CODE'
5-H 'PayPal-Auth-Assertion: PAYPAL-AUTH-ASSERTION'

Sample request - Node

1var http = require("https");
2var options = {
3 "method": "GET",
4 "hostname": "api-m.sandbox.paypal.com",
5 "port": null,
6 "path": "/v2/checkout/orders/5O190127TN364715T",
7 "headers": {
8 "Content-Type": "application/json",
9 "Authorization": "Bearer ACCESS-TOKEN",
10 "PayPal-Partner-Attribution-Id": "BN-CODE",
11 "PayPal-Auth-Assertion": "PAYPAL-AUTH-ASSERTION"
12 }
13};
14var req = http.request(options, function(res) {
15 var chunks = [];
16 res.on("data", function(chunk) {
17 chunks.push(chunk);
18 });
19 res.on("end", function() {
20 var body = Buffer.concat(chunks);
21 console.log(body.toString());
22 });
23});
24req.end();

A successful request returns the HTTP 200 OK status code and a JSON response body that shows order details.

1{
2 "id": "5O190127TN364715T",
3 "status": "CREATED",
4 "intent": "CAPTURE",
5 "purchase_units": [
6 {
7 "reference_id": "d9f80740-38f0-11e8-b467-0ed5f89f718b",
8 "amount": {
9 "currency_code": "USD",
10 "value": "100.00"
11 }
12 }
13 ],
14 "create_time": "2018-04-01T21:18:49Z",
15 "links": [
16 {
17 "href": "https://api-m.paypal.com/v2/checkout/orders/5O190127TN364715T",
18 "rel": "self",
19 "method": "GET"
20 },
21 {
22 "href": "https://www.paypal.com/checkoutnow?token=5O190127TN364715T",
23 "rel": "approve",
24 "method": "GET"
25 },
26 {
27 "href": "https://api-m.paypal.com/v2/checkout/orders/5O190127TN364715T/capture",
28 "rel": "capture",
29 "method": "POST"
30 }
31 ]
32}

5. Disburse funds

Once funds are captured, call /v1/payments/referenced-payouts-items to disburse funds to your seller. To make this call you must pass a reference_id. Retrieve the reference_id by making a show order details call and note down the urchase_units/payments/captures/id field.

Copy the following code and modify as follows:

Sample request - cURL

1curl -v https://api-m.sandbox.paypal.com/v1/payments/referenced-payouts-items
2-X POST
3-H "Content-Type: application/json"
4-H "Authorization: Bearer ACCESS-TOKEN"
5-H "PayPal-Partner-Attribution-Id: BN-CODE"
6-d '{
7 "reference_id": "29N36144XH0198422",
8 "reference_type": "TRANSACTION_ID"
9}'

Sample request - Node

1var http = require("https");
2var options = {
3 "method": "GET",
4 "hostname": "api-m.sandbox.paypal.com",
5 "port": null,
6 "path": "/v2/checkout/orders/5O190127TN364715T",
7 "headers": {
8 "content-type": "application/json",
9 "Authorization": "Bearer ACCESS-TOKEN",
10 }
11};
12var req = http.request(options,
13function (res) {
14 var chunks = [];
15 res.on("data ", function (chunk) {
16 chunks.push(chunk);
17 });
18 res.on("end ", function () {
19 var body = Buffer.concat(chunks);
20 console.log(body.toString());
21 })
22;});
23req.end();

A successful request returns the HTTP 200 OK status code and a JSON response body that shows order details.

Next steps

Recommended
Integration Checklist

Go through the integration checklist before you go live.