Help us understand the problem. What is going on with this article?

PHPとAmazon Payを使ったクレジットカード決済サンプル

More than 1 year has passed since last update.

はじめに

「Amazon Pay」はAmazon以外のサイトで、Amazonアカウントのクレジットカードや住所を使って決済ができるサービスです。
https://pay.amazon.com/jp

今回はPHPを使ってAmazon Payのクレジットカード決済を試してみたので、サンプルコードをご紹介します。

前提条件として、Amazon Payの申し込みが済んでいて、Sandbox用の各種ID(出品者ID、クライアントIDなど)が発行されているものとします。

Amazonログインのウェブ設定

まずは使用するサイトのドメインと、Amazonログイン後のリダイレクト先URLを設定します。Amazon Payの管理画面でヘッダーのセレクトボックスから「Amazonログイン」を選択して、表示されたウェブ設定から「JavaScriptの種類」と「リダイレクトURL」を設定します。
qiita.png

Amazonログインボタン表示ページ

Amazonのログインボタンを表示するページです。

amazon_pay.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Amazon Pay</title>
</head>

<body>
<script async="async" src='https://origin-na.ssl-images-amazon.com/images/G/09/EP/offAmazonPayments/sandbox/prod/lpa/js/Widgets.js'></script>
<div id="AmazonPayButton"></div>
<script>
    window.onAmazonLoginReady = function () {
        amazon.Login.setClientId('--- CLIENT_ID ---');
    };
    window.onAmazonPaymentsReady = function() {
        showButton();
    };
</script>
<script>
function showButton() {
    var authRequest;
    OffAmazonPayments.Button("AmazonPayButton", "--- MERCHANT_ID ---", {
        type: "PwA",
        color: "Gold",
        size: "large",
        language: "jp",
        authorization: function () {
            loginOptions = { scope: "profile payments:widget", popup: true };
            authRequest = amazon.Login.authorize(loginOptions, "--- REDIRECT_URL ---");
        },
        onError: function(error) {
            // error handling
        }
    });
};
</script>
</body>
</html>

Amazonのログインボタンが表示されます。
q2.png

ボタンを押すと、Amazonのログイン画面がポップアップで表示されます。
q1.png

Amazon Payのテストアカウントでユーザー名とアカウントを入力してログインします。
要求された権限を許可すると、--- REDIRECT_URL ---で設定したURLにaccess_tokenをパラメータにしてリダイレクトされます。

--- REDIRECT_URL ---はAmazonログインのウェブ設定で設定したURLを入力します。

クレジットカード選択ページ

Amazonアカウントに登録してあるクレジットカードを選択するページです。パラメータのaccess_tokenは後ほど使うのでSESSIONに保存しておきます。

select_card.php
<?php
    session_start();
    $_SESSION['access_token'] = $_GET['access_token'];
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>クレジットカード選択ページ</title>
</head>

<body>
<div id="walletWidgetDiv" style="width:300px; height:240px;"></div>
<script>
    window.onAmazonLoginReady = function() {
        amazon.Login.setClientId('--- CLIENT_ID ---');
    };
</script>
<script src='https://origin-na.ssl-images-amazon.com/images/G/09/EP/offAmazonPayments/sandbox/prod/lpa/js/Widgets.js'></script>
<script type="text/javascript">
    new OffAmazonPayments.Widgets.Wallet({
        sellerId: '--- MERCHANT_ID ---',
        onOrderReferenceCreate: function (orderReference) {
            orderReferenceId = orderReference.getAmazonOrderReferenceId();
            document.getElementById("orderReferenceId").value = orderReferenceId;
        },
        onPaymentSelect: function () {
        },
        design: {
            designMode: 'responsive'
        },
        onError: function (error) {
        }
    }).bind("walletWidgetDiv");
</script>
<form action="/payment.php" method="POST">
    <input type="hidden" id="orderReferenceId" name="orderReferenceId">
    <input type="submit" value="購入する">
</form>
</body>
</html>

Amazonのテストアカウントに登録してあるクレジットカード情報が表示されます。
q3.png
クレジットカードを選択して「購入する」ボタンを押します。

クレジットカード決済処理

クレジットカード選択ページから送られてきたorderReferenceIdを使ってクレジットカード決済を実行します。

処理の流れとしては、
(1) Clientインスタンスを作成
(2) 注文情報をセット
(3) 注文情報を確定
(4) オーソリをリクエスト
(5) 注文を確定
となります。

Amazon Pay SDK (PHP)をダウンロードしておきます。composerでインストールも可能です。
https://github.com/amzn/amazon-pay-sdk-php

payment.php
<?php
require '/home/hoge/amazon/AmazonPay/Client.php';

