Authorize and Capture Funds

API, SDKLegacyLast updated: April 6th 2022, @ 4:06:12 pm


For increased flexibility in obtaining payments from buyers, you can authorize a payment and capture it later. This allows you to:

  • Get approval from your buyer to capture funds from them at a future time.
  • Authorize the transaction immediately, or authorize the transaction at a later time when the buyer is not present on your site.
  • Capture the transaction at a later time when the buyer is not present on your site.

Note: This feature assumes you have completed a basic Smart Payment Buttons integration.

Understand the authorization periods

An authorization places a hold on the funds and is valid for 29 days. After a successful authorization, PayPal recommends that you capture the funds within the three-day honor period. Success of the capture is subject to risk and availability of funds on the authorized funding instrument. Within the 29-day authorization period, you can issue multiple re-authorizations after the honor period expires. A re-authorization generates a new Authorization ID and restarts the honor period, and any subsequent capture should be performed on the new Authorization ID. If you do a re-authorization on the 27th day of the authorization, you get only two days of honor period.

Within a 29-day authorization period, you can issue multiple reauthorizations after the initial three-day honor period expires.

DayActionAuthorization periodHonor period
1Authorization-1Begins 29-day authorization periodDays 1 through 3
4Reauthorization-1 on Authorization-1Within 29-day authorization periodDays 4 through 7
8Reauthorization-2 on Authorization-1Within 29-day authorization periodDays 8 through 11

For any payment type, you can capture less than or the full original authorized amount. You can also capture up to 115% of or $75 USD more than the original authorized amount, whichever is less.

You can also complete partial captures during a single authorization period. For PayPal payment authorizations, you must enable this feature on your PayPal account.

Note:

  • Customers and merchants cannot close accounts that have authorized but not yet captured payments.
  • You can also authorize payments for orders, which confirms the availability of funds but does not place the funds on hold.

Integrate Authorize Capture

1. Update the script tag

Update the PayPal script tag to pass intent=authorize:

<script
  src="https://www.paypal.com/sdk/js?client-id=CLIENT_ID&intent=authorize">
</script>

2. Set up the transaction

Next, implement the createOrder function, which is called when the buyer clicks the PayPal button. This will:

  • Call PayPal using actions.order.create() to set up the details of the transaction, including the amount, line item details, and more.
  • Launch the PayPal Checkout window so the buyer can log in and approve the transaction on paypal.com.

Note: For the basic integration, you'll complete this step on the client. For advanced use cases, you can also call from your server to set up a transaction.

<script>
  paypal.Buttons({
    createOrder: function(data, actions) {
      // Set up the transaction
      return actions.order.create({
        purchase_units: [{
          amount: {
            value: '0.01'
          }
        }]
      });
    }
  }).render('#paypal-button-container');
</script>

3. Authorize the transaction

Next, implement the onApprove function, which you call after the buyer approves the transaction on paypal.com. This function:

  • Calls PayPal to authorize the funds and finalize the transaction.
  • Shows an alert to the buyer to let them know the transaction is successful.
  • Calls your server to validate the transaction and saves the details to your database.

Note: For the basic authorize and capture integration, you complete this step on the client. You can also make a call directly from your server to PayPal to authorize a transaction. This enables you to authorize or reauthorize the transaction later when the buyer is no longer present on the page.

<script>
  paypal.Buttons({
    createOrder: function(data, actions) {
      return actions.order.create({
        purchase_units: [{
          amount: {
            value: '0.01'
          }
        }]
      });
    },
    onApprove: function(data, actions) {

      // Authorize the transaction
      actions.order.authorize().then(function(authorization) {

        // Get the authorization id
        var authorizationID = authorization.purchase_units[0]
          .payments.authorizations[0].id

        // Call your server to validate and capture the transaction
        return fetch('/paypal-transaction-complete', {
          method: 'post',
          headers: {
            'content-type': 'application/json'
          },
          body: JSON.stringify({
            orderID: data.orderID,
            authorizationID: authorizationID
          })
        });
      });
    }
  }).render('#paypal-button-container');
</script>

For the full list of parameters you can pass to actions.order.authorize() to set up the transaction, and example responses, read the Orders API reference.

4. Verify the transaction

Next, your server verifies the transaction, saves it to your database, and dispatches the purchased item to the buyer.

Tip: if you have already completed a basic integration, change this step to save the authorization ID to your database. You will use this to capture the funds later.

This code:

  1. Sets up your server to make calls to PayPal.
  2. Sets up your server to receive a call from the client with the order ID.
  3. Calls PayPal to get the order details.
  4. Handles any errors from the call.
  5. Validates the order details are as expected.
  6. Saves the order in your database.
  7. Returns a successful response to the client.

For the full list of order details you can retrieve from /v2/checkout/orders/, see show order details in the Orders API reference.

5. Capture the authorization

When you're ready to capture the funds from the transaction, call the PayPal REST API on your server with the authorization ID you saved in the last step. The buyer does not need to be present for this step.

