amzn/amazon-pay-sdk-v2-php

该软件包已被废弃,不再维护。作者建议使用amzn/amazon-pay-api-sdk-php软件包。

Amazon Pay V2 SDK (PHP)

4.3.0 2019-10-09 22:10 UTC

This package is auto-updated.

Last update: 2020-04-10 20:07:03 UTC


README

Amazon Pay API V2 集成

请注意,Amazon Pay V2 SDK 只能用于 V2 特定的 API 调用(例如,Alexa Delivery Trackers、In-Store API、API V2 等)

如果您正在使用原始的Amazon Pay API 参考指南开发集成,则需要使用原始的Amazon Pay SDK (PHP)

要求

  • PHP 5.5 或更高版本,但强烈建议只使用最新的 PHP 版本,并经常更新,以确保应用最新的安全修复
  • Curl 7.18 或更高版本
  • phpseclib 2.0

SDK 安装

使用 composer 安装 V2 SDK 的最新版本及其依赖项

    composer require amzn/amazon-pay-sdk-v2-php

使用以下测试脚本来验证安装

    <?php
        include 'vendor/autoload.php';
        echo "SDK_VERSION=" . AmazonPayV2\Client::SDK_VERSION . "\n";
    ?>

公钥和私钥

以前的 MWS 或 Amazon Pay V1 集成中的 MWS 访问密钥、MWS 秘密密钥和 MWS 授权令牌不能与该 SDK 一起使用。

您需要生成自己的公钥/私钥对,以便使用该 SDK 进行 API 调用。

在 Windows 10 上,可以使用 ssh-keygen 命令完成此操作

ssh-keygen -t rsa -b 2048 -f private.pem
ssh-keygen -f private.pem -e -m PKCS8 > public.pub

在 Linux 或 macOS 上,可以使用 openssl 命令完成此操作

openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout > public.pub

上述第一个命令生成私钥,第二个命令使用私钥生成公钥。

要将密钥与您的账户关联,请发送电子邮件至 amazon-pay-delivery-notifications@amazon.com,邮件内容应包括(1)您的公钥和(2)您的商户 ID。在任何情况下都不要将您的私钥发送给亚马逊(或任何其他人)!

在您的卖家中心账户中,1-2 个工作日内,账户管理员将收到一条消息,其中包含您需要使用 SDK 的 public_key_id。

命名空间

该软件包的命名空间为 AmazonPayV2,以确保与使用 AmazonPay 命名空间的原始 Amazon Pay MWS SDK 无冲突。

配置数组

    $amazonpay_config = array(
        'public_key_id' => 'ABC123DEF456XYZ',  // RSA Public Key ID (this is not the Merchant or Seller ID)
        'private_key'   => 'keys/private.pem', // Path to RSA Private Key (or a string representation)
        'sandbox'       => true,               // true (Sandbox) or false (Production) boolean
        'region'        => 'us'                // Must be one of: 'us', 'eu', 'jp' 
    );

便利函数(概述)

利用内置的便利函数轻松进行 API 调用。向下滚动以查看示例代码片段。

使用便利函数时,请求负载将使用提供的私钥进行签名,并使用 HTTPS 请求向正确的区域端点发出请求。在请求限制的情况下,将使用指数退避方法尝试 HTTPS 调用最多三次。

Alexa Delivery Trackers API

请注意,您必须将您的商户账户列入白名单才能使用Delivery Trackers API

  • deliveryTrackers($payload, $headers = null) → POST to "v1/deliveryTrackers"

Authorization Tokens API

请注意,您的解决方案提供商账户必须与商户账户有预存在的关联(有效的和活跃的API V1风格MWS授权令牌),才能使用此功能。

  • getAuthorizationToken($mwsAuthToken, $merchantId, $headers = null) → GET to "v1/authorizationTokens/$mwsAuthToken?merchantId=$merchantId"

API V2

API V2集成指南

下面的创建/POST调用中,$headers字段是必需的,因为它至少需要x-amz-pay-idempotency-key头部

    $headers = array('x-amz-pay-idempotency-key' => uniqid());