Use AmazonPay\Client;

class Payment
{
    const MERCHANT_ID = '--- MERCHANT_ID ---';
    // 決済金額
    const AMOUNT = 100;

    public function execute()
    {
        $referenceId = $_REQUEST['orderReferenceId'];

        // (1) Clientインスタンスを作成
        $config = array(
            'merchant_id' => self::MERCHANT_ID,
            'access_key' => '--- ACCESS_KEY ---',
            'secret_key' => '--- SECRET_KEY---',
            'client_id' => '--- CLIENT_ID ---',
            'currency_code' => 'jpy',
            'region' => 'jp',
            'sandbox' => true,
        );
        $client = new Client($config);

        // (2) 注文情報をセット
        $setOrderParams = array(
            'merchant_id' => self::MERCHANT_ID,
            'amazon_order_reference_id' => $referenceId,
            'amount' => self::AMOUNT,
            'currency_code' => 'JPY',
            'seller_note' => 'ご購入ありがとうございます',
            'seller_order_id' => 'Order_' . time(),
            'store_name' => 'ショップ名',
        );
        $client->SetOrderReferenceDetails($setOrderParams);

        if ($client->success === false) {
            header('Location: /error.html');
            exit;
        }

        // (3) 注文情報を確定
        $confirmOrderParams = array(
            'amazon_order_reference_id' => $referenceId
        );
        $client->confirmOrderReference($confirmOrderParams);

        if ($client->success === false) {
            header('Location: /error.html');
            exit;
        }

        // (4) オーソリをリクエスト
        $authorizeParams = array(
            'amazon_order_reference_id' => $referenceId,
            'authorization_amount' => self::AMOUNT,
            'authorization_reference_id' => 'Order_' . time(),
            'seller_authorization_note' => 'Authorizing payment',
            'transaction_timeout' => 0,
        );
        $response = $client->authorize($authorizeParams);
        $result = $response->toArray();

        // オーソリが成功したか確認
        $amazonAuthorizationId = $result['AuthorizeResult']['AuthorizationDetails']['AmazonAuthorizationId'];
        if (empty($amazonAuthorizationId)) {
            header('Location: /error.html');
            exit;
        }
        if ($client->success === false) {
            header('Location: /error.html');
            exit;
        }

        // (5) 注文を確定
        $captureParams = array(
            'amazon_authorization_id' => $amazonAuthorizationId,
            'capture_amount' => self::AMOUNT,
            'currency_code' => 'JPY',
            'capture_reference_id' => 'Order_' . time(),
            'seller_capture_note' => '購入が完了しました',
        );
        $response = $client->capture($captureParams);
        $result = $response->toArray();

        // 注文の確定に失敗したらオーソリを取り消して、注文をクローズする
        if ($result['ResponseStatus'] !== '200') {
            $cancelParams = array(
                'merchant_id' => self::MERCHANT_ID,
                'amazon_order_reference_id' => $referenceId,
            );
            $client->cancelOrderReference($cancelParams);
            $closeParams = array(
                'merchant_id' => self::MERCHANT_ID,
                'amazon_authorization_id' => $amazonAuthorizationId,
            );
            $client->closeAuthorization($closeParams);

            header('Location: /error.html');
            exit;
        }

        header('Location: /success.html');
        exit;
    }
}

$payment = new Payment();
$payment->execute();
?>

デジタルコンテンツの販売であればこのように注文確定までやってしまってよいと思いますが、商品の発送がある物販の場合はオーソリだけしておいて、商品の確保後や発送後にAmazon Payの管理画面から注文を確定するなどします。

access_tokenを使った情報の取得

Amazonログイン後に発行されたaccess_tokenを使って許可されたユーザー情報にアクセスすることができます。

APIリクエストサンプル

<?php
    $token = "--- ACCESS_TOKEN ---";
    $curl = curl_init('https://api.sandbox.amazon.com/user/profile');
    curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: bearer ' . $token));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

    $response = curl_exec($curl);
    curl_close($curl);
    $data = json_decode($response, true);
    var_dump($data);
?>

レスポンスサンプル

array(3) {
  ["user_id"]=>
  string(42) "AmazonのユーザーID"
  ["name"]=>
  string(9) "テスト太郎"
  ["email"]=>
  string(21) "hoge@example.com"
}

まとめ

このようにAmazonアカウントを使って簡単にクレジットカード決済ができました。ユーザーにとってはAmazonアカウントを使うことで新規アカウント登録の手間が省け、運営する側としてもユーザー管理の手間が省けます。

サンプルコードの環境は
php 5.4.16
Amazon Pay SDK (PHP) 3.2.0
を使っています。

p_s_m_t
PHPを使ってWebサービスを開発しています
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした