PayPal Checkout

Authorize and Capture Funds

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

The time periods for authorization and capture are:

Period Duration Description
Authorization

A 29-day period that begins when the customer authorizes the payment.

Note: A day is defined as the start of the calendar day when an authorization or reauthorization is made, from 00:00 to 23:50 Pacific Time.

The authorization places the customer's balance on hold to ensure that you can capture the funds.

Honor

A three-day period from day one to day three of the authorization period.

Note: A day is defined as the start of the calendar day when an authorization or reauthorization is made, from 00:00 to 23:50 Pacific Time.

After a successful authorization or reauthorization, PayPal honors the authorized funds for three days. However, PayPal cannot ensure that 100% of the funds will be available.

You can only reauthorize a payment after the honor period concludes.

To ensure that funds are still available, you can re-authorize a payment after the initial three-day honor period from days four to 29, after the three-day honor period for the original authorization expires. A re-authorized payment has a new, three-day honor period and there should be only one re-authorization within the honor period. If 30 days have passed from the original authorization, you must create a new authorization. You can re-authorize a transaction once for up to 115% of the original authorization or $75 USD more, whichever is less.

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

Day Action Authorization period Honor period
1 Authorization-1 Begins 29-day authorization period Days 1 through 3
4 Reauthorization-1 on Authorization-1 Within 29-day authorization period Days 4 through 7
8 Reauthorization-2 on Authorization-1 Within 29-day authorization period Days 8 through 11

For any payment type, you can capture less than the 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.

Use this fully-annotated code sample to:

  1. Set up your server to make calls to PayPal
  2. Set up your server to receive a call from the client with the order ID
  3. Call PayPal to get the transaction details
  4. Handle any errors from the call
  5. Validate the transaction details are as expected
  6. Save the transaction in your database
  7. Return a successful response to the client

Note: To install the PayPal SDK on your server, see the Set up Server-Side SDK guide. If you are calling the API directly, you do not need to install the SDK.

// Note: This code is intended as a *pseudocode* example. 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.sandbox.paypal.com/v1/oauth2/token/';
PAYPAL_ORDER_API = 'https://api.sandbox.paypal.com/v2/checkout/orders/';

// 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. Set up your server to receive a call from the client
function handleRequest(request, response) {

  // 2a. Get the order ID from the request body
  orderID = request.body.orderID;

  // 3. Call PayPal to get the transaction details
  details = http.get(PAYPAL_ORDER_API + orderID, {
    headers: {
      Accept:        `application/json`,
      Authorization: `Bearer ${ auth.access_token }`
    }
  });

  // 4. Handle any errors from the call
  if (details.error) {
    return response.send(500);
  }

  // 5. Validate the transaction details are as expected
  if (details.purchase_units[0].amount.value !== '5.77') {
    return response.send(400);
  }

  // 6. Save the transaction in your database
  database.saveTransaction(orderID);

  // 7. Return a successful response to the client
  return response.send(200);
}
curl -v -X GET https://api.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T \
-H "Content-Type: application/json" \
-H "Authorization: Bearer Access-Token"
// 1. Set up your server to make calls to PayPal

// 1a. Import the SDK package
const checkoutNodeJssdk = require('@paypal/checkout-server-sdk');

// 1b. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
/**
 *
 * PayPal HTTP client dependency
 */
const payPalClient = require('../Common/payPalClient');

// 2. Set up your server to receive a call from the client
module.exports = async function handleRequest(req, res) {

  // 2a. Get the order ID from the request body
  const orderID = req.body.orderID;

  // 3. Call PayPal to get the transaction details
  let request = new checkoutNodeJssdk.orders.OrdersGetRequest(orderID);

  let order;
  try {
    order = await payPalClient.client().execute(request);
  } catch (err) {

    // 4. Handle any errors from the call
    console.error(err);
    return res.send(500);
  }

  // 5. Validate the transaction details are as expected
  if (order.result.purchase_units[0].amount.value !== '220.00') {
    return res.send(400);
  }

  // 6. Save the transaction in your database
  // await database.saveTransaction(orderID);

  // 7. Return a successful response to the client
  return res.send(200);
}
<?php