This code:

  1. Sets up your server to make calls to PayPal.
  2. Gets the authorization ID from your database.
  3. Calls PayPal to capture the authorization.
  4. Saves the order ID to your database.
  5. Handles any errors from the call.
{`

The capture request generates a response with a capture ID that you can use for refunding transactions:

For the full list of parameters and example responses, see capturing authorized payments in the Payments API reference.

Note: Remember to swap the credentials and API URL from sandbox to production when going live with your integration.

6. Test and go live

Follow the steps in the basic integration to test your integration and go live.

Reauthorize authorization

An authorization places a hold on the funds and is valid for 29 days. After a successful authorization, PayPal recommends that you capture the funds within the three-day honor period. Success of the capture is subject to risk and availability of funds on the authorized funding instrument. Within the 29-day authorization period, you can issue multiple re-authorizations after the honor period expires. A re-authorization generates a new Authorization ID and restarts the honor period, and any subsequent capture should be performed on the new Authorization ID. If you do a re-authorization on the 27th day of the authorization, you get only two days of honor period.

  1. Set up your server to make calls to PayPal
  2. Get the authorization ID from your database
  3. Call PayPal to reauthorize the authorization
  4. Handle any errors from the call
// Note: This is example code. Each server platform and programming language has a different way of handling requests, making HTTP API calls, and serving responses to the browser.

// 1. Set up your server to make calls to PayPal

// 1a. Add your client ID and secret
PAYPAL_CLIENT = 'PAYPAL_SANDBOX_CLIENT';
PAYPAL_SECRET = 'PAYPAL_SANDBOX_SECRET';

// 1b. Point your server to the PayPal API
PAYPAL_OAUTH_API         = 'https://api-m.sandbox.paypal.com/v1/oauth2/token/';
PAYPAL_AUTHORIZATION_API = 'https://api-m.sandbox.paypal.com/v2/payments/authorizations/';

// 1c. Get an access token from the PayPal API
basicAuth = base64encode(`${ PAYPAL_CLIENT }:${ PAYPAL_SECRET }`);
auth = http.post(PAYPAL_OAUTH_API {
  headers: {
    Accept:        `application/json`,
    Authorization: `Basic ${ basicAuth }`
  },
  data: `grant_type=client_credentials`
});

// 2. Get the authorization ID from your database
authorizationID = database.lookupAuthorizationID();

// 3. Call PayPal to reauthorize the authorization
reauthorization = http.post(PAYPAL_AUTHORIZATION_API + authorizationID + '/reauthorize', {
  headers: {
    Accept:        `application/json`,
    Authorization: `Bearer ${ auth.access_token }`,
    data:          {
      amount: {
        currency_code: 'USD'
        value:         '10.99',
      }
    }
  }
});

// 4. Handle any errors from the call
if (reauthorization.error) {
  console.error(reauthorization.error);
}

Learn how to reauthorize authorized payments in the Payments API Reference.

Note: Remember to swap the credentials and API URL from sandbox to production when going live with your integration.

Void authorization

You can void authorizations for various reasons, including non-availability of some items in cart and partial order cancelled by payer. You have flexibility to void an authorization and ensure further fund captures are cancelled.

Voids are not fully supported with captured authorizations.

  1. Set up your server to make calls to PayPal
  2. Get the authorization ID from your database
  3. Call PayPal to void the authorization
  4. Handle any errors from the call
// Note: This is example code. Each server platform and programming language has a different way of handling requests, making HTTP API calls, and serving responses to the browser.

// 1. Set up your server to make calls to PayPal

// 1a. Add your client ID and secret
PAYPAL_CLIENT = 'PAYPAL_SANDBOX_CLIENT';
PAYPAL_SECRET = 'PAYPAL_SANDBOX_SECRET';

// 1b. Point your server to the PayPal API
PAYPAL_OAUTH_API         = 'https://api-m.sandbox.paypal.com/v1/oauth2/token/';
PAYPAL_AUTHORIZATION_API = 'https://api-m.sandbox.paypal.com/v2/payments/authorizations/';

// 1c. Get an access token from the PayPal API
basicAuth = base64encode(`${ PAYPAL_CLIENT }:${ PAYPAL_SECRET }`);
auth = http.post(PAYPAL_OAUTH_API {
  headers: {
    Accept:        `application/json`,
    Authorization: `Basic ${ basicAuth }`
  },
  data: `grant_type=client_credentials`
});

// 2. Get the authorization ID from your database
authorizationID = database.lookupAuthorizationID();

// 3. Call PayPal to void the authorization
voidedAuth = http.post(PAYPAL_AUTHORIZATION_API + authorizationID + '/void', {
  headers: {
    Accept:        `application/json`,
    Authorization: `Bearer ${ auth.access_token }`,
    data:          {
      amount: {
        currency_code: 'USD'
        value:         '10.99',
      }
    }
  }
});

// 4. Handle any errors from the call
if (voidedAuth.error) {
  console.error(voidedAuth.error);
}

Learn how to void authorized payments in the Payments API Reference.

Note: Remember to swap the credentials and API URL from sandbox to production when going live with your integration.