API V2 CheckoutSession对象

  • createCheckoutSession($payload, $headers) → POST to "v1/checkoutSessions"
  • getCheckoutSession($checkoutSessionId, $headers = null) → GET to "v1/checkoutSessions/$checkoutSessionId"
  • updateCheckoutSession($checkoutSessionId, $payload, $headers = null) → PATCH to "v1/checkoutSessions/$checkoutSessionId"

API V2 ChargePermission对象

  • getChargePermission($chargePermissionId, $headers = null) → GET to "v1/chargePermissions/$chargePermissionId"
  • updateChargePermission($chargePermissionId, $payload, $headers = null) → PATCH to "v1/chargePermissions/$chargePermissionId"
  • closeChargePermission($chargePermissionId, $payload, $headers = null) → DELETE to "v1/chargePermissions/$chargePermissionId/close"

Charge对象

  • createCharge($payload, $headers) → POST to "v1/charges"
  • getCharge($chargeId, $headers = null) → GET to "v1/charges/$chargeId"
  • captureCharge($chargeId, $payload, $headers) → POST to "v1/charges/$chargeId/capture"
  • cancelCharge($chargeId, $payload, $headers = null) → DELETE to "v1/charges/$chargeId/cancel"

API V2 Refund对象

  • createRefund($payload, $headers) → POST to "v1/refunds"
  • getRefund($refundId, $headers = null) → GET to "v1/refunds/$refundId"

门店API

在生产环境中使用门店API调用之前,请先联系您的Amazon Pay账户经理以获取门店集成指南的副本。

  • instoreMerchantScan($payload, $headers = null) → POST to "in-store/v1/merchantScan"
  • instoreCharge($payload, $headers = null) → POST to "in-store/v1/charge"
  • instoreRefund($payload, $headers = null) → POST to "in-store/v1/refund"

使用便利函数

进行API调用需要四个简单步骤

步骤1. 构建一个客户端(使用之前定义的配置数组)。

    $client = new AmazonPayV2\Client($amazonpay_config);

步骤2. 生成有效负载。

    $payload = '{"scanData":"UKhrmatMeKdlfY6b","scanReferenceId":"0b8fb271-2ae2-49a5-b35d7","merchantCOE":"US","ledgerCurrency":"USD","chargeTotal":{"currencyCode":"USD","amount":"2.00"},"metadata":{"merchantNote":"Merchant Name","communicationContext":{"merchantStoreName":"Store Name","merchantOrderId":"789123"}}}';

步骤3. 执行调用。

     $result = $client->instoreMerchantScan($payload);

步骤4. 检查结果。

$result将是一个包含以下键的数组

  • 'status' - 整数HTTP状态码(200,201等)
  • 'response' - JSON响应体
  • 'request_id' - 来自Amazon API网关的请求ID
  • 'url' - SDK调用的REST调用的URL,用于故障排除
  • 'method - POST,GET,PATCH或DELETE
  • 'headers' - 包含由SDK生成的各种头部的数组,用于故障排除
  • 'request' - JSON请求负载
  • 'retries' - 通常为0,但反映了请求因节流或其他服务器问题而重试的次数
  • 'duration' - SDK函数调用的时长(毫秒)

前两项(状态、响应)是关键。其余项在故障排除情况下很有用。

在PHP中解析响应,可以使用PHP的json_decode()函数

    $response = json_decode($result['response'], true);
    $id = $response['chargePermissionId'];

如果您是解决方案提供商,需要代表不同的商户账户发起API调用,您需要将额外的认证令牌参数传递到API调用中。

    $headers = array('x-amz-pay-authtoken' => 'other_merchant_super_secret_token');
    $result = $client->instoreMerchantScan($payload, $headers);