namespace Sample;

require __DIR__ . '/vendor/autoload.php';
//1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
use Sample\PayPalClient;
use PayPalCheckoutSdk\Orders\OrdersGetRequest;

class GetOrder
{

  // 2. Set up your server to receive a call from the client
  /**
   *You can use this function to retrieve an order by passing order ID as an argument.
   */
  public static function getOrder($orderId)
  {

    // 3. Call PayPal to get the transaction details
    $client = PayPalClient::client();
    $response = $client->execute(new OrdersGetRequest($orderId));
    /**
     *Enable the following line to print complete response as JSON.
     */
    //print json_encode($response->result);
    print "Status Code: {$response->statusCode}\n";
    print "Status: {$response->result->status}\n";
    print "Order ID: {$response->result->id}\n";
    print "Intent: {$response->result->intent}\n";
    print "Links:\n";
    foreach($response->result->links as $link)
    {
      print "\t{$link->rel}: {$link->href}\tCall Type: {$link->method}\n";
    }
    // 4. Save the transaction in your database. Implement logic to save transaction to your database for future reference.
    print "Gross Amount: {$response->result->purchase_units[0]->amount->currency_code} {$response->result->purchase_units[0]->amount->value}\n";

    // To print the whole response body, uncomment the following line
    // echo json_encode($response->result, JSON_PRETTY_PRINT);
  }
}

/**
 *This driver function invokes the getOrder function to retrieve
 *sample order details.
 *
 *To get the correct order ID, this sample uses createOrder to create a new order
 *and then uses the newly-created order ID with GetOrder.
 */
if (!count(debug_backtrace()))
{
  GetOrder::getOrder('REPLACE-WITH-ORDER-ID', true);
}
?>
# 1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
from sample import PayPalClient
from paypalcheckoutsdk.orders import OrdersGetRequest

class GetOrder(PayPalClient):

  #2. Set up your server to receive a call from the client
  """You can use this function to retrieve an order by passing order ID as an argument"""   
  def get_order(self, order_id):
    """Method to get order"""
    request = OrdersGetRequest(order_id)
    #3. Call PayPal to get the transaction
    response = self.client.execute(request)
    #4. Save the transaction in your database. Implement logic to save transaction to your database for future reference.
    print 'Status Code: ', response.status_code
    print 'Status: ', response.result.status
    print 'Order ID: ', response.result.id
    print 'Intent: ', response.result.intent
    print 'Links:'
    for link in response.result.links:
      print('\t{}: {}\tCall Type: {}'.format(link.rel, link.href, link.method))
    print 'Gross Amount: {} {}'.format(response.result.purchase_units[0].amount.currency_code,
                       response.result.purchase_units[0].amount.value)

"""This driver function invokes the get_order function with
   order ID to retrieve sample order details. """
if __name__ == '__main__':
  GetOrder().get_order('REPLACE-WITH-VALID-ORDER-ID')
# 1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
require_relative '../paypal_client'
require 'json'
require 'ostruct'

include PayPalCheckoutSdk::Orders

module Samples
  class GetOrder

  #2. Set up your server to receive a call from the client
  # You can use this function to retrieve an order by passing order ID as an argument
  def get_order(order_id)
    request = OrdersGetRequest::new(order_id)
    #3. Call PayPal to get the transaction
    response = PayPalClient::client::execute(request)
    #4. Save the transaction in your database. Implement logic to save transaction to your database for future reference.
    puts "Status Code: " + response.status_code.to_s
    puts "Status: " + response.result.status
    puts "Order ID: " + response.result.id
    puts "Intent: " + response.result.intent
    puts "Links:"
    for link in response.result.links
    # You could also call this link.rel or link.href, but method is a reserved keyword for RUBY. Avoid calling link.method.
    puts "\t#{link["rel"]}: #{link["href"]}\tCall Type: #{link["method"]}"
    end
    puts "Gross Amount: " + response.result.purchase_units[0].amount.currency_code + response.result.purchase_units[0].amount.value
  end
  end
