---
title: Verify & complete checkout
url: amazon-pay-checkout/verify-and-complete-checkout.html
---

**[Step 6 of 10]** The buyer is redirected to `checkoutResultReturnUrl` after Amazon Pay has processed the transaction. The Amazon Pay checkout session ID will be included as a query parameter. 

In this step, you will use the checkout session ID to confirm that the buyer has successfully returned to your site and finalize the `paymentIntent`. At the end of this step, you will be able to present the buyer with the checkout result.

<script>
  function keySpecifics(){
    const keyQuery = "?environmentSpecificKeys=";
    const currentSetting = window.location.search?.split("?environmentSpecificKeys=")[1] ?? 'false';
    const newSetting = currentSetting === 'false' ? 'true' : 'false';
    window.location = window.location.origin + window.location.pathname + keyQuery + newSetting // +  window.location.hash (not included as it feels weird to jump down)
  }
</script>
<div style="display:none" class="environmentSpecificKeys">
  <div markdown="span" class="alert alert-info" role="alert"><i class="fa fa-info-circle"></i> <b>Note:</b> If your publicKeyId <b>_does not_</b> have an environment prefix (does not begin with 'SANDBOX' or 'LIVE') follow <a href='#' onclick='keySpecifics()' rel='noopener noreferrer'>these instructions</a> instead.</div>
</div>
<div style="display:none" class="notEnvironmentSpecificKeys">
  <div markdown="span" class="alert alert-info" role="alert"><i class="fa fa-info-circle"></i> <b>Note:</b> If your publicKeyId has an environment prefix (for example: SANDBOX-AFVX7ULWSGBZ5535PCUQOY7B) follow <a href='#' onclick='keySpecifics()' rel='noopener noreferrer'>these instructions</a> instead.</div>
</div>


* TOC
{:toc}
{::options toc_levels="3" /}

***

### 1. Complete Checkout Session  

Use <a href="../amazon-pay-api-v2/checkout-session.md#complete-checkout-session" target="_blank" rel="noopener noreferrer">Complete Checkout Session</a> to confirm that the buyer has successfully returned to your site. The `chargeAmount` in the request must match the Checkout Session object `paymentDetails.chargeAmount` to verify order amount. You must also specify `totalOrderAmount` if one was provided for the Checkout Session object.

**Note:** Amazon Pay will not finalize the `paymentIntent` until you confirm checkout with Complete Checkout Session. Any Checkout Session that is not confirmed within 24 hours will be cancelled. If payment authorization was requested it will also be cancelled.


**Successful response:**

<a href="../amazon-pay-api-v2/checkout-session.md#complete-checkout-session" target="_blank" rel="noopener noreferrer">Complete Checkout Session</a> will return a success response if the transaction was processed successfully. Implement the guidance that corresponds to the Checkout Session `paymentIntent`:

<table width="100%" border="1"> 
    <tbody>
        <tr id='SNR9CAGnO6p'>
            <td id='s:SNR9CAGnO6p;SNR9CAhxnzV' style='vertical-align: top; font-weight: bold; width: 30%;' class='bold'>paymentIntent
                <br /></td>
            <td id='s:SNR9CAGnO6p;SNR9CA8ReW0' style='vertical-align: top; font-weight: bold; width: 70%;' class='bold'>Description
                <br /></td>
        </tr>
        <tr id='SNR9CAHofkb'>
            <td id='s:SNR9CAHofkb;SNR9CAhxnzV' style=''>AuthorizeWithCapture
                <br /></td>
            <td id='s:SNR9CAHofkb;SNR9CA8ReW0' style=''>Payment has been authorized and captured. <br><br>1. Store the <code>ChargeId</code> - You must store the <code>ChargeId</code> to process refunds.<br><br> 2. Store the <code>ChargePermissionId</code> - If you specified <code>totalOrderAmount</code> and there is uncaptured payment, see <a href="../amazon-pay-checkout/deferred-transactions.md" target="_blank" rel="noopener noreferrer">manage deferred payments</a> for more information. You can also use the <code>ChargePermissionId</code> to retrieve buyer and transaction info using <a href="../amazon-pay-api-v2/charge-permission.md#get-charge-permission" target="_blank" rel="noopener noreferrer">Get Charge Permission</a> for 30 days, you must store the data to persist the information beyond 30 days. 
                <br /></td>
        </tr>
        <tr id='SNR9CAGci5Y'>
            <td id='s:SNR9CAGci5Y;SNR9CAhxnzV' style=''>Authorize
                <br /></td>
            <td id='s:SNR9CAGci5Y;SNR9CA8ReW0' style=''>Payment has been authorized. <br><br>1. Store the <code>ChargeId</code> - You must store the ChargeID for deferred payment capture. See <a href="../amazon-pay-checkout/deferred-transactions.md" target="_blank" rel="noopener noreferrer">deferred transactions</a> for more info.<br><br> 2. Store the <code>ChargePermissionId</code> - If you specified <code>totalOrderAmount</code> and there is uncaptured payment, see <a href="../amazon-pay-checkout/deferred-transactions.md" target="_blank" rel="noopener noreferrer">manage deferred payments</a> for more information. You can also use the <code>ChargePermissionId</code> to retrieve buyer and transaction info using <a href="../amazon-pay-api-v2/charge-permission.md#get-charge-permission" target="_blank" rel="noopener noreferrer">Get Charge Permission</a> for 30 days, you must store the data to persist the information beyond 30 days. 
                <br /></td>
        </tr>
        <tr id='SNR9CA2df1n'>
            <td id='s:SNR9CA2df1n;SNR9CAhxnzV' style=''>Confirm
                <br /></td>
            <td id='s:SNR9CA2df1n;SNR9CA8ReW0' style=''>Payment has not been authorized or captured.<br><br>1. Store the <code>ChargePermissionId</code> - You must store the <code>ChargePermissionId</code> for deferred payment authorization. See <a href="../amazon-pay-checkout/deferred-transactions.md" target="_blank" rel="noopener noreferrer">deferred transactions</a> for more info. You can also use the <code>ChargePermissionId</code> to retrieve buyer and transaction info after checkout. You will only be able to retrieve the data using <a href="../amazon-pay-api-v2/charge-permission.md#get-charge-permission" target="_blank" rel="noopener noreferrer">Get Charge Permission</a> for 30 days, you must store the data to persist the information beyond 30 days.  
                <br /></td>
        </tr>
    </tbody>
</table>

**Error response:**

<a href="../amazon-pay-api-v2/checkout-session.md#complete-checkout-session" target="_blank" rel="noopener noreferrer">Complete Checkout Session</a> will return an error response for failed transactions. The buyer either canceled checkout or was unable to provide a valid payment instrument. You should:

1. Redirect the buyer to the start of checkout
2. Display a message such as: "Your payment was not successful. Please try another payment method.“

#### Request


<div style="display:none" class="environmentSpecificKeys">
<code style="color:black">
curl "https://pay-api.amazon.com/:version/checkoutSessions/:checkoutSessionId/complete" \<br />
-X POST<br />
-H "authorization:Px2e5oHhQZ88vVhc0DO%2FsShHj8MDDg%3DEXAMPLESIGNATURE"<br />
-H "x-amz-pay-date:20201012T235046Z"<br />
-d @request_body<br />
</code>
</div>
<div style="display:none" class="notEnvironmentSpecificKeys">
<code style="color:black">
curl "https://pay-api.amazon.com/:environment/:version/checkoutSessions/:checkoutSessionId/complete" \<br />
-X POST<br />
-H "authorization:Px2e5oHhQZ88vVhc0DO%2FsShHj8MDDg%3DEXAMPLESIGNATURE"<br />
-H "x-amz-pay-date:20201012T235046Z"<br />
-H "x-amz-pay-idempotency-key:AVLo5tI10BHgEk2jEXAMPLEKEY"<br />
-d @request_body<br />
</code>
</div>

#### Request body

```
{
    "chargeAmount": {
        "amount": "14.00",
        "currencyCode": "USD"
    }
}
```



#### Request parameters