执行第2步的另一种方式是使用PHP数组并程序化生成JSON负载

    $payload = array(
        'scanData' => 'UKhrmatMeKdlfY6b',
        'scanReferenceId' => uniqid(),
        'merchantCOE' => 'US',
        'ledgerCurrency' => 'USD',
        'chargeTotal' => array(
            'currencyCode' => 'USD',
            'amount' => '2.00'
        ),
        'metadata' => array(
            'merchantNote' => 'Merchant Name',
            'communicationContext' => array(
                'merchantStoreName' => 'Store Name',
                'merchantOrderId' => '789123'
            )
        )
    );
    $payload = json_encode($payload);

便捷函数代码示例

Alexa配送通知

    <?php
    include 'vendor/autoload.php';

    $amazonpay_config = array(
        'public_key_id' => 'MY_PUBLIC_KEY_ID',
        'private_key'   => 'keys/private.pem',
        'region'        => 'US',
        'sandbox'       => false
    );
    $payload = array(
        'amazonOrderReferenceId' => 'P01-0000000-0000000',
        'deliveryDetails' => array(array(
            'trackingNumber' => '01234567890',
            'carrierCode' => 'FEDEX'
        ))
    );
    try {
        $client = new AmazonPayV2\Client($amazonpay_config);
        $result = $client->deliveryTrackers($payload);
        if ($result['status'] === 200) {
            // success
            echo $result['response'] . "\n";
        } else {
            // check the error
            echo 'status=' . $result['status'] . '; response=' . $result['response'] . "\n";
        }
    } catch (\Exception $e) {
        // handle the exception
        echo $e . "\n";
    }
    ?>

API V2 - 创建结账会话(AJAX服务示例)

    <?php
    session_start();

    include 'vendor/autoload.php';

    $amazonpay_config = array(
        'public_key_id' => 'MY_PUBLIC_KEY_ID',
        'private_key'   => 'keys/private.pem',
        'region'        => 'US',
        'sandbox'       => true
    );
    $payload = array(
        'webCheckoutDetail' => array(
            'checkoutReviewReturnUrl' => 'https://localhost/store/checkout_review',
            'checkoutResultReturnUrl' => 'https://localhost/store/checkout_result'
        ),
        'storeId' => 'amzn1.application-oa2-client.000000000000000000000000000000000'
    );
    $headers = array('x-amz-pay-Idempotency-Key' => uniqid());
    try {
        $client = new AmazonPayV2\Client($amazonpay_config);
        $result = $client->createCheckoutSession($payload, $headers);

        header("Content-type:application/json; charset=utf-8");
        echo $result['response'];
        if ($result['status'] !== 201) {
            http_response_code(500);
        }

    } catch (\Exception $e) {
        // handle the exception
        echo $e . "\n";
        http_response_code(500);
    }
    ?>

API V2 - 创建结账会话(独立脚本示例)

    <?php
    include 'vendor/autoload.php';

    $amazonpay_config = array(
        'public_key_id' => 'MY_PUBLIC_KEY_ID',
        'private_key'   => 'keys/private.pem',
        'region'        => 'US',
        'sandbox'       => true
    );
    $payload = array(
        'webCheckoutDetail' => array(
            'checkoutReviewReturnUrl' => 'https://localhost/store/checkout_review',
            'checkoutResultReturnUrl' => 'https://localhost/store/checkout_result'
        ),
        'storeId' => 'amzn1.application-oa2-client.000000000000000000000000000000000'
    );
    $headers = array('x-amz-pay-Idempotency-Key' => uniqid());
    try {
        $client = new AmazonPayV2\Client($amazonpay_config);
        $result = $client->createCheckoutSession($payload, $headers);
        if ($result['status'] === 201) {
            // created
            $response = json_decode($result['response'], true);
            $checkoutSessionId = $response['checkoutSessionId'];
            echo "checkoutSessionId=$checkoutSessionId\n";
        } else {
            // check the error
            echo 'status=' . $result['status'] . '; response=' . $result['response'] . "\n";
        }
    } catch (\Exception $e) {
        // handle the exception
        echo $e . "\n";
    }
    ?>

