◄︎ Gregor's Portfolio Site
01 Nov 2020

Intro to amazon pay

Amazon Pay is an easy to use payment processor that allows you to leverage the Amazon payment infrastructure inside your e-commerce website or application. It is designed to reduce the steps and friction involved in the checkout process by letting customers checkout using the address and payment information stored in their existing Amazon account.

With minimal configuration it allows you to support a wide variety of flexible payment scenarios including the following:

Integrations and sample code are available for many common e-commerce platforms including Shopify, WooCommerce, and Magento. A full list can be found here. And with the available JavaScript API, custom solutions can be easily adapted. SDKs are also provided in most major programming languages including Node.js, Java, .NET, and PHP.

Industry Overview

Fees and services are mostly standardized across the industry. Platforms like PayPal and Amazon Pay have the added benefit of reducing friction for their millions of users who have address and payment information stored in their accounts.

Service Domestic Processing Fee Cross Border Fee Authorization Fee Countries
Amazon Pay 2.9% 3.9% $0.30 67
PayPal 2.9% 4.4%+ $0.30 200+
Stripe 2.9% 3.9% $0.30 42


Integration Demo

If using a standard shopping cart platform, the required code configuration is done automatically. That allows for quick setup and ease of use. But this is my developer blog, so I'll do things the hard way 💪. The following code example explores the functionality of a custom Amazon Pay integration using HTML and JavaScript. When fully carried out, it will showcase necessary API calls to execute a purchase.

You can check out a completed demo here. The code is run serverlessly on AWS Lambda and backend communication is handled through API Gateway: https://uanqseeg8l.execute-api.us-east-1.amazonaws.com/prod

Account Requirements:

