MagentoでAmazon Pay決済【住所連携の調整編】

takeda
2025-01-16
2025-01-16

こんにちは!

前回、「MagentoでAmazon Pay決済【インストール編】」をお送りしましたが、その中でチェックアウト画面がうまく進むことが出来ないケースがあるという問題について少し触れました。

今回はその詳しい内容や解消方法について解説したいと思います。

検証した環境

下記の環境で検証を行いました。

  • プラットフォーム: Adobe Commerce 2.4.7-p3
  • AmazonPay決済エクステンション: amzn/amazon-pay-magento-2-module: 5.18.0

どういった問題か

MagentoでAmazon Pay決済エクステンションを利用してチェックアウトを行うとき、下記のような流れになりますが。

チェックアウト画面のAmazon Payボタンを押すと、Amazonアカウントのログイン画面にリダイレクトされます。用意しておいたテスト用アカウントでログインすると、再びMagento側のチェックアウト画面にリダイレクトされます。テストアカウントに設定している配送先住所が画面に連携されます。

image-png-Nov-17-2024-10-36-19-1229-AM

問題とはここで「Next」ボタンを押したとき何も反応しない。という現象のことです。

image-png-Nov-23-2024-06-45-38-6558-AMちなみにMagento のバージョンが 2.4.4や2.4.5の場合にはこの問題は起きずボタンは正常に機能しますが、2.4.6と2.4.7ではボタンが反応しません。

なぜボタンが反応しないのか

この画面は本来お届け先を設定する画面ですので「Next」ボタンを押したとき、設定された住所(shipping-address)のバリデーションが行われます。実はこのバリデーションで弾かれてしまっているため次の画面に進まないのです。

本来は入力でエラー等があれば画面に表示されますが、Amazon Pay決済のフローでは従来の住所入力のフォームの代わりにAmazonアカウントから取得した住所が固定で表示される画面構成となっておりエラー表示をするための構成要素がありません。そのため、ボタンを押しても何も反応しない風に見えてしまうわけです。

バリデーションエラーの原因

Amazon Payから取得した住所をMagentoに連携する際の内容に問題があります。

問題の画面から「通常の購入フローに戻る」で前の画面に戻ってみるとその内容が分かります。

戻った画面では住所の入力フォームにAmazon Payから取得した住所がセットされています。
Street Addressの欄は2行ありますが入力必須の1行目が空欄になっておりこの部分が必須エラーの原因になっているわけです。

住所連携時の不具合

セラーセントラル側のテストアカウント(Amazonアカウント)ではお届け先住所が次のように設定されていますがそのままではMagento側と項目が合わないため、エクステンション側で住所を変換して連携しています。その変換プロセスに問題があり今回のような症状を引き起こしています。

システム間でのデータ連携において項目の相違を補うためのデータ変換はよくある事です。
この例で言うとAmazon側では氏名が姓と名に分かれていため、Magento側にはFirst Nameに氏名をセットし、Last Nameには「.(ドット)」がダミーでセットされています。
その他にもCityが無いためダミーで「-(ハイフン)」がセットされたりしています。
問題のStreet Addressは住所1~3が変換されてセットされますが、2行目に住所1~3を連結したものがセットされています。1行目は何故か空欄です、これがバリデーションで問題となっています。

ソースコードを紐解くと、Amazon Payのエステンションがそのように変換してしまっており、Magento側はそれをそのまま受け入れている格好です。

Magentoの2.4.5まではこの問題が起きていませんでしたが、Magento側でStreet Addressに配列を受け入れる際に空の要素を除去してから取り込むようになっていたため問題が起きていませんでした。

解消方法

この問題を解消するにはいつくか方法があります。
下記に対象のソースコードと変更例を示します。いずれの場合も対象ファイルを直接変更するのではなく、出来ればカスタマイズモジュール等で適切にオーバーライドして対応するのが望ましいです。

方法1: Magento側の処理を以前の方法に変更

バージョン2.4.5までは問題が起きていなかったので、それと同じ方法に修正する事で解消可能です。

対象ソースコード

vendor\magento\module-checkout\view\frontend\web\js\model\new-customer-address.js 41行目付近

        return {
            email: addressData.email,
            countryId: countryId,
            regionId: regionId || addressData.regionId,
            regionCode: addressData.region ? addressData.region['region_code'] : null,
            region: addressData.region ? addressData.region.region : null,
            customerId: addressData['customer_id'] || addressData.customerId,
            street: addressData.street, ←この部分を変更します
            company: addressData.company,
            telephone: addressData.telephone,

以前のバージョンと同様の処理にすることで空の要素が除去され、問題が解消出来ます。

            street: addressData.street ? _.compact(addressData.street) : addressData.street,

方法2: エクステンションのデータ変換処理を修正

Amazon Pay決済のエクステンションに根本原因と思われる箇所がありますので、それを訂正する事でも解消可能です。

対象ソースコード

vendor\amzn\amazon-pay-magento-2-module\Domain\AmazonAddressDecoratorJp.php 113行目付近のgetLine関数

    public function getLine($lineNumber)
    {
        $lines = $this->getLines();
        if (isset($lines[$lineNumber - 1])) {
            return $lines[$lineNumber - 1];
        }
        return null;
    }

問題の関数を下記の様に変更する事で解消されます。

    public function getLine($lineNumber)
    {
        return $this->amazonAddress->getLine($lineNumber);
    }

住所データを変換するクラスは基本のクラスと地域コード別の独自変換のクラスで構成されていて、今回修正するクラスは地域が日本の場合に使用されるクラスです。
問題の関数は住所1~3が格納されている配列から指定の行を取り出すものですが、この実装では指定の行番号を-1した添え字のデータを取り出すように実装がされており、ここに問題が潜んでいます。
一般的な配列は0から始まる添え字でデータが格納されますが、ここで扱っている配列の内容は実は行番号をそのままキーとした連想配列となっているため、取り出すときに行番号を-1する必要はありません。そのため1行目を取り出そうとして-1をした場合キー"0"には何も格納されていないため、戻り値として必ずnullが返される事となってしまい今回の問題を起こす原因となっています。

方法2はこの添え字の扱いを訂正する事で解消するものです。

方法3: エクステンション側で空の要素を取り除く

方法2でも解消は可能ですが今後モジュール内での配列の格納の扱い方が変わると再び問題となってしまう懸念があります。
そこで3番目の方法としては、方法2の箇所は訂正せずにその後の処理で空の要素を取り除く方法を紹介します。

対象ソースコード

vendor\amzn\amazon-pay-magento-2-module\view\frontend\web\js\action\checkout-session-address-load.js 33行目付近に対処用の処理を挿入

下記の処理を追記し変換済みのデータから空の要素を取り除きます。

        var handleResponse = function(data) {
            if (data.length) {
                data[0].street = data[0].street.filter(function( item ) {
                    return item != '';
                });
            }
            fullScreenLoader.stopLoader(true);
            callback(data.length ? data.shift() : {});
        }

streetに入っている配列から空の要素が取り除かれる事で必須エラーの問題が解消されます。

 

以上、3つの対処法を紹介しました。
いずれかお好みの方法で問題を解決してみてください。

補足
Magentoのバージョンやエクステンションのバージョンによっては対処方法が変わったり、問題自体が解消される事があるかもしれませんのでご留意ください。

最後に

この様に外部システムとの連携において住所情報などのフォーマット変換はそれぞれの仕様に合わせた対応が必要となります。

今回は必須エラーの回避についてのみ対応しましたが、実際の現場ではサイトの住所項目の仕様に合わせて実に様々な調整が求められますので、それぞれの要件に合わせて対応していきましょう。