end

# This driver function invokes the get_order function
# with order ID to retrieve sample order details.
if __FILE__ == $0
   Samples::GetOrder::new::get_order('REPLACE-WITH-VALID-ORDER-ID')
end
package com.paypal;

import java.io.IOException;

import org.json.JSONObject;

import com.braintreepayments.http.HttpResponse;
import com.braintreepayments.http.serializer.Json;
import com.paypal.orders.Order;
import com.paypal.orders.OrdersGetRequest;

/*
*
*1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
*This step extends the SDK client.  It's not mandatory to extend the client, you can also inject it.
*/
public class GetOrder extends PayPalClient {

  //2. Set up your server to receive a call from the client
  /**
   *Method to perform sample GET on an order
   *
   *@throws IOException Exceptions from the API, if any
   */
  public void getOrder(String orderId) throws IOException {
    OrdersGetRequest request = new OrdersGetRequest(orderId);
    //3. Call PayPal to get the transaction
    HttpResponse<Order> response = client().execute(request);
    //4. Save the transaction in your database. Implement logic to save transaction to your database for future reference.
    System.out.println("Full response body:");
    System.out.println(new JSONObject(new Json().serialize(response.result())).toString(4));
  }

  /**
   *This driver method invokes the getOrder function with
   *order ID to retrieve order details.
   *
   *To get the correct order ID, this sample uses createOrder to create
   *a new order and then uses the newly-created order ID as a
   *parameter to getOrder.
   *
   *@param args
   *@throws IOException
   */
  public static void main(String[] args) throws IOException {
    new GetOrder().getOrder("REPLACE-WITH-VALID-ORDER-ID");
  }
}
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

//1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
using BraintreeHttp;
using PayPalCheckoutSdk.Core;
using PayPalCheckoutSdk.Orders;

namespace Samples
{
  public class GetOrderSample
  {

    //2. Set up your server to receive a call from the client
    /*
      You can use this method to retrieve an order by passing the order ID.
     */
    public async static Task<HttpResponse> GetOrder(string orderId, bool debug = false)
    {
      OrdersGetRequest request = new OrdersGetRequest(orderId);
      //3. Call PayPal to get the transaction
      var response = await PayPalClient.client().Execute(request);
      //4. Save the transaction in your database. Implement logic to save transaction to your database for future reference.
      var result = response.Result<Order>();
      Console.WriteLine("Retrieved Order Status");
      Console.WriteLine("Status: {0}", result.Status);
      Console.WriteLine("Order Id: {0}", result.Id);
      Console.WriteLine("Intent: {0}", result.Intent);
      Console.WriteLine("Links:");
      foreach (LinkDescription link in result.Links)
      {
        Console.WriteLine("\t{0}: {1}\tCall Type: {2}", link.Rel, link.Href, link.Method);
      }
      AmountWithBreakdown amount = result.PurchaseUnits[0].Amount;
      Console.WriteLine("Total Amount: {0} {1}", amount.CurrencyCode, amount.Value);

      return response;
    }

    /*
      This driver method invokes the getOrder function with
      order ID to retrieve order details.

      To get the correct order ID, this sample uses createOrder to create
      a new order and then uses the newly-created order ID with GetOrder.
     */
    static void Main(string[] args)
    {
      GetOrder("REPLACE-WITH-VALID-ORDER-ID").Wait();
    }
  }
}

For the full list of keys you can retrieve from /v2/checkout/orders/, see the Orders Get 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.

  1. Set up your server to make calls to PayPal
  2. Get the authorization ID from your database
  3. Call PayPal to capture the authorization
  4. Save the capture ID to your database
  5. Handle any errors from the call

Note: To install the PayPal SDK on your server, see the Set up Server-Side SDK guide. If you are calling the API directly, you do not need to install the SDK.