Before you get started, the following is required.
  • An account with Amazon Seller Central (free)
  • Amazon Pay Sandbox integration
  • One or more Test Accounts
  • JavaScript

    Once the page is loaded the following code will instantiate the Amazon Pay widget which allows users to begin the authentication process. Each widget is country specific. The example below uses the US script.

    <script>
      window.onAmazonLoginReady = function () {
        amazon.Login.setClientId('CLIENT_ID');
      };
      window.onAmazonPaymentsReady = function() {
        showButton();
      };
    </script>
    
    <script async='async' src='https://static-na.payments-amazon.com/OffAmazonPayments/us/sandbox/js/Widgets.js'></script>

    The showButton function call needs to be placed after the widget code. When clicked, the button makes a call to the amazon.Login.authorize() endpoint. Included in the arguments is a redirect URL to send users upon successful authentication response.

    <script>
      function showButton() {               
          var authRequest;
          OffAmazonPayments.Button("AmazonPayButton", "MERCHANT_ID", {
            type: "Type",
            color: "Color",
            size: "Size",
            language: "en-US",
            authorization: function () {
              loginOptions = { scope: "profile payments:widget payments:shipping_address", popup: true };
              authRequest = amazon.Login.authorize(loginOptions, "https://amzn.github.io/amazon-pay-sdk-samples/set.html");
          },
            onError: function(error) {
              // Your error handling code.
              // console.error("The following error occurred", error.getErrorCode(), error.getErrorMessage());
            }
          });
      };
    </script>

    HTML

    Once the onAmazonPaymentsReady method is successful, the contents of this HTML element will be populated with the Amazon Pay button code.

    <div id="AmazonPayButton"></div>

    Viewing Shipping & Payment Information

    Once the user is authenticated an access token will be returned. Save this into your system and pass it along to the GetOrderReferenceDetails endpoint.

    HTML

    The elements below will hold the address and payment information associated with the user account.

    <div id="addressBookWidgetDiv"></div>
    <div id="walletWidgetDiv"></div>

    JavaScript

    Set the clientID and load the country specific widget, if they are not already stored from previous steps.

    <script type='text/javascript'>
        window.onAmazonLoginReady = function () {
          amazon.Login.setClientId('CLIENT_ID');
        };
    </script>
    
    <script type='text/javascript' src='https://static-na.payments-amazon.com/OffAmazonPayments/us/sandbox/js/Widgets.js'></script>
    

    Use the onOrderReferenceCreate method to produce an Order Reference ID. That is the value the backend will need to verify and complete the transaction.

    <script type="text/javascript">
        new OffAmazonPayments.Widgets.AddressBook({
          sellerId: 'MERCHANT_ID',
          onOrderReferenceCreate: function (orderReference) {
              orderReferenceId = orderReference.getAmazonOrderReferenceId();
          },
          onAddressSelect: function () {
              // Carry out additional steps dependent on address location, like adjusting tax rates or delivery options
          },
          design: {
              designMode: 'responsive'
          },
          onError: function (error) {
              // Your error handling code.
          }
        }).bind("addressBookWidgetDiv");
    
        new OffAmazonPayments.Widgets.Wallet({
          sellerId: 'MERCHANT_ID',
          onPaymentSelect: function () {
          },
          design: {
            designMode: 'responsive'
          },
          onError: function (error) {
            // Your error handling code.
          }
        }).bind("walletWidgetDiv");
    </script>

    Backend API Calls

    The following calls handle secret key information and cannot be processed on the front end. Using the SetOrderReferenceDetails and GetOrderReferenceDetails to specify the order information for each session. To run it requires the Reference ID created in the previous steps. Other required paramaters include the MWS Access Key and Secret Key. Please see this article for help locating this information.

    from amazon_pay.client import AmazonPayClient
      
      client = AmazonPayClient(
        mws_access_key='ACCESS_KEY',
        mws_secret_key='SECRET_KEY',
        merchant_id='MERCHANT_ID',
        sandbox=True,
        region='na',
        currency_code='USD')
        
        order_reference_id = 'AMAZON_ORDER_REFERENCE_ID'
        
        response = client.set_order_reference_details(
          amazon_order_reference_id=order_reference_id,
          order_total='0.99')
          
          if response.success:
          response = client.get_order_reference_details(
            amazon_order_reference_id=order_reference_id,
            address_consent_token=session['access_token'])
            
            pretty = json.dumps(
              json.loads(
                response.to_json()),
                indent=4)
                return pretty

    Here is a version of the backend code modified to run in an AWS Lambda function. Note the inclusion of a Lambda handler and a valid HTML response as a return. Also, in this scenario the order total and order reference ID are loaded as query parameters passed through an API Gateway proxy integration:

    import sys
    import json
    import urllib.parse
    
    sys.path.append('lib')
    from amazon_pay.client import AmazonPayClient
    
    def lambda_handler(event, context):
      client = AmazonPayClient(
          mws_access_key='ACCESS_KEY',
          mws_secret_key='SECRET_KEY',
          merchant_id='MERCHANT_ID',
          sandbox=True,
          region='na',
          currency_code='USD')
    
      order_reference_id = event["queryStringParameters"]["OrderReferenceId"]
      order_total_param = event["queryStringParameters"]["OrderTotal"]
      access_token_decoded = urllib.parse.unquote(event["queryStringParameters"]["AccessToken"])
    
      response = client.set_order_reference_details(
          amazon_order_reference_id=order_reference_id,
          order_total=order_total_param)
    
      if response.success:
          response = client.get_order_reference_details(
              amazon_order_reference_id=order_reference_id,
              address_consent_token=access_token_decoded)
    
      pretty = json.dumps(
          json.loads(
              response.to_json()),
          indent=4)
          
      print('this is the body response')
      print(pretty)
      return {
        'statusCode': 200,
        'body': pretty,
        'headers': {
          'Content-Type': 'application/json'
        }
      }


    Wrapping Up

    Building the code samples for this page was my introduction into the world of Amazon Pay. It is a flexible solution for a multitude of online payment needs. For a more in depth walkthrough on the setup of Amazon Pay, head over to the integration guide on the Amazon Pay Developer portal.



    Further Reading

    Amazon Pay Developer Guides:
  • Amazon Pay SDK Samples
  • Amazon Login JavaScript Reference Guide
  • Amazon Pay and Login with Amazon integration guide