Amazon Payの実装でつまづきやすいこと一覧

公式ではありませんが、Amazon PayをECサイトに導入時に、実装でつまづきやすいことをまとめてみました。
随時更新予定です。
追記してほしい内容があれば、コメントにお願いいたします。

(※2019/0910更新)
以下のページの実装の手引きに、以降にまとめている「リダイレクト形式のログイン方法」や「Amazon Pay APIの処理フロー」など必要なことがまとまってました。

[Amazon Pay FAQ](http://amazonpay-integration.amazon.co.jp/amazonpay-faq/index.html)

0.概要　を見た後に、こちらを見るとよさそうです。

# 0.概要
## ざっくりとイメージを掴みたい
### Amazon Payの流れを知る
[セルフチェックシート　> Amazon Payの流れをざっと見る](https://pwa.geekylab.net/selfcheck/index.html)

### Amazon Payを体験する
[Amazon Payを体験してみる](https://s3-ap-northeast-1.amazonaws.com/amazonpay-demoshop/amazonpay-demoshop/shop-item.html)

# １．ウィジェットの表示

## Amazonから連携されるアカウント情報について知りたい
javascriptから取得可能なアカウント情報　と　GetOrderReferenceDetails APIから取得可能なアカウント情報　でそれぞれ違いがあります。

### javascriptから取得可能なアカウント情報
[プロファイル情報の取得](https://pay.amazon.com/jp/developer/documentation/lpwa/201953190#201953190)の　その他サンプルコード　にある JavaScriptコードサンプル に実装方法が記載されています。
取得可能なアカウント情報は以下の通りです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/56279/b936a292-9063-5f75-5570-bf6e56163c35.png)

### GetOrderReferenceDetails APIから取得可能なアカウント情報
[GetOrderReferenceDetails](https://pay.amazon.com/jp/developer/documentation/apireference/201751970) APIのレスポンス　OrderReferenceDetails　内の　Destination > [Address](https://pay.amazon.com/jp/developer/documentation/apireference/201752430)より取得可能です。
アカウント情報は以下の通りです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/56279/31496e1c-8e31-64f9-25fa-902d259b0d9d.png)
自社サイトの会員情報と連携する場合は、GetOrderReferenceDetailsを実行し、アカウント情報を取得することをオススメします。

>ただし、テスト環境と本番環境では取得できるAmazon Payのアカウント情報が異なります。
テスト環境では、会社名が住所3が無く、市区町村としてCity情報が存在しますのでご注意ください。

## ドメインがlocalhostのときに、リダイレクト形式で認証した場合、「セッションが終了しました。 Amazon Payのボタンをクリックしてもう一度サインインしてください。」と表示される
Amazon Payボタンウィジェット押下後に表示されるAmazonログイン画面を、ポップアップ形式・リダイレクト形式　２つの方法で表示することが可能です。
※参考：[リダイレクト認証を有効にする。](https://pay.amazon.com/jp/developer/documentation/lpwa/201953170#201953170)
ただし、リダイレクト形式の場合、ドメインがlocalhostのときに下記サンプルコードの通り実行しても、うまく動きません。
[リダイレクト認証サンプルコード](https://johna1203.github.io:443/pwa-widget-generator/?seller_id=your_seller_merchant_id&client_id=your_client_id&region=JP&buttonInfo_color=Gold&buttonInfo_type=PwA&buttonInfo_size=medium&displayInfo_scope_login=login&displayInfo_scope_addressbook=undefined&displayInfo_scope_wallet=undefined&displayInfo_scope_consent=&buttonInfo_scope_profile=profile&buttonInfo_scope_payments_widget=&buttonInfo_scope_payments_shipping_address=&buttonInfo_scope_payments_billing_address=&buttonInfo_popup=true&implementationType=onetime&widget_size=responsive&widget_size_width=400&widget_size_height=228&redirect_url_type=url&redirect_url=callback.html&asynchronous=async)

この場合は、下記方法を試してみてください。

```javascript
# accessTokenのsecure属性を削除する。
document.cookie = "amazon_Login_accessToken=" + accessToken + ";path=/; secure ";
→「secure」を削除する
```

## Amazonログイン後のリダイレクト先ページにパラメーターを追加で渡す方法が知りたい
loginOptionsの「state」に、リダイレクト先ページへ渡したいパラメーターを追加することで、対応可能

   ```javascript
   OffAmazonPayments.Button("AmazonPayButton", sellerId, {
            type: "PwA",
            color: "Gold",
            size: "large",
            authorization: function() {
                loginOptions = {
                    scope: "profile payments:widget payments:shipping_address postal_code",
                    state: "123",#ここにパラメーターを追加
                    popup: false
                };
                authRequest = amazon.Login.authorize(loginOptions, "confirmation_redirect.html");
            },
            onError: function(error) {
                // your error handling code.
                // alert("The following error occurred: "
                // + error.getErrorCode()
                // + ' - ' + error.getErrorMessage());
            }
        });
```

## 毎回Amazonアカウントへのログインを求めるようにしたい
一度、Amazonアカウントでログインすると、数分間は、Amazonアカウントへのログインを求められない。
求められるようにするには、javascript内のloginOptionに```interactive: 'always'```を設定すればよい。

```javascript
loginOptions = {scope: 'profile postal_code payments:widget payments:shipping_address payments:billing_address', popup: true, interactive: 'always'};
```

## アドレス帳ウィジェット・お支払い方法ウィジェットが２回レンダリングする
[Code Generator](http://amzn.github.io/amazon-pay-sdk-samples/code_generator/?region=JP&ld=NSGoogle)のサンプルのように、```new OffAmazonPayments.Widgets.AddressBook```の中で、```new OffAmazonPayments.Widgets.Wallet```を実行する必要があります。

**理由**
Amazonでは、アドレス帳ウィジェットに表示される住所毎に、お支払い方法を設定するようです。
そのため、アドレス帳ウィジェットがレンダリングされると、住所に紐づくお支払い方法を表示するため、お支払い方法ウィジェットも自動でレンダリングされます。
結果として、
①お支払い方法ウィジェットがレンダリング
②アドレス帳ウィジェットがレンダリング　→　お支払い方法ウィジェットが再度レンダリングされる
という事象が発生します。

```javascript
    function showAddressBookWidget() {
        // AddressBook
        new OffAmazonPayments.Widgets.AddressBook({
          sellerId: 'your_seller_merchant_id',
          
          onReady: function (orderReference) {
              var orderReferenceId = orderReference.getAmazonOrderReferenceId();
              var el;
              if ((el = document.getElementById("orderReferenceId"))) {
                el.value = orderReferenceId;
              }
              // Wallet
              showWalletWidget(orderReferenceId); ##ここがポイント！
          },
.....

    function showWalletWidget(orderReferenceId) {
        // Wallet
        new OffAmazonPayments.Widgets.Wallet({
.....
```


# 2.Amazon Pay APIの実行
## GetOrderReferenceDetails APIを呼び出せるタイミングが知りたい
ConfirmOrderReference前でも実行可能。ただし、以下の制約あり
* ウィジェット表示前：OrderReferenceIDはウィジェット表示時に発行されるため、OrderReferenceIDをリクエストパラメータとするGetOrderReferenceDetails APIは呼び出せない
* ウィジェット表示後・アクセストークンなしの場合：配送先の一部（国コード、都道府県、郵便番号）が取得可能
* ウィジェット表示後・アクセストークンありの場合：配送先と購入者の情報が取得可能

## capture(売上請求) APIのエラーをsandbox環境で再現させたい
[※capture（売上請求）](https://pay.amazon.com/jp/developer/documentation/apireference/201752040)のリファレンス
SellerCaptureNoteに、下記を設定いただければ、Sandbox環境では、AmazonRejectedエラーが返却されます。

```json
{"SandboxSimulation": {"State":"Declined", "ReasonCode":"AmazonRejected"}}
```

## capture（売上請求）API実行後、closeAuthorization」を行ったときにエラーが発生
　* captureが成功すると、自動的に該当オーソリデータはcloseするため、closeAuthorizationを明示的に実施しなくても大丈夫

## 0円で売上請求した場合のcaptureAPIの挙動
* 下記の通りエラーになる

```json
{
  "Error": {
    "Type": "Sender",
    "Code": "InvalidParameterValue",
    "Message": "The Value '0' is invalid for the Parameter 'amount'"
  },
  "RequestId": "503862a1-7977-4d78-b915-3e9862cb62b2",
  "ResponseStatus": "400"
}
```

## オーソリ金額の上限額をしりたい
* ワンタイムペイメントは一回の支払いにつき上限１０００万円まで
* 定期支払いは、月額５万円まで
* ただし、クレジットカードの上限額が30万円であれば、30万以上でオーソリ処理を行うと、HardDeclineされる。

## APIの同時リクエスト数が最大値を超えると、どのような動きになるか
* スロットリングの最大値を超えると、HTTPレスポンスコード503エラーが返却される
* Amazon Pay側で待ち状態にならないので、あらためてAPIリクエストする必要あり

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56279/cf53377f-7fa2-e305-2301-39e79fbb3015.png)

## 各種APIの同時リクエスト数が知りたい
* API毎に同時リクエスト件数が決まっている [Throttling limits for payment APIs](https://pay.amazon.com/de/developer/documentation/apireference/RU9E56JA5GLC3YQ)
* 例えば、SetBillingAgreementDetails、ConfirmBillingAgreement、AuthorizeOnBillingAgreementは１０で、GetBillingAgreementDetailsは２０
* [Amazon Pay API リファレンス](https://pay.amazon.com/jp/developer/documentation/apireference/201751630)の各APIの説明で、最大リクエストクォーターとして記載されている

## Amazonからメールが送信されるタイミングが知りたい
[FAQ](https://m.media-amazon.com/images/G/09/AmazonPayments/LoginAndPayWithAmazonSystemIntegrationFAQ.pdf?ld=APJPLPADirect)のP.52を参照
![image.png](https://qiita-image-store.s3.amazonaws.com/0/56279/fb353557-1c36-451b-9202-a01ce04361ef.png)

# 3.IPN　の受け取り
## IPNが送られているのか、受信できていないのかわからない
### (前提)IPNを受け取れるようSellerCentralから設定
* [SellerCentral](https://sellercentral.amazon.co.jp/gp/pyop/seller/account/settings/user-settings-view.html/ref=ps_pyopiset_dnav_xx_)よりIPNの通知先URLを設定
SellerCentral > 設定 > インテグレーション

### IPNの受け取り先に、サンプルIPNを送信する
[IPNテストツール](https://sellercentral.amazon.co.jp/external-payments/ipn-test)を利用

### IPNのレスポンス内容を確認する
[ScrachPad](https://pwa.geekylab.net/index.html)を利用

**手順**

1. [SellerCentral](https://pwa.geekylab.net/scratchpad/php/ipnhandler.php)より下記URLをIPNの通知先として設定
1. ツールのAuthorizationにあるListen IPN notificationにチェック
1. パラメータを設定し、CloseAuthorizationを実行
1. ツールのIPN Noticeタブを選択


# 4.定期支払い(autopay)
## 注文者が定期支払いを解約するにはどうすればよいか
Amazon Payの購入者ページから解約可能

** 定期解約の方法 **
1. [amazon pay](https://pay.amazon.com/jp)ページから、購入者様　リンクを押下
1. ご利用履歴　から対象の注文の　詳細　リンク　を押下
1. 定期購入契約のキャンセル　を押下

# 5.本番への切り替え
## 本番への切り替え方法を知りたい
以下を参照してください。
[本番への切り替え](https://pwa.geekylab.net/selfcheck/case99-001.html)
※特に出品者情報は、メールなど本番用にも設定が必要ですので、お気をつけください。