// Note: This code is intended as a *pseudocode* example. 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.sandbox.paypal.com/v1/oauth2/token/';
PAYPAL_AUTHORIZATION_API = 'https://api.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 capture the authorization
capture = http.post(PAYPAL_AUTHORIZATION_API + authorizationID + '/capture', {
  headers: {
    Accept:        `application/json`,
    Authorization: `Bearer ${ auth.access_token }`
  }
});

// 4. Save the capture ID to your database
if (!capture.error) {
  captureID = capture.purchase_units[0]
    .payments.captures[0].id;
  database.saveCaptureID(captureID);
}

// 5. Handle any errors from the call
if (capture.error) {
  return console.error(capture.error);
}
curl -v -X POST https://api.sandbox.paypal.com/v2/checkout/orders/ORDER-ID/authorize \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer " \
  -H "PayPal-Request-Id: 7b92603e-77ed-4896-8e78-5dea2050476a"
// 1. Set up your server to make calls to PayPal

// 1a. Import the SDK package
const checkoutNodeJssdk = require('@paypal/checkout-server-sdk');

// 1b. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
/**
 *
 * PayPal HTTP client dependency
 */
const payPalClient = require('../Common/payPalClient');

module.exports = async function captureAuthorization() {

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

  // 3. Call PayPal to capture the authorization
  const request = new checkoutNodeJssdk.payments.AuthorizationsCaptureRequest(authorizationID);
  request.requestBody({});
  try {
    const capture = await payPalClient.client().execute(request);

    // 4. Save the capture ID to your database for future reference.
    const captureID = capture.result.purchase_units[0]
        .payments.captures[0].id;
    //await database.saveCaptureID(captureID);

  } catch (err) {

    // 5. Handle any errors from the call
    console.error(err);
  }
}
<?php
namespace Sample\AuthorizeIntentExamples;

require __DIR__ . '/vendor/autoload.php';
//1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
use Sample\PayPalClient;
use PayPalCheckoutSdk\Payments\AuthorizationsCaptureRequest;

class CaptureAuthorization
{

  // 2. Set up your server to receive a call from the client
  /**
   *Use the following function to capture Authorization.
   *Pass a valid authorization ID as an argument.
   */
  public static function captureAuth($authorizationId, $debug=false)
  {
    $request = new AuthorizationsCaptureRequest($authorizationId);
    $request->body = self::buildRequestBody();
    // 3. Call PayPal to capture an authorization.
    $client = PayPalClient::client();
    $response = $client->execute($request);
    // 4. Save the capture ID to your database for future reference.
    if ($debug)
    {
      print "Status Code: {$response->statusCode}\n";
      print "Status: {$response->result->status}\n";
      print "Capture ID: {$response->result->id}\n";
      print "Links:\n";
      foreach($response->result->links as $link)
      {
        print "\t{$link->rel}: {$link->href}\tCall Type: {$link->method}\n";
      }
      // To toggle printing the whole response body comment/uncomment
      // the follwowing line
      echo json_encode($response->result, JSON_PRETTY_PRINT), "\n";
    }
    return $response;
  }

   /**
   *You can use the following method to build the capture request body.
   *Refer to the Payments API reference for more information.
   */
  public static function buildRequestBody()
  {
    return "{}";
  }
}

/**
 *Driver function for invoking the capture flow.
 */
