Authorize a payment and capture funds later

SDKCurrentStandardDirect merchant

Last updated: Mar 4th, 11:57pm

The standard Checkout integration supports a 2-step authorize and capture payment model.

Authorize a buyer's funds before you capture them, then settle the purchase later. An authorization places a hold on the funds and is valid for 29 days. For example, use authorize and capture to complete a task before finalizing the payment, such as verifying that you have the item in stock.

How it works

  1. The payer checks out and provides a payment method.
  2. You authorize the payment.
  3. A hold is placed on the payment method until you are ready to capture payment.
  4. You finalize the transaction and capture the payment.
  5. The payer's payment method is charged.

Know before you code

Required
You need a developer account to get sandbox credentials

PayPal uses the following REST API credentials, which you can get from the developer dashboard:

  • Client ID: Authenticates your account with PayPal and identifies an app in your sandbox.
  • Client secret: Authorizes an app in your sandbox. Keep this secret safe and don't share it.
DashboardRead the guide

Required
Standard Checkout

This feature modifies an existing standard Checkout integration and uses the following:

  • JavaScript SDK: Adds PayPal-supported payment methods.
  • Orders REST API: Create, update, retrieve, authorize, and capture orders.
  • Payments REST API: Authorize, capture, retrieve, and refund payments.
  • You can use Postman to explore and test PayPal APIs.
1

Separate authorize and capture in the approval intent

The default approval intent of the JavaScript SDK is to both authorize the transaction and capture payment immediately. To split authorize and capture into separate actions, add &intent=authorize to the JavaScript SDK script tag, as shown in the following example:

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

    Authorize payment

    The onApprove function in the default integration captures the payment immediately. Replace the existing onApprove function with the following code. This code authorizes the payment but doesn't capture it.

      1onApprove: function(data) {
      2 // Authorize the transaction
      3 return fetch('/my-server/authorize-paypal-order', {
      4 method: 'post',
      5 body: JSON.stringify({
      6 orderID: data.orderID
      7 })
      8 })
      9 .then(response => response.json())
      10 .then((authorizePayload) => {
      11 // Get the authorization id from your payload
      12 const authorizationID = authorizePayload.authorizationID;
      13 // Optional message given to purchaser
      14 alert(`
      15 You have authorized this transaction.
      16 Order ID: ${data.orderID}
      17 Authorization ID: ${authorizationID}
      18 `);
      19
      20 // Later you can use your server to validate and capture the transaction
      21 });
      22 })
      23}

      Step result

      A successful authorization results in:

      • A Pending transaction in your business account.
      • A hold on the money that is valid for 29 days. After a successful authorization, capture the payment within the 3-day honor period. Payment capture is subject to risk and money availability.

      You can use your server-side code to capture the order ID and authorization ID passed in the fetch method in the onApprove function.

      3

      Capture order and authorization IDs

      Each server implementation is different. Make sure you have logic in your server-side code to receive the order ID and authorization ID that you pass from the client-side JavaScript fetch function.

      4

      Save order information

      Copy the following code and modify it to save the details to your server-side database:

      Sample request

      API endpoint used: Show order details

        1curl -v -X GET https://api-m.sandbox.paypal.com/v2/checkout/orders/48S239579N169645 \\
        2 -H "Content-Type: application/json" \\
        3 -H "Authorization: Bearer ACCESS-TOKEN" \\

        Modify the code

        After you copy the code in the sample request, modify the following:

        • Access-Token - Your access token.
        • Order ID - In the URI for the API call, replace the sample ID with your order ID. In this example, the sample order ID is 48S239579N169645.

        Step result

        A successful request results in the following:

        • A return status code of HTTP 200 OK.
        • A JSON response body containing order details that you can save to your server-side database.

        After you capture the order details, you can complete any business tasks, such as verifying you have the item in stock, before you capture the payment.


        Sample response

          1{
          2 "id": "48S239579N1696452",
          3 "intent": "AUTHORIZE",
          4 "purchase_units": [{
          5 "reference_id": "default",
          6 "amount": {
          7 "currency_code": "USD",
          8 "value": "30.00"
          9 },
          10 "payee": {
          11 "email_address": "payee@example.com",
          12 "merchant_id": "JK9AB28SRU4XL"
          13 },
          14 "shipping": {
          15 "name": {
          16 "full_name": "Firstname Lastname"
          17 },
          18 "address": {
          19 "address_line_1": "123 Main St.",
          20 "admin_area_2": "Anytown",
          21 "admin_area_1": "CA",
          22 "postal_code": "12345",
          23 "country_code": "US"
          24 }
          25 },
          26 "payments": {
          27 "authorizations": [{
          28 "status": "CREATED",
          29 "id": "66P728836U784324A",
          30 "amount": {
          31 "currency_code": "USD",
          32 "value": "30.00"
          33 },
          34 "seller_protection": {
          35 "status": "ELIGIBLE",
          36 "dispute_categories": ["ITEM_NOT_RECEIVED", "UNAUTHORIZED_TRANSACTION"]
          37 },
          38 "expiration_time": "2020-01-01T15:57:51Z",
          39 "links": [{
          40 "href": "https://api-m.sandbox.paypal.com/v2/payments/authorizations/66P728836U784324A",
          41 "rel": "self",
          42 "method": "GET"
          43 }, {
          44 "href": "https://api-m.sandbox.paypal.com/v2/payments/authorizations/66P728836U784324A/capture",
          45 "rel": "capture",
          46 "method": "POST"
          47 }, {
          48 "href": "https://api-m.sandbox.paypal.com/v2/payments/authorizations/66P728836U784324A/void",
          49 "rel": "void",
          50 "method": "POST"
          51 }, {
          52 "href": "https://api-m.sandbox.paypal.com/v2/payments/authorizations/66P728836U784324A/reauthorize",
          53 "rel": "reauthorize",
          54 "method": "POST"
          55 }, {
          56 "href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/48S239579N1696452",
          57 "rel": "up",
          58 "method": "GET"
          59 }],
          60 "create_time": "2020-02-03T15:57:51Z",
          61 "update_time": "2020-02-03T15:57:51Z"
          62 }]
          63 }
          64 }],
          65 "payer": {
          66 "name": {
          67 "given_name": "Firstname",
          68 "surname": "Lastname"
          69 },
          70 "email_address": "payer@example.com",
          71 "payer_id": "8Y7QBG68GYPHQ",
          72 "address": {
          73 "country_code": "US"
          74 }
          75 },
          76 "create_time": "2020-02-03T15:57:17Z",
          77 "update_time": "2020-02-03T15:57:51Z",
          78 "links": [{
          79 "href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/48S239579N1696452",
          80 "rel": "self",
          81 "method": "GET"
          82 }],
          83 "status": "COMPLETED"
          84}
          5

          Reauthorize payment

          If you haven’t captured the payment within 3 days of authorization, you can reauthorize the payment to make sure the money is still available.

          You can issue multiple reauthorizations within the 29-day authorization period after the honor period expires. A reauthorization generates a new authorization ID and restarts the 3-day honor period. Use the new authorization ID on subsequent captures.

          If you reauthorize on the 27th day of the authorization period, you get only 2 days of the honor period.

          To reauthorize a payment, copy the following code and modify it.

          Sample request

          API endpoint used: Reauthorize authorized payment

            1curl -v -X POST https://api-m.sandbox.paypal.com/v2/payments/authorizations/66P728836U784324A/reauthorize \\
            2 -H "Content-Type: application/json" \\
            3 -H "Authorization: Bearer ACCESS-TOKEN" \\
            4 -H "PayPal-Request-Id: PAYPAL-REQUEST-ID" \\

            Modify the code

            After you copy the code in the sample request, modify the following:

            • Access-Token - Your access token.
            • Authorization ID - In the URI of the API call, replace the sample ID with your authorization ID. In this example, the authorization ID is 66P728836U784324A.
            • PAYPAL-REQUEST-ID - Replace the sample ID with a unique alphanumeric ID that you generate. The PayPal request ID helps prevent duplicate authorizations if the API call is interrupted. For more information, see API idempotency.

            Step result

            A successful request results in the following:

            • A return status code of HTTP 201 Created.
            • A JSON response body containing a new authorization ID that you can use to capture the payment.

            Sample response

              1{
              2 "id": "8AA831015G517922L",
              3 "status": "CREATED",
              4 "links": [{
              5 "rel": "self",
              6 "method": "GET",
              7 "href": "https://api-m.paypal.com/v2/payments/authorizations/8AA831015G517922L"
              8 }, {
              9 "rel": "capture",
              10 "method": "POST",
              11 "href": "https://api-m.paypal.com/v2/payments/authorizations/8AA831015G517922L/capture"
              12 }, {
              13 "rel": "void",
              14 "method": "POST",
              15 "href": "https://api-m.paypal.com/v2/payments/authorizations/8AA831015G517922L/void"
              16 }, {
              17 "rel": "reauthorize",
              18 "method": "POST",
              19 "href": "https://api-m.paypal.com/v2/payments/authorizations/8AA831015G517922L/reauthorize"
              20 }]
              21}
              6

              Capture payment

              To capture the payment, copy the following code and modify it.

              Sample request

              API endpoint used: Capture authorized payment

                1curl -v -X POST https://api-m.sandbox.paypal.com/v2/payments/authorizations/66P728836U784324A/capture \\
                2 -H "Content-Type: application/json" \\
                3 -H "Authorization: Bearer ACCESS-TOKEN" \\
                4 -H "PayPal-Request-Id: PAYPAL-REQUEST-ID" \\

                Modify the code

                After you copy the code in the sample request, modify the following:

                • ACCESS-TOKEN - Your access token.
                • Authorization ID - In the URI for the API call, replace the sample ID with your authorization ID. The authorization ID is either the original authorization ID or the ID from reauthorizing the transaction. In this example, the authorization ID is 66P728836U784324A.
                • PAYPAL-REQUEST-ID - Replace the sample ID with a unique alphanumeric ID you generate. The PayPal request ID helps prevent duplicate authorizations if the API call is interrupted. For more information, see API idempotency.

                Step result

                A successful request results in the following:

                • A return status code of HTTP 201 Created.
                • A JSON response body containing details for the captured payment. Use the that is ID returned if you need to refund the transaction in the future.
                • The transaction in your business account changes from Pending to Completed.

                Sample response

                  1{
                  2 "id": "5KA38057EC136584R",
                  3 "status": "COMPLETED",
                  4 "links": [{
                  5 "href": "https://api-m.sandbox.paypal.com/v2/payments/captures/5KA38057EC136584R",
                  6 "rel": "self",
                  7 "method": "GET"
                  8 }, {
                  9 "href": "https://api-m.sandbox.paypal.com/v2/payments/captures/5KA38057EC136584R/refund",
                  10 "rel": "refund",
                  11 "method": "POST"
                  12 }, {
                  13 "href": "https://api-m.sandbox.paypal.com/v2/payments/authorizations/66P728836U784324A",
                  14 "rel": "up",
                  15 "method": "GET"
                  16 }]
                  17}