<table width="100%" border="1">
    <tbody>
        <tr id='ERL9CAipzsl'>
            <td id='s:ERL9CAipzsl;ERL9CAFccoh' style='vertical-align: top; font-weight: bold; width: 30%;' class='bold'>Name
                <br /></td>
            <td id='s:ERL9CAipzsl;ERL9CAjQdu4' style='vertical-align: top; font-weight: bold; width: 20%;' class='bold'>Location
                <br /></td>
            <td id='s:ERL9CAipzsl;ERL9CAxmCJ7' style='vertical-align: top; font-weight: bold; width: 50%;' class='bold'>Description
                <br /></td>
        </tr>
        <tr id='ERL9CA4LMaA'>
            <td id='s:ERL9CA4LMaA;ERL9CAFccoh' style='vertical-align: top;'>checkoutSessionId<br><b>(required)</b><br><br>Type: string
                <br /></td>
            <td id='s:ERL9CA4LMaA;ERL9CAjQdu4' style='vertical-align: top;'>Path parameter
                <br /></td>
            <td id='s:ERL9CA4LMaA;ERL9CAxmCJ7' style='vertical-align: top;'>Checkout Session identifier
                <br /></td>
        </tr>
        <tr id='ERL9CAvm2Or'>
            <td id='s:ERL9CAvm2Or;ERL9CAFccoh' style='vertical-align: top;'>chargeAmount<br><b>(required)</b><br><br>Type: <a href="../amazon-pay-api-v2/checkout-session.md#type-price" target="_blank" rel="noopener noreferrer">price</a>
                <br /></td>
            <td id='s:ERL9CAvm2Or;ERL9CAjQdu4' style='vertical-align: top;'>Body
                <br /></td>
            <td id='s:ERL9CAvm2Or;ERL9CAxmCJ7' style='vertical-align: top;'>Amount to be processed using <code>paymentIntent</code> during checkout. Must match Checkout Session object <code>paymentDetails.chargeAmount</code>
                <br /></td>
        </tr>
        <tr id=''>
            <td id='' style='vertical-align: top;'>totalOrderAmount<br><br>Type: <a href="../amazon-pay-api-v2/checkout-session.md#type-price" target="_blank" rel="noopener noreferrer">price</a>
                <br /></td>
            <td id='' style='vertical-align: top;'>Body
                <br /></td>
            <td id='' style='vertical-align: top;'>Total order amount. Must match Checkout Session object <code>paymentDetails.totalOrderAmount</code> if a value was provided
                <br /></td>
        </tr>
    </tbody>
</table>

#### Sample Code

<div style="display:none" class="environmentSpecificKeys">
<ul id="profileTabs" class="nav nav-tabs">
  <li class="nav-item"><a class="active nav-link noExtIcon" href="#phptab-completeCheckoutSession" data-toggle="tab">PHP</a></li>
  <li class="nav-item"><a class="nav-link noExtIcon" href="#dotnettab-completeCheckoutSession" data-toggle="tab">.NET</a></li>
  <li class="nav-item"><a class="nav-link noExtIcon" href="#javatab-completeCheckoutSession" data-toggle="tab">Java</a></li>
  <li class="nav-item"><a class="nav-link noExtIcon" href="#nodejstab-completeCheckoutSession" data-toggle="tab">Node.js</a></li>
</ul>
<div class="tab-content">
  <div role="tabpanel" class="tab-pane active" id="phptab-completeCheckoutSession">   
<div markdown="block">
```
<?php

    include 'vendor/autoload.php';
    $amazonpay_config = array(
        'public_key_id' => 'YOUR_PUBLIC_KEY_ID',
        'private_key'   => 'keys/private.pem', // Path to RSA Private Key (or a string representation)
        'region'        => 'YOUR_REGION_CODE',
        'algorithm'     => 'AMZN-PAY-RSASSA-PSS-V2'
    );

    $payload = array(
        'chargeAmount' => array(
            'amount' => '14.00',
            'currencyCode' => 'USD'
        )
    );

    try {
        $client = new Amazon\Pay\API\Client($amazonpay_config);
        $result = $client->completeCheckoutSession('bd504926-f659-4ad7-a1a9-9a747aaf5275', $payload);
        
        if ($result['status'] === 202) {
            // Charge Permission is in AuthorizationInitiated state
            $response = json_decode($result['response'], true);
            $checkoutSessionState = $response['statusDetails']['state'];
            $chargeId = $response['chargeId'];
            $chargePermissionId = $response['chargePermissionId'];
        } 
        else if ($result['status'] === 200) {
            $response = json_decode($result['response'], true);
            $checkoutSessionState = $response['statusDetails']['state'];
            $chargePermissionId = $response['chargePermissionId'];
        } else {
            // check the error
            echo 'status=' . $result['status'] . '; response=' . $result['response'] . "\n";
        }
    } catch (Exception $e) {
        // handle the exception
        echo $e;
    }
?>
```

