amzn / amazon-pay-sdk-v2-php
Requires
- php: >=5.5.0
- ext-curl: *
- phpseclib/phpseclib: ~2.0
Requires (Dev)
- phpunit/phpunit: ^4
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
下面的创建/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');