if (!count(debug_backtrace()))
{
  CaptureAuthorization::captureAuth(&apos REPLACE-WITH-VALID-APPROVED-AUTH-ID', true);
}
?>
# 1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
from sample import PayPalClient
from paypalcheckoutsdk.payments import AuthorizationsCaptureRequest
import json

class CaptureAuthorization(PayPalClient):

  #2. Set up your server to receive a call from the client
  """Use this function to capture an approved authorization.
     Pass a valid authorization ID as an argument to this function."""
  def capture_auth(self, authorization_id, debug=False):
    """Method to capture order using authorization_id"""
    request = AuthorizationsCaptureRequest(authorization_id)
    request.request_body(self.build_request_body())
    # 3. Call PayPal to capture an authorization.
    response = self.client.execute(request)
    # 4. Save the capture ID to your database for future reference.
    if debug:
      print 'Status Code: ', response.status_code
      print 'Status: ', response.result.status
      print 'Capture ID: ', response.result.id
      print 'Links: '
      for link in response.result.links:
        print('\t{}: {}\tCall Type: {}'.format(link.rel, link.href, link.method))
      json_data = self.object_to_json(response.result)
      print "json_data: ", json.dumps(json_data,indent=4)
    return response

  """Sample request body to Capture Authorization."""
  @staticmethod
  def build_request_body():
    return {}


"""This driver function invokes the capture order function with
   a valid authorization ID to capture. Replace the auth_id value with
   a valid authorization ID"""
if __name__ == "__main__":
  auth_id = &apos REPLACE-WITH-VALID-APPROVED-AUTH-ID'
  CaptureAuthorization().capture_auth(auth_id, debug=True)
# 1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
require_relative '../paypal_client'
include PayPalCheckoutSdk::Payments
module Samples
  module AuthorizeIntentExamples
    class CaptureAuthorization

      #2. Set up your server to receive a call from the client
      # Use this function to capture on an authorization.
      # Pass a valid authorization ID as an argument.
      def capture_auth (authorization_id, debug=false)
        request = AuthorizationsCaptureRequest::new(authorization_id)
        request.prefer("return=representation")
        # You can update the fields in the following request body
        # as needed. Refer to the Payments API reference for more information.
        request.request_body({})
        begin
          # 3. Call PayPal to capture an authorization.
          response = PayPalClient::client::execute(request)
          # 4. Save the capture ID to your database for future reference.
          if debug
            puts "Status Code: " + response.status_code.to_s
            puts "Status: " + response.result.status
            puts "Order ID: " + response.result.id
            puts "Intent: " + response.result.intent
            puts "Links:"
            for link in response.result.links
              # This could also be called link.rel or link.href, but
              # method is a reserved keyword for Ruby. Avoid calling link.method.
              puts "\t#{link["rel"]}: #{link["href"]}\tCall Type: #{link["method"]}"
            end
            puts PayPalClient::openstruct_to_hash(response.result).to_json
          end
          return response
        rescue BraintreeHttp::HttpError => ioe
          # Exception occurred while processing the refund.
          puts " Status Code: " + ioe.status_code.to_s
          puts " Debug Id: " + ioe.result.debug_id
          puts " Response: " + PayPalClient::openstruct_to_hash(ioe.result).to_json
        end
      end
    end
  end
end

# This driver function invokes the capture_order function with
# a valid authorization ID. Replace the authorization ID with a valid
# authorization ID.
if __FILE__ == $0
  Samples::AuthorizeIntentExamples::CaptureAuthorization::new::capture_auth(&apos REPLACE-WITH-VALID-APPROVED-AUTH-ID',true)
end
package com.paypal.AuthorizeIntentExamples;

import java.io.IOException;

import org.json.JSONObject;

import com.braintreepayments.http.HttpResponse;
import com.braintreepayments.http.serializer.Json;
import com.paypal.PayPalClient;
import com.paypal.orders.OrderRequest;
import com.paypal.payments.AuthorizationsCaptureRequest;
import com.paypal.payments.Capture;
import com.paypal.payments.LinkDescription;

/*
*
*1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
*This step extends the SDK client. It's not mandatory to extend the client, you can also inject it.
*/
public class CaptureAuthorization extends PayPalClient {

  //2. Set up your server to receive a call from the client
  /**
   *Method to capture order after authorization
   *
   *@param authId Authorization ID from authorizeOrder response
   *@param debug  true = print response data
   *@return HttpResponse<Capture> response received from API
   *@throws IOException Exceptions from API if any
   */
  public HttpResponse<Capture> captureAuth(String authId, boolean debug) throws IOException {
    AuthorizationsCaptureRequest request = new AuthorizationsCaptureRequest(authId);
    request.requestBody(buildRequestBody());
    //3. Call PayPal to capture an authorization.
    HttpResponse<Capture> response = client().execute(request);
    //4. Save the capture ID to your database for future reference.
    if (debug) {
      System.out.println("Status Code: " + response.statusCode());
      System.out.println("Status: " + response.result().status());
      System.out.println("Capture ID: " + response.result().id());
      System.out.println("Links: ");
      for (LinkDescription link : response.result().links()) {
        System.out.println("\t" + link.rel() + ": " + link.href() + "\tCall Type: " + link.method());
      }
      System.out.println("Full response body:");
      System.out.println(new JSONObject(new Json()
              .serialize(response.result())).toString(4));
    }
    return response;
  }

  /**
   *Create an empty body for capture request
   *
   *@return OrderRequest request with empty body
   */
  public OrderRequest buildRequestBody() {
    return new OrderRequest();
  }

  /**
   *This function uses the captureOrder function to
   *capture an authorization. Replace the authorization ID with
   *the valid authorization ID.
   *
   *@param args
   */
  public static void main(String[] args) {
    try {
      new CaptureAuthorization().captureAuth(" REPLACE-WITH-VALID-APPROVED-AUTH-ID", true);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

}
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
//1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
using Samples;
using PayPalCheckoutSdk.Payments;
using BraintreeHttp;

namespace Samples.AuthorizeIntentExamples
{
  public class CaptureAuthorizationSample
  {
    //2. Set up your server to receive a call from the client
    // Use this method to capture the payment on the approved authorization.
    public async static Task<HttpResponse> CaptureAuth(string AuthorizationId, bool debug = false)
    {
      var request = new AuthorizationsCaptureRequest(AuthorizationId);
      request.Prefer("return=representation");
      request.RequestBody(new CaptureRequest());
      //3. Call PayPal to capture an authorization.
      var response = await PayPalClient.client().Execute(request);
      //4. Save the capture ID to your database for future reference.
      if (debug)
      {
        var result = response.Result<Capture>();
        Console.WriteLine("Status: {0}", result.Status);
        Console.WriteLine("Order Id: {0}", result.Id);
        Console.WriteLine("Links:");
        foreach (LinkDescription link in result.Links)
        {
          Console.WriteLine("\t{0}: {1}\tCall Type: {2}", link.Rel,
                                  link.Href,
                                  link.Method);
        }
        Console.WriteLine("Response JSON: \n {0}",
                    PayPalClient.ObjectToJSONString(result));
      }

      return response;
    }

    static void Main(string[] args)
    {
      string AuthId = " REPLACE-WITH-VALID-APPROVED-AUTH-ID";
      CaptureAuth(AuthId, true).Wait();
    }
  }
}

Read about capturing authorized payments, including sample responses, in the Payments API reference.

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

{
  "id": "1HW32023TU4585620"
}

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

PayPal holds the authorized amount in the payer's account for a three-day honor period. When the honor period expires, you must reauthorize the transaction amount to ensure that funds are still available.

You have an option to reauthorize only within validity of the order from day four to day 29. After 29 days, a new authorization is required.

A reauthorized payment has a new three-day honor period. You can reauthorize an authorized payment once for up to 115% of the original authorized amount, not to exceed an increase of $75 USD.

  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 code is intended as a *pseudocode* example. 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.sandbox.paypal.com/v1/oauth2/token/';
PAYPAL_AUTHORIZATION_API = 'https://api.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: When you go live with your integration, remember to swap the credentials and API URL from sandbox to live.

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 code is intended as a *pseudocode* example. 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.sandbox.paypal.com/v1/oauth2/token/';
PAYPAL_AUTHORIZATION_API = 'https://api.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: When you go live with your integration, remember to swap the credentials and API URL from sandbox to live.

Feedback