</div>
  </div>
  <div role="tabpanel" class="tab-pane" id="dotnettab-completeCheckoutSession">
<div markdown="block">
```
using Amazon.Pay.API.Types;
using Amazon.Pay.API.WebStore;
using Amazon.Pay.API.WebStore.Types;
using Amazon.Pay.API.WebStore.CheckoutSession;

public class Sample
{
    public WebStoreClient InitiateClient()
    {
        // set up config
        var payConfiguration = new ApiConfiguration
        (
            region: Region.YOUR_REGION_CODE,
            publicKeyId: "YOUR_PUBLIC_KEY_ID",
            privateKey: "PATH_OR_CONTENT_OF_YOUR_PRIVATE_KEY",
            algorithm: AmazonSignatureAlgorithm.V2
        );

        // init API client
        var client = new WebStoreClient(payConfiguration);

        return client;
    }

    public CheckoutSessionResponse CompleteCheckoutSession(string checkoutSessionId)
    {
        // prepare the request
        var request = new CompleteCheckoutSessionRequest(14.00M, Currency.USD);

        // send the request
        var result = client.CompleteCheckoutSession(checkoutSessionId, request);

        // check if API call was successful
        if (!result.Success)
        {
            // do something, e.g. throw an error
        }

        return result;
    }
}
```

</div>
  </div>
  <div role="tabpanel" class="tab-pane" id="javatab-completeCheckoutSession">
<div markdown="block">
```
import com.amazon.pay.api.AmazonPayResponse;
import com.amazon.pay.api.PayConfiguration;
import com.amazon.pay.api.WebstoreClient;
import com.amazon.pay.api.exceptions.AmazonPayClientException;
import com.amazon.pay.api.types.Region;

import org.json.JSONObject;

public void sample() {
    PayConfiguration payConfiguration = null;
    try {
        payConfiguration = new PayConfiguration()
            .setPublicKeyId("YOUR_PUBLIC_KEY_ID")
            .setRegion(Region.YOUR_REGION_CODE)
            .setPrivateKey("YOUR_PRIVATE_KEY")
            .setAlgorithm("AMZN-PAY-RSASSA-PSS-V2");

        WebstoreClient webstoreClient = new WebstoreClient(payConfiguration);
        AmazonPayResponse response = null;
        String checkoutSessionId = "bd504926-f659-4ad7-a1a9-9a747aaf5275";

        JSONObject payload = new JSONObject();

        JSONObject chargeAmount = new JSONObject();
        chargeAmount.put("amount", "14.00");
        chargeAmount.put("currencyCode", "USD");
        payload.put("chargeAmount", chargeAmount);

        response = webstoreClient.completeCheckoutSession(checkoutSessionId, payload);
        String chargePermissionId = response.getResponse().getString("chargePermissionId");
    } catch (AmazonPayClientException e) {
        e.printStackTrace();
    }
}

```

</div>
  </div>
  <div role="tabpanel" class="tab-pane" id="nodejstab-completeCheckoutSession">
<div markdown="block">
```html
const fs = require('fs');
const Client = require('@amazonpay/amazon-pay-api-sdk-nodejs');

const config = {
    publicKeyId: 'YOUR_PUBLIC_KEY_ID',
    privateKey: fs.readFileSync('tst/private.pem'),
    region: 'YOUR_REGION_CODE',
    algorithm: 'AMZN-PAY-RSASSA-PSS-V2' 
};    
                
const payload = {
    chargeAmount: {
        amount: "14.00",
        currencyCode: "USD"
    }
};
                        
const testPayClient = new Client.WebStoreClient(config);
const response = testPayClient.completeCheckoutSession('bd504926-f659-4ad7-a1a9-9a747aaf5275', payload);

response.then(function (result) {
    console.log(result.data);
}).catch(err => {
    console.log(err);
});
```

</div>
  </div>
</div>
</div>
<div style="display:none" class="notEnvironmentSpecificKeys">
<ul id="profileTabs" class="nav nav-tabs">
  <li class="nav-item"><a class="active nav-link noExtIcon" href="#phptab-completeCheckoutSession-NESK" data-toggle="tab">PHP</a></li>
  <li class="nav-item"><a class="nav-link noExtIcon" href="#dotnettab-completeCheckoutSession-NESK" data-toggle="tab">.NET</a></li>
  <li class="nav-item"><a class="nav-link noExtIcon" href="#javatab-completeCheckoutSession-NESK" data-toggle="tab">Java</a></li>
  <li class="nav-item"><a class="nav-link noExtIcon" href="#nodejstab-completeCheckoutSession-NESK" data-toggle="tab">Node.js</a></li>
</ul>
<div class="tab-content">
  <div role="tabpanel" class="tab-pane active" id="phptab-completeCheckoutSession-NESK">   
<div markdown="block">
```
<?php

    include 'vendor/autoload.php';
    $amazonpay_config = array(
        'public_key_id' => 'YOUR_PUBLIC_KEY_ID',
        'private_key'   => 'keys/private.pem', // Path to RSA Private Key (or a string representation)
        'region'        => 'YOUR_REGION_CODE',
        'sandbox'       => true,
        'algorithm'     => 'AMZN-PAY-RSASSA-PSS-V2'
    );

    $payload = array(
        'chargeAmount' => array(
            'amount' => '14.00',
            'currencyCode' => 'USD'
        )
    );

    try {
        $client = new Amazon\Pay\API\Client($amazonpay_config);
        $result = $client->completeCheckoutSession('bd504926-f659-4ad7-a1a9-9a747aaf5275', $payload);
        
        if ($result['status'] === 202) {
            // Charge Permission is in AuthorizationInitiated state
            $response = json_decode($result['response'], true);
            $checkoutSessionState = $response['statusDetails']['state'];
            $chargeId = $response['chargeId'];
            $chargePermissionId = $response['chargePermissionId'];
        } 
        else if ($result['status'] === 200) {
            $response = json_decode($result['response'], true);
            $checkoutSessionState = $response['statusDetails']['state'];
            $chargePermissionId = $response['chargePermissionId'];
        } else {
            // check the error
            echo 'status=' . $result['status'] . '; response=' . $result['response'] . "\n";
        }
    } catch (Exception $e) {
        // handle the exception
        echo $e;
    }
?>
```

</div>
  </div>
  <div role="tabpanel" class="tab-pane" id="dotnettab-completeCheckoutSession-NESK">
<div markdown="block">
```
using Amazon.Pay.API.Types;
using Amazon.Pay.API.WebStore;
using Amazon.Pay.API.WebStore.Types;
using Amazon.Pay.API.WebStore.CheckoutSession;

public class Sample
{
    public WebStoreClient InitiateClient()
    {
        // set up config
        var payConfiguration = new ApiConfiguration
        (
            region: Region.YOUR_REGION_CODE,
            environment: Environment.Sandbox,
            publicKeyId: "YOUR_PUBLIC_KEY_ID",
            privateKey: "PATH_OR_CONTENT_OF_YOUR_PRIVATE_KEY",
            algorithm: AmazonSignatureAlgorithm.V2
        );

        // init API client
        var client = new WebStoreClient(payConfiguration);

        return client;
    }

    public CheckoutSessionResponse CompleteCheckoutSession(string checkoutSessionId)
    {
        // prepare the request
        var request = new CompleteCheckoutSessionRequest(14.00M, Currency.USD);

        // send the request
        var result = client.CompleteCheckoutSession(checkoutSessionId, request);

        // check if API call was successful
        if (!result.Success)
        {
            // do something, e.g. throw an error
        }

        return result;
    }
}
```

</div>
  </div>
  <div role="tabpanel" class="tab-pane" id="javatab-completeCheckoutSession-NESK">