API V2 - 获取结账会话

    <?php
    include 'vendor/autoload.php';

    $amazonpay_config = array(
        'public_key_id' => 'MY_PUBLIC_KEY_ID',
        'private_key'   => 'keys/private.pem',
        'region'        => 'US',
        'sandbox'       => true
    );

    try {
        $checkoutSessionId = '00000000-0000-0000-0000-000000000000';
        $client = new AmazonPayV2\Client($amazonpay_config);
        $result = $client->getCheckoutSession($checkoutSessionId);
        if ($result['status'] === 200) {
            $response = json_decode($result['response'], true);
            $checkoutSessionState = $response['statusDetail']['state'];
            $chargeId = $response['chargeId'];
            $chargePermissionId = $response['chargePermissionId'];

            // NOTE: Once Checkout Session moves to a "Completed" state, buyer and shipping
            // details must be obtained from the getCharges() function call instead
            $buyerName = $response['buyer']['name'];
            $buyerEmail = $response['buyer']['email'];
            $shipName = $response['shippingAddress']['name'];
            $shipAddrLine1 = $response['shippingAddress']['addressLine1'];
            $shipCity = $response['shippingAddress']['city'];
            $shipState = $response['shippingAddress']['stateOrRegion'];
            $shipZip = $response['shippingAddress']['postalCode'];
            $shipCounty = $response['shippingAddress']['countryCode'];

            echo "checkoutSessionState=$checkoutSessionState\n";
            echo "chargeId=$chargeId; chargePermissionId=$chargePermissionId\n";
            echo "buyer=$buyerName ($buyerEmail)\n";
            echo "shipName=$shipName\n";
            echo "address=$shipAddrLine1; $shipCity $shipState $shipZip ($shipCounty)\n";
        } else {
            // check the error
            echo 'status=' . $result['status'] . '; response=' . $result['response'] . "\n";
        }
    } catch (\Exception $e) {
        // handle the exception
        echo $e . "\n";
    }
    ?>

API V2 - 更新结账会话

    <?php
    include 'vendor/autoload.php';

    $amazonpay_config = array(
        'public_key_id' => 'MY_PUBLIC_KEY_ID',
        'private_key'   => 'keys/private.pem',
        'region'        => 'US',
        'sandbox'       => true
    );

    $payload = array(
       'paymentDetail' => array(
            'paymentIntent' => 'Authorize',
            'canHandlePendingAuthorization' => false,
            'chargeAmount' => array(
                'amount' => '1.23',
                'currencyCode' => 'USD'
            ),
        ),
        'merchantMetadata' => array(
            'merchantReferenceId' => '2020-00000001',
            'merchantStoreName' => 'Store Name',
            'noteToBuyer' => 'Thank you for your order!'
        )
    );

    try {
        $checkoutSessionId = '00000000-0000-0000-0000-000000000000';
        $client = new AmazonPayV2\Client($amazonpay_config);
        $result = $client->updateCheckoutSession($checkoutSessionId, $payload);
        if ($result['status'] === 200) {
            $response = json_decode($result['response'], true);
            $amazonPayRedirectUrl = $response['webCheckoutDetail']['amazonPayRedirectUrl'];
            echo "amazonPayRedirectUrl=$amazonPayRedirectUrl\n";
        } else {
            // check the error
            echo 'status=' . $result['status'] . '; response=' . $result['response'] . "\n";
        }
    } catch (\Exception $e) {
        // handle the exception
        echo $e . "\n";
    }
    ?>

API V2 - 捕获费用

    <?php
    include 'vendor/autoload.php';

    $amazonpay_config = array(
        'public_key_id' => 'MY_PUBLIC_KEY_ID',
        'private_key'   => 'keys/private.pem',
        'region'        => 'US',
        'sandbox'       => true
    );

    $payload = array(
        'captureAmount' => array(
            'amount' => '1.23',
            'currencyCode' => 'USD'
        ),
        'softDescriptor' => 'For CC Statement'
    );

    try {
        $chargeId = 'S01-0000000-0000000-C000000';
        $headers = array('x-amz-pay-Idempotency-Key' => uniqid());
        $client = new AmazonPayV2\Client($amazonpay_config);
        $result = $client->captureCharge($chargeId, $payload, $headers);

        if ($result['status'] === 200) {
            $response = json_decode($result['response'], true);
            $state = $response['statusDetail']['state'];
            $reasonCode = $response['statusDetail']['reasonCode'];
            $reasonDescription = $response['statusDetail']['reasonDescription'];
            echo "state=$state; reasonCode=$reasonCode; reasonDescription=$reasonDescription\n";
        } else {
            // check the error
            echo 'status=' . $result['status'] . '; response=' . $result['response'] . "\n";
        }
    } catch (\Exception $e) {
        // handle the exception
        echo $e . "\n";
    }
    ?>

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

手动签名(仅限高级用例)

此SDK提供帮助您手动签名API请求的能力,如果您想使用自己的代码通过互联网发送HTTPS请求。

使用值的getPostSignedHeaders函数调用示例

    /*  getPostSignedHeaders convenience – Takes values for canonical request sorts and parses it and  
     *  returns a signature for the request being sent 
     *  @param $http_request_method [String] 
     *  @param $request_uri [String] 
     *  @param $request_parameters [array()]
     *  @param $request_payload [string]
     */

示例请求方法

    $method = 'POST';

    // API Merchant Scan
    $url = 'https://pay-api.amazon.com/sandbox/in-store/v1/merchantScan';
    
    $payload = array(
        'scanData' => 'UKhrmatMeKdlfY6b',
        'scanReferenceId' => '0b8fb271-2ae2-49a5-b35d4',
        'merchantCOE' => 'US',
        'ledgerCurrency' => 'USD',
        'chargeTotal' => array(
            'currencyCode' => 'USD',
            'amount' => '2.00'
        ),
        'metadata' => array(
            'merchantNote' => 'Ice Cream',
            'customInformation' => 'In-store Ice Cream',
            'communicationContext' => array(
                'merchantStoreName' => 'Store Name',
                'merchantOrderId' => '789123'
            )
        )
    ); 

    // Convert to json string
    $payload = json_encode($payload);
    
    $requestParameters = array();

    $client = new AmazonPayV2\Client($amazonpay_config);

    $postSignedHeaders = $client->getPostSignedHeaders($method, $url, $requestParameters, $payload);

使用值的createSignature函数调用示例

(这仅在您不使用getPostSignedHeaders并希望创建自己的自定义头部时使用。)

  /*    createSignature convenience – Takes values for canonical request sorts and parses it and  
   *    returns a signature for the request being sent 
   *    @param $http_request_method [String] 
   *    @param $request_uri [String] 
   *    @param $request_parameters [Array()]
   *    @param $pre_signed_headers [Array()]
   *    @param $request_payload [String]
   *    @param $timeStamp [String]
   */

    // Example request method:

    $method = 'POST';

    // API Merchant Scan
    $url = 'https://pay-api.amazon.com/sandbox/in-store/v1/merchantScan';
    
    $payload = array(
        'scanData' => 'ScanData',
        'scanReferenceId' => '0b8fb271-2ae2-49a5-b35d4',
        'merchantCOE' => 'US',
        'ledgerCurrency' => 'USD',
        'chargeTotal' => array(
            'currencyCode' => 'USD',
            'amount' => '2.00'
        ),
        'metadata' => array(
            'merchantNote' => 'Ice Cream',
            'customInformation' => 'In-store Ice Cream',
            'communicationContext' => array(
                'merchantStoreName' => 'Store Name',
                'merchantOrderId' => '789123'
            )
        )
    ); 

    // Convert to json string
    $payload = json_encode($payload);
    
    $requestParameters = array();

    $client = new AmazonPayV2\Client($amazonpay_config);

    // Create an array that will contain the parameters for the charge API call
    $pre_signed_headers = array();
    $pre_signed_headers['Accept'] = 'application/json';
    $pre_signed_headers['Content-Type'] = 'application/json';
    $pre_signed_headers['X-Amz-Pay-Region'] = 'na';

    $client = new Client($amazonpay_config);
    $signedInput = $client->createSignature($method, $url, $requestParameters, $pre_signed_headers, $payload, '20180326T203730Z');