123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016 |
- <?php
- namespace AmazonPay;
- /* Class Client
- * Takes configuration information
- * Makes API calls to MWS for Amazon Pay
- * returns Response Object
- */
- require_once 'ResponseParser.php';
- require_once 'HttpCurl.php';
- require_once 'ClientInterface.php';
- require_once 'Regions.php';
- if (!interface_exists('\Psr\Log\LoggerAwareInterface')) {
- require_once(__DIR__.'/../Psr/Log/LoggerAwareInterface.php');
- }
- if (!interface_exists('\Psr\Log\LoggerInterface')) {
- require_once(__DIR__.'/../Psr/Log/LoggerInterface.php');
- }
- use Psr\Log\LoggerAwareInterface;
- use Psr\Log\LoggerInterface;
- class Client implements ClientInterface, LoggerAwareInterface
- {
- const SDK_VERSION = '3.6.0';
- const MWS_VERSION = '2013-01-01';
- const MAX_ERROR_RETRY = 3;
- // Construct User agent string based off of the application_name, application_version, PHP platform
- private $userAgent = null;
- private $parameters = null;
- private $mwsEndpointPath = null;
- private $mwsEndpointUrl = null;
- private $profileEndpoint = null;
- private $config = array(
- 'merchant_id' => null,
- 'secret_key' => null,
- 'access_key' => null,
- 'region' => null,
- 'currency_code' => null,
- 'sandbox' => false,
- 'platform_id' => null,
- 'cabundle_file' => null,
- 'application_name' => null,
- 'application_version' => null,
- 'proxy_host' => null,
- 'proxy_port' => -1,
- 'proxy_username' => null,
- 'proxy_password' => null,
- 'client_id' => null,
- 'app_id' => null,
- 'handle_throttle' => true,
- 'override_service_url' => null
- );
- private $modePath = null;
- // Final URL to where the API parameters POST done, based off the config['region'] and respective $mwsServiceUrls
- private $mwsServiceUrl = null;
- private $mwsServiceUrls;
- private $profileEndpointUrls;
- private $regionMappings;
- // Implement a logging library that utilizes the PSR 3 logger interface
- private $logger = null;
- // Boolean variable to check if the API call was a success
- public $success = false;
- /* Takes user configuration array from the user as input
- * Takes JSON file path with configuration information as input
- * Validates the user configuration array against existing config array
- */
- public function __construct($config = null)
- {
- $this->getRegionUrls();
- if (!is_null($config)) {
- if (is_array($config)) {
- $configArray = $config;
- } elseif (!is_array($config)) {
- $configArray = $this->checkIfFileExists($config);
- }
- // Invoke sandbox setter to throw exception if not Boolean datatype
- if (!empty($configArray['sandbox'])) {
- $this->setSandbox($configArray['sandbox']);
- }
- if (is_array($configArray)) {
- $this->checkConfigKeys($configArray);
- } else {
- throw new \Exception('$config is of the incorrect type ' . gettype($configArray) . ' and should be of the type array');
- }
- } else {
- throw new \Exception('$config cannot be null.');
- }
- }
- public function setLogger(LoggerInterface $logger = null) {
- $this->logger = $logger;
- }
-
- /* Helper function to log data within the Client */
- private function logMessage($message) {
- if ($this->logger) {
- $this->logger->debug($message);
- }
- }
-
- /* Get the Region specific properties from the Regions class.*/
- private function getRegionUrls()
- {
- $regionObject = new Regions();
- $this->mwsServiceUrls = $regionObject->mwsServiceUrls;
- $this->regionMappings = $regionObject->regionMappings;
- $this->profileEndpointUrls = $regionObject->profileEndpointUrls;
- }
- /* checkIfFileExists - check if the JSON file exists in the path provided */
- private function checkIfFileExists($config)
- {
- if (file_exists($config)) {
- $jsonString = file_get_contents($config);
- $configArray = json_decode($jsonString, true);
- $jsonError = json_last_error();
- if ($jsonError != 0) {
- $errorMsg = "Error with message - content is not in json format" . $this->getErrorMessageForJsonError($jsonError) . " " . $configArray;
- throw new \Exception($errorMsg);
- }
- } else {
- $errorMsg ='$config is not a Json File path or the Json File was not found in the path provided';
- throw new \Exception($errorMsg);
- }
- return $configArray;
- }
- /* Checks if the keys of the input configuration matches the keys in the config array
- * if they match the values are taken else throws exception
- * strict case match is not performed
- */
- private function checkConfigKeys($config)
- {
- $config = array_change_key_case($config, CASE_LOWER);
- $config = $this->trimArray($config);
- foreach ($config as $key => $value) {
- if (array_key_exists($key, $this->config)) {
- $this->config[$key] = $value;
- } else {
- throw new \Exception('Key ' . $key . ' is either not part of the configuration or has incorrect Key name.
- check the config array key names to match your key names of your config array', 1);
- }
- }
- }
- /* Convert a json error code to a descriptive error message
- *
- * @param int $jsonError message code
- *
- * @return string error message
- */
- private function getErrorMessageForJsonError($jsonError)
- {
- switch ($jsonError) {
- case JSON_ERROR_DEPTH:
- return " - maximum stack depth exceeded.";
- break;
- case JSON_ERROR_STATE_MISMATCH:
- return " - invalid or malformed JSON.";
- break;
- case JSON_ERROR_CTRL_CHAR:
- return " - control character error.";
- break;
- case JSON_ERROR_SYNTAX:
- return " - syntax error.";
- break;
- default:
- return ".";
- break;
- }
- }
- /* Setter for sandbox
- * Sets the Boolean value for config['sandbox'] variable
- */
- public function setSandbox($value)
- {
- if (is_bool($value)) {
- $this->config['sandbox'] = $value;
- } else {
- throw new \Exception('sandbox value ' . $value . ' is of type ' . gettype($value) . ' and should be a boolean value');
- }
- }
- /* Setter for config['client_id']
- * Sets the value for config['client_id'] variable
- */
- public function setClientId($value)
- {
- if (!empty($value)) {
- $this->config['client_id'] = $value;
- } else {
- throw new \Exception('setter value for client ID provided is empty');
- }
- }
- /* Setter for config['app_id']
- * Sets the value for config['app_id'] variable
- */
- public function setAppId($value)
- {
- if (!empty($value)) {
- $this->config['app_id'] = $value;
- } else {
- throw new \Exception('setter value for app ID provided is empty');
- }
- }
- /* Setter for Proxy
- * input $proxy [array]
- * @param $proxy['proxy_user_host'] - hostname for the proxy
- * @param $proxy['proxy_user_port'] - hostname for the proxy
- * @param $proxy['proxy_user_name'] - if your proxy required a username
- * @param $proxy['proxy_user_password'] - if your proxy required a password
- */
- public function setProxy($proxy)
- {
- if (!empty($proxy['proxy_user_host']))
- $this->config['proxy_host'] = $proxy['proxy_user_host'];
- if (!empty($proxy['proxy_user_port']))
- $this->config['proxy_port'] = $proxy['proxy_user_port'];
- if (!empty($proxy['proxy_user_name']))
- $this->config['proxy_username'] = $proxy['proxy_user_name'];
- if (!empty($proxy['proxy_user_password']))
- $this->config['proxy_password'] = $proxy['proxy_user_password'];
- }
- /* Setter for $mwsServiceUrl
- * Set the URL to which the post request has to be made for unit testing
- */
- public function setMwsServiceUrl($url)
- {
- $this->mwsServiceUrl = $url;
- }
- /* Getter
- * Gets the value for the key if the key exists in config
- */
- public function __get($name)
- {
- if (array_key_exists(strtolower($name), $this->config)) {
- return $this->config[strtolower($name)];
- } else {
- throw new \Exception('Key ' . $name . ' is either not a part of the configuration array config or the ' . $name . ' does not match the key name in the config array', 1);
- }
- }
- /* Getter for parameters string
- * Gets the value for the parameters string for unit testing
- */
- public function getParameters()
- {
- return trim($this->parameters);
- }
-
- /* Trim the input Array key values */
- private function trimArray($array)
- {
- foreach ($array as $key => $value) {
- // Do not attemp to trim array variables, boolean variables, or the proxy password
- // Trimming a boolean value (as a string) may not produce the expected output, so pass it through as-is
- if (!is_array($value) && !is_bool($value) && $key !== 'proxy_password') {
- $array[$key] = trim($value);
- }
- }
- return $array;
- }
- /* GetUserInfo convenience function - Returns user's profile information from Amazon using the access token returned by the Button widget.
- *
- * @see http://login.amazon.com/website Step 4
- * @param $accessToken [String]
- */
- public function getUserInfo($accessToken)
- {
- // Get the correct Profile Endpoint URL based off the country/region provided in the config['region']
- $this->profileEndpointUrl();
- if (empty($accessToken)) {
- throw new \InvalidArgumentException('Access Token is a required parameter and is not set');
- }
- // To make sure double encoding doesn't occur decode first and encode again.
- $accessToken = urldecode($accessToken);
- $url = $this->profileEndpoint . '/auth/o2/tokeninfo?access_token=' . $this->urlEncode($accessToken);
- $httpCurlRequest = new HttpCurl($this->config);
- $response = $httpCurlRequest->httpGet($url);
- $data = json_decode($response);
- // Ensure that the Access Token matches either the supplied Client ID *or* the supplied App ID
- // Web apps and Mobile apps will have different Client ID's but App ID should be the same
- // As long as one of these matches, from a security perspective, we have done our due diligence
- if (($data->aud != $this->config['client_id']) && ($data->app_id != $this->config['app_id'])) {
- // The access token does not belong to us
- throw new \Exception('The Access Token belongs to neither your Client ID nor App ID');
- }
- // Exchange the access token for user profile
- $url = $this->profileEndpoint . '/user/profile';
- $httpCurlRequest = new HttpCurl($this->config);
- $httpCurlRequest->setAccessToken($accessToken);
- $httpCurlRequest->setHttpHeader();
- $response = $httpCurlRequest->httpGet($url);
- $userInfo = json_decode($response, true);
- return $userInfo;
- }
- /* setParametersAndPost - sets the parameters array with non empty values from the requestParameters array sent to API calls.
- * If Provider Credit Details is present, values are set by setProviderCreditDetails
- * If Provider Credit Reversal Details is present, values are set by setProviderCreditDetails
- */
- private function setParametersAndPost($parameters, $fieldMappings, $requestParameters)
- {
- /* For loop to take all the non empty parameters in the $requestParameters and add it into the $parameters array,
- * if the keys are matched from $requestParameters array with the $fieldMappings array
- */
- foreach ($requestParameters as $param => $value) {
- // Do not use trim on boolean values, or it will convert them to '0' or '1'
- if (!is_array($value) && !is_bool($value)) {
- $value = trim($value);
- }
- // Ensure that no unexpected type coercions have happened
- if ($param === 'capture_now' || $param === 'confirm_now' || $param === 'inherit_shipping_address' || $param === 'request_payment_authorization') {
- if (!is_bool($value)) {
- throw new \Exception($param . ' value ' . $value . ' is of type ' . gettype($value) . ' and should be a boolean value');
- }
- } elseif ($param === 'provider_credit_details' || $param === 'provider_credit_reversal_details' || $param === 'order_item_categories' || $param === 'notification_configuration_list') {
- if (!is_array($value)) {
- throw new \Exception($param . ' value ' . $value . ' is of type ' . gettype($value) . ' and should be an array value');
- }
- }
- // When checking for non-empty values, consider any boolean as non-empty
- if (array_key_exists($param, $fieldMappings) && (is_bool($value) || $value!='')) {
- if (is_array($value)) {
- // If the parameter is a provider_credit_details or provider_credit_reversal_details, call the respective functions to set the values
- if ($param === 'provider_credit_details') {
- $parameters = $this->setProviderCreditDetails($parameters, $value);
- } elseif ($param === 'provider_credit_reversal_details') {
- $parameters = $this->setProviderCreditReversalDetails($parameters, $value);
- } elseif ($param === 'order_item_categories') {
- $parameters = $this->setOrderItemCategories($parameters, $value);
- } elseif ($param == 'notification_configuration_list') {
- $parameters = $this->setNotificationConfigurationList($parameters, $value);
- }
- } else {
- $parameters[$fieldMappings[$param]] = $value;
- }
- }
- }
- $parameters = $this->setDefaultValues($parameters, $fieldMappings, $requestParameters);
- $responseObject = $this->calculateSignatureAndPost($parameters);
- return $responseObject;
- }
- /* calculateSignatureAndPost - convert the Parameters array to string and curl POST the parameters to MWS */
- private function calculateSignatureAndPost($parameters)
- {
- // Call the signature and Post function to perform the actions. Returns XML in array format
- $parametersString = $this->calculateSignatureAndParametersToString($parameters);
- // POST using curl the String converted Parameters
- $response = $this->invokePost($parametersString);
- // Send this response as args to ResponseParser class which will return the object of the class.
- $responseObject = new ResponseParser($response);
- return $responseObject;
- }
- /* If merchant_id is not set via the requestParameters array then it's taken from the config array
- *
- * Set the platform_id if set in the config['platform_id'] array
- *
- * If currency_code is set in the $requestParameters and it exists in the $fieldMappings array, strtoupper it
- * else take the value from config array if set
- */
- private function setDefaultValues($parameters, $fieldMappings, $requestParameters)
- {
- if (empty($requestParameters['merchant_id']))
- $parameters['SellerId'] = $this->config['merchant_id'];
- if (array_key_exists('platform_id', $fieldMappings)) {
- if (empty($requestParameters['platform_id']) && !empty($this->config['platform_id']))
- $parameters[$fieldMappings['platform_id']] = $this->config['platform_id'];
- }
- if (array_key_exists('currency_code', $fieldMappings)) {
- if (!empty($requestParameters['currency_code'])) {
- $parameters[$fieldMappings['currency_code']] = strtoupper($requestParameters['currency_code']);
- } else if (!(array_key_exists('Action', $parameters) &&
- ($parameters['Action'] === 'SetOrderAttributes' || $parameters['Action'] === 'ConfirmOrderReference' || $parameters['Action'] === 'SetBillingAgreementDetails'))) {
- // Only supply a default CurrencyCode parameter if not using SetOrderAttributes, ConfirmOrderReference, or SetBillingAgreementDetails
- $parameters[$fieldMappings['currency_code']] = strtoupper($this->config['currency_code']);
- }
- }
- return $parameters;
- }
- /* setOrderItemCategories - helper function used by SetOrderAttributes API to set
- * one or more Order Item Categories
- */
- private function setOrderItemCategories($parameters, $categories)
- {
- $categoryIndex = 0;
- $categoryString = 'OrderAttributes.SellerOrderAttributes.OrderItemCategories.OrderItemCategory.';
- foreach ($categories as $value) {
- $categoryIndex = $categoryIndex + 1;
- $parameters[$categoryString . $categoryIndex] = $value;
- }
- return $parameters;
- }
- /* setMerchantNotificationUrls - helper function used by SetMerchantNotificationConfiguration API to set
- * one or more Notification Configurations
- */
- private function setNotificationConfigurationList($parameters, $configuration)
- {
- $configurationIndex = 0;
- if (!is_array($configuration)) {
- throw new \Exception('Notification Configuration List value ' . $configuration . ' is of type ' . gettype($configuration) . ' and should be an array value');
- }
- foreach ($configuration as $url => $events) {
- $configurationIndex = $configurationIndex + 1;
- $parameters['NotificationConfigurationList.NotificationConfiguration.' . $configurationIndex . '.NotificationUrl'] = $url;
- $eventIndex = 0;
- if (!is_array($events)) {
- throw new \Exception('Notification Configuration Events value ' . $events . ' is of type ' . gettype($events) . ' and should be an array value');
- }
- foreach ($events as $event) {
- $eventIndex = $eventIndex + 1;
- $parameters['NotificationConfigurationList.NotificationConfiguration.' . $configurationIndex . '.EventTypes.EventTypeList.' . $eventIndex] = $event;
- }
- }
- return $parameters;
- }
- /* setProviderCreditDetails - sets the provider credit details sent via the Capture or Authorize API calls
- * @param provider_id - [String]
- * @param credit_amount - [String]
- * @optional currency_code - [String]
- */
- private function setProviderCreditDetails($parameters, $providerCreditInfo)
- {
- $providerIndex = 0;
- $providerString = 'ProviderCreditList.member.';
- $fieldMappings = array(
- 'provider_id' => 'ProviderId',
- 'credit_amount' => 'CreditAmount.Amount',
- 'currency_code' => 'CreditAmount.CurrencyCode'
- );
- foreach ($providerCreditInfo as $key => $value) {
- $value = array_change_key_case($value, CASE_LOWER);
- $providerIndex = $providerIndex + 1;
- foreach ($value as $param => $val) {
- if (array_key_exists($param, $fieldMappings) && trim($val)!='') {
- $parameters[$providerString.$providerIndex. '.' .$fieldMappings[$param]] = $val;
- }
- }
- // If currency code is not entered take it from the config array
- if (empty($parameters[$providerString.$providerIndex. '.' .$fieldMappings['currency_code']])) {
- $parameters[$providerString.$providerIndex. '.' .$fieldMappings['currency_code']] = strtoupper($this->config['currency_code']);
- }
- }
- return $parameters;
- }
- /* setProviderCreditReversalDetails - sets the reverse provider credit details sent via the Refund API call.
- * @param provider_id - [String]
- * @param credit_amount - [String]
- * @optional currency_code - [String]
- */
- private function setProviderCreditReversalDetails($parameters, $providerCreditInfo)
- {
- $providerIndex = 0;
- $providerString = 'ProviderCreditReversalList.member.';
- $fieldMappings = array(
- 'provider_id' => 'ProviderId',
- 'credit_reversal_amount' => 'CreditReversalAmount.Amount',
- 'currency_code' => 'CreditReversalAmount.CurrencyCode'
- );
- foreach ($providerCreditInfo as $key => $value) {
- $value = array_change_key_case($value, CASE_LOWER);
- $providerIndex = $providerIndex + 1;
- foreach ($value as $param => $val) {
- if (array_key_exists($param, $fieldMappings) && trim($val)!='') {
- $parameters[$providerString.$providerIndex. '.' .$fieldMappings[$param]] = $val;
- }
- }
- // If currency code is not entered take it from the config array
- if (empty($parameters[$providerString.$providerIndex. '.' .$fieldMappings['currency_code']])) {
- $parameters[$providerString.$providerIndex. '.' .$fieldMappings['currency_code']] = strtoupper($this->config['currency_code']);
- }
- }
- return $parameters;
- }
- /* GetMerchantAccountStatus API call - Returns the status of the Merchant Account.
- * @see TODO
- * @param requestParameters['merchant_id'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function getMerchantAccountStatus($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'GetMerchantAccountStatus';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* GetOrderReferenceDetails API call - Returns details about the Order Reference object and its current state.
- * @see https://pay.amazon.com/developer/documentation/apireference/201751970
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_order_reference_id'] - [String]
- * @optional requestParameters['address_consent_token'] - [String]
- * @optional requestParameters['access_token'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- *
- * You cannot pass both address_consent_token and access_token in
- * the same call or you will encounter a 400/"AmbiguousToken" error
- */
- public function getOrderReferenceDetails($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'GetOrderReferenceDetails';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_order_reference_id' => 'AmazonOrderReferenceId',
- 'address_consent_token' => 'AddressConsentToken',
- 'access_token' => 'AccessToken',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* ListOrderReference API call - Returns details about the Order Reference object and its current state from the sellers.
- * @see https://pay.amazon.com/developer/documentation/apireference/201751970
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['query_id'] - [String]
- * @param requestParameters['query_id_type'] - [String] (SellerOrderId)
- * @optional requestParameters['page_size'] - [Int]
- * @optional requestParameters['created_start_time'] - [String] (Date/Time ISO8601)
- * @optional requestParameters['created_end_time'] - [String] (Date/Time ISO8601) Limited to 31 days
- * @optional requestParameters['sort_order'] - [String] (Ascending/Descending)
- * @optional requestParameters['mws_auth_token'] - [String]
- * @optional requestParameters['status_list'] - [Array]
- */
- public function listOrderReference($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'ListOrderReference';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $payment_domains = array(
- "us" => "NA_USD",
- "jp" => "FE_JPY",
- "de" => "EU_EUR",
- "uk" => "EU_GBP"
- );
- $requestParameters['payment_domain'] = $payment_domains[strtolower($this->config['region'])];
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'mws_auth_token' => 'MWSAuthToken',
-
- 'query_id' => 'QueryId',
- 'query_id_type' => 'QueryIdType',
- 'page_size' => 'PageSize',
- 'created_start_time' => 'CreatedTimeRange.StartTime',
- 'created_end_time' => 'CreatedTimeRange.EndTime',
- 'sort_order' => 'SortOrder',
- 'payment_domain' => 'PaymentDomain'
- );
- if( $requestParameters['order_status_list'] ){
- $status_index = 0;
- foreach ($requestParameters['order_status_list'] as $status) {
- $status_index++;
- $requestParameters['order_status_list_'.$status_index] = $status;
- $fieldMappings['order_status_list_'.$status_index] = 'OrderReferenceStatusListFilter.OrderReferenceStatus.'.$status_index;
- }
- }
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* ListOrderReferenceByNextToken API call - Returns details about the Order Reference object and its current
- * state from the sellers.
- * @see https://pay.amazon.com/developer/documentation/apireference/201751970
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['next_token'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function listOrderReferenceByNextToken($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'ListOrderReferenceByNextToken';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'mws_auth_token' => 'MWSAuthToken',
-
- 'next_page_token' => 'NextPageToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* SetOrderReferenceDetails API call - Sets order reference details such as the order total and a description for the order.
- * @see https://pay.amazon.com/developer/documentation/apireference/201751960
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_order_reference_id'] - [String]
- * @param requestParameters['amount'] - [String]
- * @param requestParameters['currency_code'] - [String]
- * @optional requestParameters['platform_id'] - [String]
- * @optional requestParameters['seller_note'] - [String]
- * @optional requestParameters['seller_order_id'] - [String]
- * @optional requestParameters['store_name'] - [String]
- * @optional requestParameters['custom_information'] - [String]
- * @optional requestParameters['supplementary_data'] - [String]
- * @optional requestParameters['request_payment_authorization'] - [Boolean]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function setOrderReferenceDetails($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'SetOrderReferenceDetails';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_order_reference_id' => 'AmazonOrderReferenceId',
- 'amount' => 'OrderReferenceAttributes.OrderTotal.Amount',
- 'currency_code' => 'OrderReferenceAttributes.OrderTotal.CurrencyCode',
- 'platform_id' => 'OrderReferenceAttributes.PlatformId',
- 'seller_note' => 'OrderReferenceAttributes.SellerNote',
- 'seller_order_id' => 'OrderReferenceAttributes.SellerOrderAttributes.SellerOrderId',
- 'store_name' => 'OrderReferenceAttributes.SellerOrderAttributes.StoreName',
- 'custom_information' => 'OrderReferenceAttributes.SellerOrderAttributes.CustomInformation',
- 'supplementary_data' => 'OrderReferenceAttributes.SellerOrderAttributes.SupplementaryData',
- 'request_payment_authorization' => 'OrderReferenceAttributes.RequestPaymentAuthorization',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* SetOrderAttributes API call - Sets order reference details such as the order total and a description for the order.
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_order_reference_id'] - [String]
- * @optional requestParameters['amount'] - [String]
- * @optional requestParameters['currency_code'] - [String]
- * @optional requestParameters['platform_id'] - [String]
- * @optional requestParameters['seller_note'] - [String]
- * @optional requestParameters['seller_order_id'] - [String]
- * @optional requestParameters['store_name'] - [String]
- * @optional requestParameters['custom_information'] - [String]
- * @optional requestParameters['supplementary_data'] - [String]
- * @optional requestParameters['request_payment_authorization'] - [Boolean]
- * @optional requestParameters['payment_service_provider_id'] - [String]
- * @optional requestParameters['payment_service_provider_order_id'] - [String]
- * @optional requestParameters['order_item_categories'] - [array()]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function setOrderAttributes($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'SetOrderAttributes';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_order_reference_id' => 'AmazonOrderReferenceId',
- 'amount' => 'OrderAttributes.OrderTotal.Amount',
- 'currency_code' => 'OrderAttributes.OrderTotal.CurrencyCode',
- 'platform_id' => 'OrderAttributes.PlatformId',
- 'seller_note' => 'OrderAttributes.SellerNote',
- 'seller_order_id' => 'OrderAttributes.SellerOrderAttributes.SellerOrderId',
- 'store_name' => 'OrderAttributes.SellerOrderAttributes.StoreName',
- 'custom_information' => 'OrderAttributes.SellerOrderAttributes.CustomInformation',
- 'supplementary_data' => 'OrderAttributes.SellerOrderAttributes.SupplementaryData',
- 'request_payment_authorization' => 'OrderAttributes.RequestPaymentAuthorization',
- 'payment_service_provider_id' => 'OrderAttributes.PaymentServiceProviderAttributes.PaymentServiceProviderId',
- 'payment_service_provider_order_id' => 'OrderAttributes.PaymentServiceProviderAttributes.PaymentServiceProviderOrderId',
- 'order_item_categories' => array(),
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* ConfirmOrderReference API call - Confirms that the order reference is free of constraints and all required information has been set on the order reference.
- * @see https://pay.amazon.com/developer/documentation/apireference/201751980
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_order_reference_id'] - [String]
- * @optional requestParameters['success_url'] - [String]
- * @optional requestParameters['failure_url'] - [String]
- * @optional requestParameters['authorization_amount'] - [String]
- * @optional requestParameters['currency_code'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function confirmOrderReference($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'ConfirmOrderReference';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_order_reference_id' => 'AmazonOrderReferenceId',
- 'success_url' => 'SuccessUrl',
- 'failure_url' => 'FailureUrl',
- 'authorization_amount' => 'AuthorizationAmount.Amount',
- 'currency_code' => 'AuthorizationAmount.CurrencyCode',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- if (isset($requestParameters['authorization_amount']) && !isset($requestParameters['currency_code'])) {
- $requestParameters['currency_code'] = strtoupper($this->config['currency_code']);
- }
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* CancelOrderReference API call - Cancels a previously confirmed order reference.
- * @see https://pay.amazon.com/developer/documentation/apireference/201751990
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_order_reference_id'] - [String]
- * @optional requestParameters['cancelation_reason'] [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function cancelOrderReference($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'CancelOrderReference';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_order_reference_id' => 'AmazonOrderReferenceId',
- 'cancelation_reason' => 'CancelationReason',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* CloseOrderReference API call - Confirms that an order reference has been fulfilled (fully or partially)
- * and that you do not expect to create any new authorizations on this order reference.
- * @see https://pay.amazon.com/developer/documentation/apireference/201752000
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_order_reference_id'] - [String]
- * @optional requestParameters['closure_reason'] [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function closeOrderReference($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'CloseOrderReference';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_order_reference_id' => 'AmazonOrderReferenceId',
- 'closure_reason' => 'ClosureReason',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* CloseAuthorization API call - Closes an authorization.
- * @see https://pay.amazon.com/developer/documentation/apireference/201752070
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_authorization_id'] - [String]
- * @optional requestParameters['closure_reason'] [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function closeAuthorization($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'CloseAuthorization';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_authorization_id' => 'AmazonAuthorizationId',
- 'closure_reason' => 'ClosureReason',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* Authorize API call - Reserves a specified amount against the payment method(s) stored in the order reference.
- * @see https://pay.amazon.com/developer/documentation/apireference/201752010
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_order_reference_id'] - [String]
- * @param requestParameters['authorization_amount'] [String]
- * @param requestParameters['currency_code'] - [String]
- * @param requestParameters['authorization_reference_id'] [String]
- * @optional requestParameters['capture_now'] [Boolean]
- * @optional requestParameters['provider_credit_details'] - [array (array())]
- * @optional requestParameters['seller_authorization_note'] [String]
- * @optional requestParameters['transaction_timeout'] [String] - Defaults to 1440 minutes
- * @optional requestParameters['soft_descriptor'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function authorize($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'Authorize';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_order_reference_id' => 'AmazonOrderReferenceId',
- 'authorization_amount' => 'AuthorizationAmount.Amount',
- 'currency_code' => 'AuthorizationAmount.CurrencyCode',
- 'authorization_reference_id' => 'AuthorizationReferenceId',
- 'capture_now' => 'CaptureNow',
- 'provider_credit_details' => array(),
- 'seller_authorization_note' => 'SellerAuthorizationNote',
- 'transaction_timeout' => 'TransactionTimeout',
- 'soft_descriptor' => 'SoftDescriptor',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* GetAuthorizationDetails API call - Returns the status of a particular authorization and the total amount captured on the authorization.
- * @see https://pay.amazon.com/developer/documentation/apireference/201752030
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_authorization_id'] [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function getAuthorizationDetails($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'GetAuthorizationDetails';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_authorization_id' => 'AmazonAuthorizationId',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* Capture API call - Captures funds from an authorized payment instrument.
- * @see https://pay.amazon.com/developer/documentation/apireference/201752040
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_authorization_id'] - [String]
- * @param requestParameters['capture_amount'] - [String]
- * @param requestParameters['currency_code'] - [String]
- * @param requestParameters['capture_reference_id'] - [String]
- * @optional requestParameters['provider_credit_details'] - [array (array())]
- * @optional requestParameters['seller_capture_note'] - [String]
- * @optional requestParameters['soft_descriptor'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function capture($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'Capture';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_authorization_id' => 'AmazonAuthorizationId',
- 'capture_amount' => 'CaptureAmount.Amount',
- 'currency_code' => 'CaptureAmount.CurrencyCode',
- 'capture_reference_id' => 'CaptureReferenceId',
- 'provider_credit_details' => array(),
- 'seller_capture_note' => 'SellerCaptureNote',
- 'soft_descriptor' => 'SoftDescriptor',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* GetCaptureDetails API call - Returns the status of a particular capture and the total amount refunded on the capture.
- * @see https://pay.amazon.com/developer/documentation/apireference/201752060
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_capture_id'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function getCaptureDetails($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'GetCaptureDetails';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_capture_id' => 'AmazonCaptureId',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* Refund API call - Refunds a previously captured amount.
- * @see https://pay.amazon.com/developer/documentation/apireference/201752080
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_capture_id'] - [String]
- * @param requestParameters['refund_reference_id'] - [String]
- * @param requestParameters['refund_amount'] - [String]
- * @param requestParameters['currency_code'] - [String]
- * @optional requestParameters['provider_credit_reversal_details'] - [array(array())]
- * @optional requestParameters['seller_refund_note'] [String]
- * @optional requestParameters['soft_descriptor'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function refund($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'Refund';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_capture_id' => 'AmazonCaptureId',
- 'refund_reference_id' => 'RefundReferenceId',
- 'refund_amount' => 'RefundAmount.Amount',
- 'currency_code' => 'RefundAmount.CurrencyCode',
- 'provider_credit_reversal_details' => array(),
- 'seller_refund_note' => 'SellerRefundNote',
- 'soft_descriptor' => 'SoftDescriptor',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* GetRefundDetails API call - Returns the status of a particular refund.
- * @see https://pay.amazon.com/developer/documentation/apireference/201752100
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_refund_id'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function getRefundDetails($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'GetRefundDetails';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_refund_id' => 'AmazonRefundId',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* GetServiceStatus API Call - Returns the operational status of the OffAmazonPayments API section
- * @see https://pay.amazon.com/developer/documentation/apireference/201752110
- *
- * The GetServiceStatus operation returns the operational status of the OffAmazonPayments API
- * section of Amazon Marketplace Web Service (Amazon MWS).
- * Status values are GREEN, GREEN_I, YELLOW, and RED.
- *
- * @param requestParameters['merchant_id'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function getServiceStatus($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'GetServiceStatus';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* CreateOrderReferenceForId API Call - Creates an order reference for the given object
- * @see https://pay.amazon.com/developer/documentation/apireference/201751670
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['id'] - [String]
- * @optional requestParameters['inherit_shipping_address'] [Boolean]
- * @optional requestParameters['confirm_now'] - [Boolean]
- * @optional Amount (required when confirm_now is set to true) [String]
- * @optional requestParameters['currency_code'] - [String]
- * @optional requestParameters['seller_note'] - [String]
- * @optional requestParameters['seller_order_id'] - [String]
- * @optional requestParameters['store_name'] - [String]
- * @optional requestParameters['supplementary_data'] - [String]
- * @optional requestParameters['custom_information'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function createOrderReferenceForId($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'CreateOrderReferenceForId';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'id' => 'Id',
- 'id_type' => 'IdType',
- 'inherit_shipping_address' => 'InheritShippingAddress',
- 'confirm_now' => 'ConfirmNow',
- 'amount' => 'OrderReferenceAttributes.OrderTotal.Amount',
- 'currency_code' => 'OrderReferenceAttributes.OrderTotal.CurrencyCode',
- 'platform_id' => 'OrderReferenceAttributes.PlatformId',
- 'seller_note' => 'OrderReferenceAttributes.SellerNote',
- 'seller_order_id' => 'OrderReferenceAttributes.SellerOrderAttributes.SellerOrderId',
- 'store_name' => 'OrderReferenceAttributes.SellerOrderAttributes.StoreName',
- 'supplementary_data' => 'OrderReferenceAttributes.SupplementaryData',
- 'custom_information' => 'OrderReferenceAttributes.SellerOrderAttributes.CustomInformation',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* GetBillingAgreementDetails API Call - Returns details about the Billing Agreement object and its current state.
- * @see https://pay.amazon.com/developer/documentation/apireference/201751690
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_billing_agreement_id'] - [String]
- * @optional requestParameters['address_consent_token'] - [String]
- * @optional requestParameters['access_token'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- *
- * You cannot pass both address_consent_token and access_token in
- * the same call or you will encounter a 400/"AmbiguousToken" error
- */
- public function getBillingAgreementDetails($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'GetBillingAgreementDetails';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_billing_agreement_id' => 'AmazonBillingAgreementId',
- 'address_consent_token' => 'AddressConsentToken',
- 'access_token' => 'AccessToken',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* SetBillingAgreementDetails API call - Sets Billing Agreement details such as a description of the agreement and other information about the seller.
- * @see https://pay.amazon.com/developer/documentation/apireference/201751700
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_billing_agreement_id'] - [String]
- * @param requestParameters['amount'] - [String]
- * @param requestParameters['currency_code'] - [String]
- * @optional requestParameters['platform_id'] - [String]
- * @optional requestParameters['seller_note'] - [String]
- * @optional requestParameters['seller_billing_agreement_id'] - [String]
- * @optional requestParameters['store_name'] - [String]
- * @optional requestParameters['custom_information'] - [String]
- * @optional requestParameters['billing_agreement_type'] - [String] either 'CustomerInitiatedTransaction' or 'MerchantInitiatedTransaction'
- * @optional requestParameters['subscription_amount'] - [String]
- * @optional requestParameters['currency_code'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function setBillingAgreementDetails($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'SetBillingAgreementDetails';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_billing_agreement_id' => 'AmazonBillingAgreementId',
- 'platform_id' => 'BillingAgreementAttributes.PlatformId',
- 'seller_note' => 'BillingAgreementAttributes.SellerNote',
- 'seller_billing_agreement_id' => 'BillingAgreementAttributes.SellerBillingAgreementAttributes.SellerBillingAgreementId',
- 'custom_information' => 'BillingAgreementAttributes.SellerBillingAgreementAttributes.CustomInformation',
- 'store_name' => 'BillingAgreementAttributes.SellerBillingAgreementAttributes.StoreName',
- 'billing_agreement_type' => 'BillingAgreementAttributes.BillingAgreementType',
- 'subscription_amount' => 'BillingAgreementAttributes.SubscriptionAmount.Amount',
- 'currency_code' => 'BillingAgreementAttributes.SubscriptionAmount.CurrencyCode',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- if (isset($requestParameters['subscription_amount']) && !isset($requestParameters['currency_code'])) {
- $requestParameters['currency_code'] = strtoupper($this->config['currency_code']);
- }
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* ConfirmBillingAgreement API Call - Confirms that the Billing Agreement is free of constraints and all required information has been set on the Billing Agreement.
- * @see https://pay.amazon.com/developer/documentation/apireference/201751710
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_billing_agreement_id'] - [String]
- * @optional requestParameters['success_url'] - [String]
- * @optional requestParameters['failure_url'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function confirmBillingAgreement($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'ConfirmBillingAgreement';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_billing_agreement_id' => 'AmazonBillingAgreementId',
- 'success_url' => 'SuccessUrl',
- 'failure_url' => 'FailureUrl',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* ValidateBillignAgreement API Call - Validates the status of the Billing Agreement object and the payment method associated with it.
- * @see https://pay.amazon.com/developer/documentation/apireference/201751720
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_billing_agreement_id'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function validateBillingAgreement($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'ValidateBillingAgreement';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_billing_agreement_id' => 'AmazonBillingAgreementId',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* AuthorizeOnBillingAgreement API call - Reserves a specified amount against the payment method(s) stored in the Billing Agreement.
- * @see https://pay.amazon.com/developer/documentation/apireference/201751940
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_billing_agreement_id'] - [String]
- * @param requestParameters['authorization_reference_id'] - [String]
- * @param requestParameters['authorization_amount'] - [String]
- * @param requestParameters['currency_code'] - [String]
- * @optional requestParameters['seller_authorization_note'] [String]
- * @optional requestParameters['transaction_timeout'] - Defaults to 1440 minutes
- * @optional requestParameters['capture_now'] [Boolean]
- * @optional requestParameters['soft_descriptor'] - - [String]
- * @optional requestParameters['seller_note'] - [String]
- * @optional requestParameters['platform_id'] - [String]
- * @optional requestParameters['custom_information'] - [String]
- * @optional requestParameters['seller_order_id'] - [String]
- * @optional requestParameters['store_name'] - [String]
- * @optional requestParameters['supplementary_data'] - [String]
- * @optional requestParameters['inherit_shipping_address'] [Boolean] - Defaults to true
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function authorizeOnBillingAgreement($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'AuthorizeOnBillingAgreement';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_billing_agreement_id' => 'AmazonBillingAgreementId',
- 'authorization_reference_id' => 'AuthorizationReferenceId',
- 'authorization_amount' => 'AuthorizationAmount.Amount',
- 'currency_code' => 'AuthorizationAmount.CurrencyCode',
- 'seller_authorization_note' => 'SellerAuthorizationNote',
- 'transaction_timeout' => 'TransactionTimeout',
- 'capture_now' => 'CaptureNow',
- 'soft_descriptor' => 'SoftDescriptor',
- 'seller_note' => 'SellerNote',
- 'platform_id' => 'PlatformId',
- 'custom_information' => 'SellerOrderAttributes.CustomInformation',
- 'seller_order_id' => 'SellerOrderAttributes.SellerOrderId',
- 'store_name' => 'SellerOrderAttributes.StoreName',
- 'supplementary_data' => 'SellerOrderAttributes.SupplementaryData',
- 'inherit_shipping_address' => 'InheritShippingAddress',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* CloseBillingAgreement API Call - Returns details about the Billing Agreement object and its current state.
- * @see https://pay.amazon.com/developer/documentation/apireference/201751950
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_billing_agreement_id'] - [String]
- * @optional requestParameters['closure_reason'] [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function closeBillingAgreement($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'CloseBillingAgreement';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_billing_agreement_id' => 'AmazonBillingAgreementId',
- 'closure_reason' => 'ClosureReason',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* GetMerchantNotificationConfiguration API Call - Returns details about the defined IPN endpoints
- *
- * @param requestParameters['merchant_id'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function getMerchantNotificationConfiguration($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'GetMerchantNotificationConfiguration';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* SetMerchantNotificationConfiguration API Call - Set IPN endpoints
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['notification_configuration_list'] - [Array]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function setMerchantNotificationConfiguration($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'SetMerchantNotificationConfiguration';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'notification_configuration_list' => array(),
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* charge convenience method
- * Performs the API calls
- * 1. SetOrderReferenceDetails / SetBillingAgreementDetails
- * 2. ConfirmOrderReference / ConfirmBillingAgreement
- * 3. Authorize (with Capture) / AuthorizeOnBillingAgreeemnt (with Capture)
- *
- * @param requestParameters['merchant_id'] - [String]
- *
- * @param requestParameters['amazon_reference_id'] - [String] : Order Reference ID /Billing Agreement ID
- * If requestParameters['amazon_reference_id'] is empty then the following is required,
- * @param requestParameters['amazon_order_reference_id'] - [String] : Order Reference ID
- * or,
- * @param requestParameters['amazon_billing_agreement_id'] - [String] : Billing Agreement ID
- *
- * @param $requestParameters['charge_amount'] - [String] : Amount value to be captured
- * @param requestParameters['currency_code'] - [String] : Currency Code for the Amount
- * @param requestParameters['authorization_reference_id'] - [String]- Any unique string that needs to be passed
- * @optional requestParameters['charge_note'] - [String] : Seller Note sent to the buyer
- * @optional requestParameters['transaction_timeout'] - [String] : Defaults to 1440 minutes
- * @optional requestParameters['charge_order_id'] - [String] : Custom Order ID provided
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function charge($requestParameters = array()) {
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $requestParameters = $this->trimArray($requestParameters);
- $setParameters = $authorizeParameters = $confirmParameters = $requestParameters;
- $chargeType = '';
-
- if (!empty($requestParameters['amazon_order_reference_id'])) {
- $chargeType = 'OrderReference';
- } elseif (!empty($requestParameters['amazon_billing_agreement_id'])) {
- $chargeType = 'BillingAgreement';
-
- } elseif (!empty($requestParameters['amazon_reference_id'])) {
- switch (substr(strtoupper($requestParameters['amazon_reference_id']), 0, 1)) {
- case 'P':
- case 'S':
- $chargeType = 'OrderReference';
- $setParameters['amazon_order_reference_id'] = $requestParameters['amazon_reference_id'];
- $authorizeParameters['amazon_order_reference_id'] = $requestParameters['amazon_reference_id'];
- $confirmParameters['amazon_order_reference_id'] = $requestParameters['amazon_reference_id'];
- break;
- case 'B':
- case 'C':
- $chargeType = 'BillingAgreement';
- $setParameters['amazon_billing_agreement_id'] = $requestParameters['amazon_reference_id'];
- $authorizeParameters['amazon_billing_agreement_id'] = $requestParameters['amazon_reference_id'];
- $confirmParameters['amazon_billing_agreement_id'] = $requestParameters['amazon_reference_id'];
- break;
- default:
- throw new \Exception('Invalid Amazon Reference ID');
- }
- } else {
- throw new \Exception('key amazon_order_reference_id or amazon_billing_agreement_id is null and is a required parameter');
- }
- // Set the other parameters if the values are present
- $setParameters['amount'] = !empty($requestParameters['charge_amount']) ? $requestParameters['charge_amount'] : '';
- $authorizeParameters['authorization_amount'] = !empty($requestParameters['charge_amount']) ? $requestParameters['charge_amount'] : '';
- $setParameters['seller_note'] = !empty($requestParameters['charge_note']) ? $requestParameters['charge_note'] : '';
- $authorizeParameters['seller_authorization_note'] = !empty($requestParameters['charge_note']) ? $requestParameters['charge_note'] : '';
- $authorizeParameters['seller_note'] = !empty($requestParameters['charge_note']) ? $requestParameters['charge_note'] : '';
- $setParameters['seller_order_id'] = !empty($requestParameters['charge_order_id']) ? $requestParameters['charge_order_id'] : '';
- $setParameters['seller_billing_agreement_id'] = !empty($requestParameters['charge_order_id']) ? $requestParameters['charge_order_id'] : '';
- $authorizeParameters['seller_order_id'] = !empty($requestParameters['charge_order_id']) ? $requestParameters['charge_order_id'] : '';
- $authorizeParameters['capture_now'] = !empty($requestParameters['capture_now']) ? $requestParameters['capture_now'] : false;
- $response = $this->makeChargeCalls($chargeType, $setParameters, $confirmParameters, $authorizeParameters);
- return $response;
- }
- /* makeChargeCalls - makes API calls based off the charge type (OrderReference or BillingAgreement) */
- private function makeChargeCalls($chargeType, $setParameters, $confirmParameters, $authorizeParameters)
- {
- switch ($chargeType) {
-
- case 'OrderReference':
-
- // Get the Order Reference details and feed the response object to the ResponseParser
- $responseObj = $this->getOrderReferenceDetails($setParameters);
-
- // Call the function getOrderReferenceDetailsStatus in ResponseParser.php providing it the XML response
- // $oroStatus is an array containing the State of the Order Reference ID
- $oroStatus = $responseObj->getOrderReferenceDetailsStatus($responseObj->toXml());
-
- if ($oroStatus['State'] === 'Draft') {
- $response = $this->setOrderReferenceDetails($setParameters);
- if ($this->success) {
- $this->confirmOrderReference($confirmParameters);
- }
- }
-
- $responseObj = $this->getOrderReferenceDetails($setParameters);
-
- // Check the Order Reference Status again before making the Authorization.
- $oroStatus = $responseObj->getOrderReferenceDetailsStatus($responseObj->toXml());
-
- if ($oroStatus['State'] === 'Open') {
- if ($this->success) {
- $response = $this->authorize($authorizeParameters);
- }
- }
- if ($oroStatus['State'] != 'Open' && $oroStatus['State'] != 'Draft') {
- throw new \Exception('The Order Reference is in the ' . $oroStatus['State'] . " State. It should be in the Draft or Open State");
- }
-
- return $response;
-
- case 'BillingAgreement':
-
- // Get the Billing Agreement details and feed the response object to the ResponseParser
-
- $responseObj = $this->getBillingAgreementDetails($setParameters);
-
- // Call the function getBillingAgreementDetailsStatus in ResponseParser.php providing it the XML response
- // $baStatus is an array containing the State of the Billing Agreement
- $baStatus = $responseObj->getBillingAgreementDetailsStatus($responseObj->toXml());
-
- if ($baStatus['State'] === 'Draft') {
- $response = $this->setBillingAgreementDetails($setParameters);
- if ($this->success) {
- $response = $this->confirmBillingAgreement($confirmParameters);
- }
- }
-
- // Check the Billing Agreement status again before making the Authorization.
- $responseObj = $this->getBillingAgreementDetails($setParameters);
- $baStatus = $responseObj->getBillingAgreementDetailsStatus($responseObj->toXml());
-
- if ($this->success && $baStatus['State'] === 'Open') {
- $response = $this->authorizeOnBillingAgreement($authorizeParameters);
- }
-
- if ($baStatus['State'] != 'Open' && $baStatus['State'] != 'Draft') {
- throw new \Exception('The Billing Agreement is in the ' . $baStatus['State'] . " State. It should be in the Draft or Open State");
- }
-
- return $response;
- default:
- throw new \Exception('Invalid Charge Type');
- }
- }
- /* GetProviderCreditDetails API Call - Get the details of the Provider Credit.
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_provider_credit_id'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function getProviderCreditDetails($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'GetProviderCreditDetails';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_provider_credit_id' => 'AmazonProviderCreditId',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* GetProviderCreditReversalDetails API Call - Get details of the Provider Credit Reversal.
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_provider_credit_reversal_id'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function getProviderCreditReversalDetails($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'GetProviderCreditReversalDetails';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_provider_credit_reversal_id' => 'AmazonProviderCreditReversalId',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* ReverseProviderCredit API Call - Reverse the Provider Credit.
- *
- * @param requestParameters['merchant_id'] - [String]
- * @param requestParameters['amazon_provider_credit_id'] - [String]
- * @optional requestParameters['credit_reversal_reference_id'] - [String]
- * @param requestParameters['credit_reversal_amount'] - [String]
- * @optional requestParameters['currency_code'] - [String]
- * @optional requestParameters['credit_reversal_note'] - [String]
- * @optional requestParameters['mws_auth_token'] - [String]
- */
- public function reverseProviderCredit($requestParameters = array())
- {
- $parameters = array();
- $parameters['Action'] = 'ReverseProviderCredit';
- $requestParameters = array_change_key_case($requestParameters, CASE_LOWER);
- $fieldMappings = array(
- 'merchant_id' => 'SellerId',
- 'amazon_provider_credit_id' => 'AmazonProviderCreditId',
- 'credit_reversal_reference_id' => 'CreditReversalReferenceId',
- 'credit_reversal_amount' => 'CreditReversalAmount.Amount',
- 'currency_code' => 'CreditReversalAmount.CurrencyCode',
- 'credit_reversal_note' => 'CreditReversalNote',
- 'mws_auth_token' => 'MWSAuthToken'
- );
- $responseObject = $this->setParametersAndPost($parameters, $fieldMappings, $requestParameters);
- return ($responseObject);
- }
- /* Create an Array of required parameters, sort them
- * Calculate signature and invoke the POST to the MWS Service URL
- *
- * @param AWSAccessKeyId [String]
- * @param Version [String]
- * @param SignatureMethod [String]
- * @param Timestamp [String]
- * @param Signature [String]
- */
- private function calculateSignatureAndParametersToString($parameters = array())
- {
- foreach ($parameters as $key => $value) {
- // Ensure that no unexpected type coercions have happened
- if ($key === 'CaptureNow' || $key === 'ConfirmNow' || $key === 'InheritShippingAddress' || $key === 'RequestPaymentAuthorization') {
- if (!is_bool($value)) {
- throw new \Exception($key . ' value ' . $value . ' is of type ' . gettype($value) . ' and should be a boolean value');
- }
- }
- // Ensure boolean values are outputed as 'true' or 'false'
- if (is_bool($value)) {
- $parameters[$key] = json_encode($value);
- }
- }
- $parameters['AWSAccessKeyId'] = $this->config['access_key'];
- $parameters['Version'] = self::MWS_VERSION;
- $parameters['SignatureMethod'] = 'HmacSHA256';
- $parameters['SignatureVersion'] = 2;
- $parameters['Timestamp'] = $this->getFormattedTimestamp();
- uksort($parameters, 'strcmp');
- $this->createServiceUrl();
- $parameters['Signature'] = $this->signParameters($parameters);
- $parameters = $this->getParametersAsString($parameters);
- // Save these parameters in the parameters variable so that it can be returned for unit testing.
- $this->parameters = $parameters;
- return $parameters;
- }
- /* Computes RFC 2104-compliant HMAC signature for request parameters
- * Implements AWS Signature, as per following spec:
- *
- * If Signature Version is 0, it signs concatenated Action and Timestamp
- *
- * If Signature Version is 1, it performs the following:
- *
- * Sorts all parameters (including SignatureVersion and excluding Signature,
- * the value of which is being created), ignoring case.
- *
- * Iterate over the sorted list and append the parameter name (in original case)
- * and then its value. It will not URL-encode the parameter values before
- * constructing this string. There are no separators.
- *
- * If Signature Version is 2, string to sign is based on following:
- *
- * 1. The HTTP Request Method followed by an ASCII newline (%0A)
- * 2. The HTTP Host header in the form of lowercase host, followed by an ASCII newline.
- * 3. The URL encoded HTTP absolute path component of the URI
- * (up to but not including the query string parameters);
- * if this is empty use a forward '/'. This parameter is followed by an ASCII newline.
- * 4. The concatenation of all query string components (names and values)
- * as UTF-8 characters which are URL encoded as per RFC 3986
- * (hex characters MUST be uppercase), sorted using lexicographic byte ordering.
- * Parameter names are separated from their values by the '=' character
- * (ASCII character 61), even if the value is empty.
- * Pairs of parameter and values are separated by the '&' character (ASCII code 38).
- *
- */
- private function signParameters(array $parameters)
- {
- $signatureVersion = $parameters['SignatureVersion'];
- $algorithm = "HmacSHA1";
- $stringToSign = null;
- if (2 === $signatureVersion) {
- $algorithm = "HmacSHA256";
- $parameters['SignatureMethod'] = $algorithm;
- $stringToSign = $this->calculateStringToSignV2($parameters);
- } else {
- throw new \Exception("Invalid Signature Version specified");
- }
- return $this->sign($stringToSign, $algorithm);
- }
- /* Calculate String to Sign for SignatureVersion 2
- * @param array $parameters request parameters
- * @return String to Sign
- */
- private function calculateStringToSignV2(array $parameters)
- {
- $data = 'POST';
- $data .= "\n";
- $data .= $this->mwsEndpointUrl;
- $data .= "\n";
- $data .= $this->mwsEndpointPath;
- $data .= "\n";
- $data .= $this->getParametersAsString($parameters);
- $this->logMessage($this->sanitizeRequestData($data));
- return $data;
- }
- /* Convert paremeters to Url encoded query string */
- private function getParametersAsString(array $parameters)
- {
- $queryParameters = array();
- foreach ($parameters as $key => $value) {
- $queryParameters[] = $key . '=' . $this->urlEncode($value);
- }
- return implode('&', $queryParameters);
- }
- private function urlEncode($value)
- {
- return str_replace('%7E', '~', rawurlencode($value));
- }
- /* Computes RFC 2104-compliant HMAC signature */
- private function sign($data, $algorithm)
- {
- if ($algorithm === 'HmacSHA1') {
- $hash = 'sha1';
- } else if ($algorithm === 'HmacSHA256') {
- $hash = 'sha256';
- } else {
- throw new \Exception("Non-supported signing method specified");
- }
- return base64_encode(hash_hmac($hash, $data, $this->config['secret_key'], true));
- }
- /* Formats date as ISO 8601 timestamp */
- private function getFormattedTimestamp()
- {
- return gmdate("Y-m-d\TH:i:s.\\0\\0\\0\\Z", time());
- }
- /* invokePost takes the parameters and invokes the httpPost function to POST the parameters
- * Exponential retries on error 500 and 503
- * The response from the POST is an XML which is converted to Array
- */
- private function invokePost($parameters)
- {
- $response = array();
- $statusCode = 200;
- $this->success = false;
- // Submit the request and read response body
- try {
- $shouldRetry = true;
- $retries = 0;
- do {
- try {
- $this->constructUserAgentHeader();
- $httpCurlRequest = new HttpCurl($this->config);
- $response = $httpCurlRequest->httpPost($this->mwsServiceUrl, $this->userAgent, $parameters);
- $curlResponseInfo = $httpCurlRequest->getCurlResponseInfo();
- $statusCode = $curlResponseInfo["http_code"];
- $this->logMessage($this->userAgent);
- $response = array(
- 'Status' => $statusCode,
- 'ResponseBody' => $response
- );
- $statusCode = $response['Status'];
- if ($statusCode == 200) {
- $shouldRetry = false;
- $this->success = true;
- } elseif ($statusCode == 500 || $statusCode == 503) {
- $shouldRetry = true;
- if ($shouldRetry && strtolower($this->config['handle_throttle'])) {
- $this->pauseOnRetry(++$retries, $statusCode);
- }
- } else {
- $shouldRetry = false;
- }
- } catch (\Exception $e) {
- throw $e;
- }
- } while ($shouldRetry);
- } catch (\Exception $se) {
- throw $se;
- }
- $this->logMessage($this->sanitizeResponseData($response['ResponseBody']));
- return $response;
- }
- /* Exponential sleep on failed request
- * Up to three retries will occur if first reqest fails
- * after 1.0 second, 2.2 seconds, and finally 7.0 seconds
- * @param retries current retry
- * @throws Exception if maximum number of retries has been reached
- */
- private function pauseOnRetry($retries, $status)
- {
- if ($retries <= self::MAX_ERROR_RETRY) {
- // PHP delays are in microseconds (1 million microsecond = 1 sec)
- // 1st delay is (4^1) * 100000 + 600000 = 0.4 + 0.6 second = 1.0 sec
- // 2nd delay is (4^2) * 100000 + 600000 = 1.6 + 0.6 second = 2.2 sec
- // 3rd delay is (4^3) * 100000 + 600000 = 6.4 + 0.6 second = 7.0 sec
- $delay = (int) (pow(4, $retries) * 100000) + 600000;
- usleep($delay);
- } else {
- throw new \Exception('Error Code: '. $status.PHP_EOL.'Maximum number of retry attempts - '. $retries .' reached');
- }
- }
- /* Create MWS service URL and the Endpoint path */
- private function createServiceUrl()
- {
- $this->modePath = strtolower($this->config['sandbox']) ? 'OffAmazonPayments_Sandbox' : 'OffAmazonPayments';
- if (!empty($this->config['region'])) {
- $region = strtolower($this->config['region']);
- if (array_key_exists($region, $this->regionMappings)) {
- if (!is_null($this->config['override_service_url'])) {
- $this->mwsEndpointUrl = preg_replace("(https?://)", "", $this->config['override_service_url']);
- } else {
- $this->mwsEndpointUrl = $this->mwsServiceUrls[$this->regionMappings[$region]];
- }
- $this->mwsServiceUrl = 'https://' . $this->mwsEndpointUrl . '/' . $this->modePath . '/' . self::MWS_VERSION;
- $this->mwsEndpointPath = '/' . $this->modePath . '/' . self::MWS_VERSION;
- } else {
- throw new \Exception($region . ' is not a valid region');
- }
- } else {
- throw new \Exception("config['region'] is a required parameter and is not set");
- }
- }
- /* Based on the config['region'] and config['sandbox'] values get the user profile URL */
- private function profileEndpointUrl()
- {
- $profileEnvt = strtolower($this->config['sandbox']) ? "api.sandbox" : "api";
-
- if (!empty($this->config['region'])) {
- $region = strtolower($this->config['region']);
- if (array_key_exists($region, $this->regionMappings) ) {
- $this->profileEndpoint = 'https://' . $profileEnvt . '.' . $this->profileEndpointUrls[$region];
- } else {
- throw new \Exception($region . ' is not a valid region');
- }
- } else {
- throw new \Exception("config['region'] is a required parameter and is not set");
- }
- }
- /* Create the User Agent Header sent with the POST request */
- /* Protected because of PSP module usaged */
- protected function constructUserAgentHeader()
- {
- $this->userAgent = 'amazon-pay-sdk-php/' . self::SDK_VERSION . ' (';
- if (($this->config['application_name']) || ($this->config['application_version'])) {
- if ($this->config['application_name']) {
- $this->userAgent .= $this->quoteApplicationName($this->config['application_name']);
- if ($this->config['application_version']) {
- $this->userAgent .= '/';
- }
- }
-
- if ($this->config['application_version']) {
- $this->userAgent .= $this->quoteApplicationVersion($this->config['application_version']);
- }
- $this->userAgent .= '; ';
- }
- $this->userAgent .= 'PHP/' . phpversion() . '; ';
- $this->userAgent .= php_uname('s') . '/' . php_uname('m') . '/' . php_uname('r');
- $this->userAgent .= ')';
- }
- /* Collapse multiple whitespace characters into a single ' ' and backslash escape '\',
- * and '/' characters from a string.
- * @param $s
- * @return string
- */
- private function quoteApplicationName($s)
- {
- $quotedString = preg_replace('/ {2,}|\s/', ' ', $s);
- $quotedString = preg_replace('/\\\\/', '\\\\\\\\', $quotedString);
- $quotedString = preg_replace('/\//', '\\/', $quotedString);
- return $quotedString;
- }
- /* Collapse multiple whitespace characters into a single ' ' and backslash escape '\',
- * and '(' characters from a string.
- *
- * @param $s
- * @return string
- */
- private function quoteApplicationVersion($s)
- {
- $quotedString = preg_replace('/ {2,}|\s/', ' ', $s);
- $quotedString = preg_replace('/\\\\/', '\\\\\\\\', $quotedString);
- $quotedString = preg_replace('/\\(/', '\\(', $quotedString);
- return $quotedString;
- }
- private function sanitizeRequestData($input)
- {
- $patterns = array();
- $patterns[0] = '/(SellerNote=)(.+)(&)/ms';
- $patterns[1] = '/(SellerAuthorizationNote=)(.+)(&)/ms';
- $patterns[2] = '/(SellerCaptureNote=)(.+)(&)/ms';
- $patterns[3] = '/(SellerRefundNote=)(.+)(&)/ms';
- $replacements = array();
- $replacements[0] = '$1REMOVED$3';
- $replacements[1] = '$1REMOVED$3';
- $replacements[2] = '$1REMOVED$3';
- $replacements[3] = '$1REMOVED$3';
- return preg_replace($patterns, $replacements, $input);
- }
- private function sanitizeResponseData($input)
- {
- $patterns = array();
- $patterns[0] = '/(<Buyer>)(.+)(<\/Buyer>)/ms';
- $patterns[1] = '/(<PhysicalDestination>)(.+)(<\/PhysicalDestination>)/ms';
- $patterns[2] = '/(<BillingAddress>)(.+)(<\/BillingAddress>)/ms';
- $patterns[3] = '/(<SellerNote>)(.+)(<\/SellerNote>)/ms';
- $patterns[4] = '/(<AuthorizationBillingAddress>)(.+)(<\/AuthorizationBillingAddress>)/ms';
- $patterns[5] = '/(<SellerAuthorizationNote>)(.+)(<\/SellerAuthorizationNote>)/ms';
- $patterns[6] = '/(<SellerCaptureNote>)(.+)(<\/SellerCaptureNote>)/ms';
- $patterns[7] = '/(<SellerRefundNote>)(.+)(<\/SellerRefundNote>)/ms';
- $replacements = array();
- $replacements[0] = '$1 REMOVED $3';
- $replacements[1] = '$1 REMOVED $3';
- $replacements[2] = '$1 REMOVED $3';
- $replacements[3] = '$1 REMOVED $3';
- $replacements[4] = '$1 REMOVED $3';
- $replacements[5] = '$1 REMOVED $3';
- $replacements[6] = '$1 REMOVED $3';
- $replacements[7] = '$1 REMOVED $3';
- return preg_replace($patterns, $replacements, $input);
- }
- /* Computes RFC 2104-compliant HMAC signature */
- public static function getSignature($stringToSign, $secretKey)
- {
- return base64_encode(hash_hmac('sha256', $stringToSign, $secretKey, true));
- }
- }
|