<div markdown="block">
```
import com.amazon.pay.api.AmazonPayResponse;
import com.amazon.pay.api.PayConfiguration;
import com.amazon.pay.api.WebstoreClient;
import com.amazon.pay.api.exceptions.AmazonPayClientException;
import com.amazon.pay.api.types.Environment;
import com.amazon.pay.api.types.Region;

import org.json.JSONObject;

public void sample() {
    PayConfiguration payConfiguration = null;
    try {
        payConfiguration = new PayConfiguration()
            .setPublicKeyId("YOUR_PUBLIC_KEY_ID")
            .setRegion(Region.YOUR_REGION_CODE)
            .setPrivateKey("YOUR_PRIVATE_KEY")
            .setEnvironment(Environment.SANDBOX)
            .setAlgorithm("AMZN-PAY-RSASSA-PSS-V2");

        WebstoreClient webstoreClient = new WebstoreClient(payConfiguration);
        AmazonPayResponse response = null;
        String checkoutSessionId = "bd504926-f659-4ad7-a1a9-9a747aaf5275";

        JSONObject payload = new JSONObject();

        JSONObject chargeAmount = new JSONObject();
        chargeAmount.put("amount", "14.00");
        chargeAmount.put("currencyCode", "USD");
        payload.put("chargeAmount", chargeAmount);

        response = webstoreClient.completeCheckoutSession(checkoutSessionId, payload);
        String chargePermissionId = response.getResponse().getString("chargePermissionId");
    } catch (AmazonPayClientException e) {
        e.printStackTrace();
    }
}

```

</div>
  </div>
  <div role="tabpanel" class="tab-pane" id="nodejstab-completeCheckoutSession-NESK">
<div markdown="block">
```html
const fs = require('fs');
const Client = require('@amazonpay/amazon-pay-api-sdk-nodejs');

const config = {
    publicKeyId: 'YOUR_PUBLIC_KEY_ID',
    privateKey: fs.readFileSync('tst/private.pem'),
    region: 'YOUR_REGION_CODE',
    sandbox: true,
    algorithm: 'AMZN-PAY-RSASSA-PSS-V2' 
};    
                
const payload = {
    chargeAmount: {
        amount: "14.00",
        currencyCode: "USD"
    }
};
                        
const testPayClient = new Client.WebStoreClient(config);
const response = testPayClient.completeCheckoutSession('bd504926-f659-4ad7-a1a9-9a747aaf5275', payload);

response.then(function (result) {
    console.log(result.data);
}).catch(err => {
    console.log(err);
});
```

</div>
  </div>
</div>
</div>

#### Response

```
{
    "checkoutSessionId": "bd504926-f659-4ad7-a1a9-9a747aaf5275",
    "webCheckoutDetails": null,
    "chargePermissionType": "OneTime",   
    "recurringMetadata": null,
    "productType": null,
    "paymentDetails": null,
    "merchantMetadata": null,
    "supplementaryData":null, // Amazon Pay system data 
    "buyer": null,
    "billingAddress": null,
    "paymentPreferences": [
        null
    ],
    "statusDetails": {
        "state": "Completed",
        "reasonCode": null,
        "reasonDescription": null,
        "lastUpdatedTimestamp": "20191015T204327Z"
    },
    "shippingAddress": null,
    "platformId":null,
    "chargePermissionId": "S01-5105180-3221187",
    "chargeId": "S01-5105180-3221187-C056351",
    "constraints": [
        null
    ],
    "creationTimestamp": "20191015T204313Z",
    "expirationTimestamp": null,
    "storeId": null,
    "deliverySpecifications": null,
    "providerMetadata": null,
    "checkoutButtonText": null,
    "releaseEnvironment": null
}
```

***

### 2. Add shipment tracking info

**Note:** This section is only applicable if you ship packages using a <a href="https://d2bvfbw64wr20e.cloudfront.net/Alexa/Delivery+Notifications/amazon-pay-delivery-tracker-supported-carriers-v2.csv" target="_blank" rel="noopener noreferrer">supported carrier</a>.

Send shipment tracking information to Amazon Pay using the Delivery Tracker API. Amazon Pay will notify your buyers on their Alexa device when their package is shipped and when their package is delivered. See <a href="../amazon-pay-checkout/setting-up-delivery-notifications.md" target="_blank" rel="noopener noreferrer">setting up delivery notifications</a> for more info.