Step 4: Add the AddressBook and Wallet widgets
After a buyer is successfully authenticated, you can render the Amazon Pay AddressBook and Wallet widgets on your site. The AddressBook and Wallet widgets show the addresses and payment instruments for the logged in customer, as they are provided in the corresponding Amazon account. One of these addresses and payment instruments are pre-selected when the widgets are rendered automatically.
Figure 1: The AddressBook widget shows the addresses stored in a buyer's Amazon account
Figure 2: The Wallet widget shows the payment methods stored in a buyer's Amazon account
You can use the widgets in sandbox mode without limitations, but they will not work in production (live mode) until you finished the account registration completely, which includes the validation process that you need to complete when you have access to Seller Central.
Embedding the widgets
- Like on any page where you use Amazon Pay functions, you must include the JavaScript blocks that load the widgets.js and set the Client-ID. Make sure that they appear in your code in the same order as shown in figure 3. There can be other code between the two script blocks.
Figure 3: JavaScript Code enabling Login and Pay with Amazon For more details on these JavaScript blocks, check the section Add a button widget.<script> window.onAmazonLoginReady = function() { amazon.Login.setClientId('YOUR-CLIENT-ID'); }; </script> <!-- insert before closing body tag--> <script async="async" src='https://static-eu.payments-amazon.com/OffAmazonPayments/eur/sandbox/lpa/js/Widgets.js'> </script>
- Embed the widgets on your website by adding code to the HTML page where you want them to appear. It makes a difference whether you include both widgets on one page or if you have distinct pages that render them, so there are different samples for one-page and multi-page checkouts. The option you use in your store is your decision. Using a one-page checkout lets your customers complete purchases quicker and with fewer clicks, while multi-page is slightly easier to integrate.
See the sample code below:
- One-page checkout
- Multi-page checkout
- Add a <meta> tag to the head of your web page for mobile-optimized websites.
The <meta> tag scales the widgets to the size of the screen so that they're readable on a mobile device or e-reader without requiring the user to manually zoom the page.
Figure 4: Meta element to support responsive/mobile designs<meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1.0"/>
- Specify the width and height parameters so that the widgets will render. We assume that you do this in CSS style documents rather that doing it inline. The following sample styles make your widgets scale as much as possible. Don't reduce the min-width further than 280px -- it breaks the layout and causes overlapping text inside of them. We recommend using a min-width of 300px.
/*
Include the min-width, max-width, min-height
and max-height if you plan to use a relative CSS unit
measurement to make sure the widget renders in the
optimal size allowed.
*/
#addressBookWidgetDiv {
min-width: 300px;
width: 100%;
max-width: 900px;
min-height: 228px;
height: 240px;
max-height: 400px;
}
#walletWidgetDiv {
min-width: 300px;
width: 100%;
max-width: 900px;
min-height: 228px;
height: 240px;
max-height: 400px;
}
/* The following are required only when you use the read-only widgets: */
#readOnlyAddressBookWidgetDiv {
min-width: 266px;
width: 100%;
max-width: 900px;
min-height: 145px;
height: 165px;
max-height: 180px;
}
#readOnlyWalletWidgetDiv {
min-width: 266px;
width: 100%;
max-width: 900px;
min-height: 145px;
height: 165px;
max-height: 180px;
}
Figure 5: CSS sample for responsive designs
If you need to limit the space required by the widgets to the absolute minimum, consider using the collapsible widgets for smart phones. They show only the pre-selected entry and a button for changing the selection that expands the widget to show the other addresses. Make sure that this expansion of the widgets doesn't break your page layout, and don't embed them in fixed-height boxes.
Checkout workflow
On every step that is explained here, always keep in mind that errors can occur, no matter how rarely this might happen. Be sure to write your code in a way that errors in one functionality don't influence the correct operation of all other elements. Also, implement a comprehensive logging, especially for the error and exception handling, to allow you to solve potential problems quickly and with minimal effort.
Overview
The following steps usually need to be performed on the page or the pages showing the widgets. If you are following one of the alternative integration scenarios, the steps might be slightly different.
- Make sure that you received and stored the AccessToken.
- Render the AddressBook widget.
- Get the Shipping address with getOrderReferenceDetails API call.
- Check whether the destination is supported by the shop configuration.
- Determine delivery options and costs according to the destination.
- Submit preliminary order total by setOrderReferenceDetails API call.
- (re-)render the Wallet widget after the setOrderReferenceDetails call.
- Get the billing address with getOrderReferenceDetails API call.
- Check the OrderReferenceDetails for constraints.
Get shipping and billing address
You can get the shipping and billing addresses in the checkout as soon as an address in the Wallet widget respectively a payment method in the Wallet widget is selected.
Requirements:
- Scope parameter payments:shipping_address for the full shipping address
- Scope parameter payments:billing_address for the billing address
- Parameter AccessToken set in GetOrderReferenceDetails call
You can and should use the onAddressSelect and onPaymentSelect callbacks in the widgets to become aware of any change inside the widgets. Unless the signed-in customer has no shipping addresses or payment instruments in their account, a shipping address and a payment instrument are pre-selected when you render the widgets. This pre-selection also triggers the onAddressSelect or onPaymentSelect event. That means you can use them to:
- Identify changes to update the addresses by sending a GetOrderReferenceDetails API call.
- Make sure that a shipping address and a payment method is selected before you let your customer proceed with the checkout.
Whether or not you need to do 1. depends on your integration. If you show shipping cost, delivery options (for example, express and standard), custom taxes, or anything else that depends on the selected shipping address on the same page with the AddressBook widget, then you will probably need to request the new address at any change in the widgets. In case you just show the widget here and anything else depending on their selection on the next page in your checkout flow, it's good enough to do that once before the next page is loaded.
Item 2. is important because, in rare cases, it might happen that the widgets are empty and in consequence no entry can be automatically selected. This can happen in the following cases:
For the AddressBook widget:
- No address was ever entered in the Amazon customer account.
For the Wallet widget:
- No payment instrument was ever provided for this account.
- No payment instrument was ever confirmed for the selected shipping address.
How could that happen?
Amazon requires the payment method to be confirmed once when a new address is entered as part of the fraud prevention strategies. As a result, the set of available payment instruments in the Wallet widget might vary for a different shipping address. To show the right set of payment methods, the Wallet widget is automatically invalidated and re-rendered on any selection change in the AddressBook widget. As a result, the Wallet widget might become empty after selection of a different shipping address.
Proceeding to checkout without a valid selection in the widgets results in errors when the order and then the payment are confirmed. So make sure of that before you let your customer proceed to checkout:
- There was at least one onAddressSelect event.
- There was at least one onPaymentSelect event after the last onAddressSelect event.
Before proceeding to the next step in the checkout, you must also make sure that there are no constraints on the OrderReferenceObject. For more information, see the Order Reference Constraints section of the <em>Amazon Pay API reference guide</em>.
Submit preliminary order total
Depending on the cart value, it might happen that certain payment instruments available in an Amazon Pay customer account can't be used. In these cases, the corresponding payment instruments are deactivated in the Wallet widget to prevent their selection. To be able to do that, you need to submit the preliminary order total after the shipping address was selected and before the Wallet widget is rendered. Since this is usually not possible when both widgets are shown on the same page, make sure that you re-render the Wallet widget after you made the setOrderReferenceDetails API call by means of executing its JavaScript code again. For details, see Re-rendering the Wallet widget.
If you don't do this, a payment method might be selected that will be excluded later when you submit the final order total on the time of order confirmation, resulting in a constraint in the OrderReferenceObject and also in an error for the ConfirmOrderReference API call. For more details, see the list of possible order reference constraints and the section on how to simulate them when testing your integration.
AddressBook widget in multipage checkout
<!-- Place this code in your HTML where you want the address widget to appear. -->
<div id="addressBookWidgetDiv"> </div>
<script>
window.onAmazonLoginReady = function() {amazon.Login.setClientId('YOUR-CLIENT-ID'); };
window.onAmazonPaymentsReady = function() {
addressBookWidget = new OffAmazonPayments.Widgets.AddressBook({
sellerId: 'YOUR_SELLER_ID_HERE',
scope: 'SCOPE',
onOrderReferenceCreate: function(orderReference) {
// Here is where you can grab the Order Reference ID.
orderReference.getAmazonOrderReferenceId();
},
onAddressSelect: function(orderReference) {
// Replace the following code with the action that you want
// to perform after the address is selected. The
// amazonOrderReferenceId can be used to retrieve the address
// details by calling the GetOrderReferenceDetails operation.
},
design: {
designMode: 'responsive'
},
onReady: function(orderReference) {
// Enter code here you want to be executed
// when the AddressBook widget has been rendered.
},
onError: function(error) {
// Your error handling code.
// During development you can use the following
// code to view error messages:
// console.log(error.getErrorCode() + ': ' + error.getErrorMessage());
// See "Handling Errors" for more information.
}
});
addressBookWidget.bind("addressBookWidgetDiv");
};
</script>
<script async="async"
src='https://static-eu.payments-amazon.com/OffAmazonPayments/eur/sandbox/lpa/js/Widgets.js'>
</script>
Figure 6: JavaScript code to add the AddressBook widget in a multipage checkout
Wallet widget in multipage checkout
The following code can be used for integrations where the address Wallet widget appear on different pages in your checkout flow. In case you have both on the same page, use the code shown in the one-page checkout sample code.
<!-- Place this code in your HTML where you want the Wallet widget to appear. -->
<div id="walletWidgetDiv"></div>
<script>
window.onAmazonLoginReady = function() {amazon.Login.setClientId('YOUR-CLIENT-ID'); };
window.onAmazonPaymentsReady = function() {
walletWidget = new OffAmazonPayments.Widgets.Wallet({
sellerId: 'YOUR_SELLER_ID_HERE',
scope: 'SCOPE',
amazonOrderReferenceId: 'ORDER_REFERENCE_ID', //the one you created before, most likely in the AddressBook widget
onPaymentSelect: function(orderReference) {
// Replace this code with the action that you want to perform
// after the payment method is selected.
// Ideally, this would enable the next action for the buyer
// including either a "Continue" or "Place Order" button.
},
design: {
designMode: 'responsive'
},
onError: function(error) {
// Your error handling code.
// During development you can use the following
// code to view error messages:
// console.log(error.getErrorCode() + ': ' + error.getErrorMessage());
// See "Handling Errors" for more information.
}
});
walletWidget.setPresentmentCurrency("EUR"); // ISO-4217 currency code, merchant is expected to enter valid list of currency supported by Amazon Pay.
walletWidget.bind("walletWidgetDiv");
};
</script>
<script async="async"
src='https://static-eu.payments-amazon.com/OffAmazonPayments/eur/sandbox/lpa/js/Widgets.js'>
</script>
Figure 7: JavaScript code to add the Wallet widget in a multipage checkout
AddressBook and Wallet widget on same page
In case of a one-page checkout or any other kind of integration where you present both widgets on the same page, you have to include their JavaScript code in the same onPaymentsReady function, as shown below in figure 6.
Note:
When showing both widgets on the same page, you usually don't have an OrderReferenceId yet when the widget is loaded since the ID is created in the AddressBook widget by default. As a result, the parameter amazonOrderReferenceId cannot be provided in the Wallet widget code, and it doesn't need to be because it can take the OrderReferenceId from the session. If you decide to do a synchronous authorization later (see Request an Authorization), you must change the widget code of both AddressBook and Wallet widget to use a specified amazonOrderReferenceId instead of generating a new one. For more information, see Step 7: Prepare to handle declined authorizations.
<!-- Place this code in your HTML where you would like the AddressBook widget to appear. -->
<div id="addressBookWidgetDiv"> </div>
<!-- Place this code in your HTML where you would like the Wallet widget to appear. -->
<div id="walletWidgetDiv"> </div>
<script>
window.onAmazonLoginReady = function() {amazon.Login.setClientId('YOUR-CLIENT-ID'); };
window.onAmazonPaymentsReady = function() {
addressBookWidget = new OffAmazonPayments.Widgets.AddressBook({
sellerId: 'YOUR_SELLER_ID_HERE',
scope: 'SCOPE',
onOrderReferenceCreate: function(orderReference) {
// Here is where you can grab the Order Reference ID.
orderReference.getAmazonOrderReferenceId();
},
onAddressSelect: function(orderReference) {
// Replace the following code with the action that you want
// to perform after the address is selected. The
// amazonOrderReferenceId can be used to retrieve the address
// details by calling the GetOrderReferenceDetails operation.
// If rendering the AddressBook and Wallet widgets
// on the same page, you do not have to provide any additional
// logic to load the Wallet widget after the AddressBook widget.
// The Wallet widget will re-render itself on all subsequent
// onAddressSelect events, without any action from you.
// We don't recommend that you explicitly refresh it.
},
design: {
designMode: 'responsive'
},
onReady: function(orderReference) {
// Enter code here you want to be executed
// when the AddressBook widget has been rendered.
},
onError: function(error) {
// Your error handling code.
// During development you can use the following
// code to view error messages:
// console.log(error.getErrorCode() + ': ' + error.getErrorMessage());
// See "Handling Errors" for more information.
}
});
addressBookWidget.bind("addressBookWidgetDiv");
walletWidget = new OffAmazonPayments.Widgets.Wallet({
sellerId: 'YOUR_SELLER_ID_HERE',
scope: 'SCOPE',
onPaymentSelect: function(orderReference) {
// Replace this code with the action that you want to perform
// after the payment method is selected.
// Ideally this would enable the next action for the buyer
// including either a "Continue" or "Place Order" button.
},
design: {
designMode: 'responsive'
},
onError: function(error) {
// Your error handling code.
// During development you can use the following
// code to view error messages:
// console.log(error.getErrorCode() + ': ' + error.getErrorMessage());
// See "Handling Errors" for more information.
}
});
walletWidget.setPresentmentCurrency("EUR"); // ISO-4217 currency code, merchant is expected to enter a valid currency supported by Amazon Pay.
walletWidget.bind("walletWidgetDiv");
};
</script>
<script async="async"
src='https://static-eu.payments-amazon.com/OffAmazonPayments/eur/sandbox/lpa/js/Widgets.js'>
</script>
Figure 8: JavaScript code to add both widgets on the same page